unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Re: Cleaning up rcirc
@ 2021-09-11 16:21 Philip Kaludercic
  2021-09-11 16:49 ` Tassilo Horn
                   ` (3 more replies)
  0 siblings, 4 replies; 40+ messages in thread
From: Philip Kaludercic @ 2021-09-11 16:21 UTC (permalink / raw)
  To: emacs-devel


Hi,

the feature/rcirc-update should have everything implemented that I
wanted to suggest adding to Emacs 28, that were missing in the last
merge. The manual and the NEWS file should reflect all the changes.

Unless there are any objections, I would like to suggest merging the
branch into master, as from what I gather the master branch will be cut
off soon.

Finally, because of my work on rcirc, it might make sense to add me as a
maintainer in the header, so that anyone submitting a bug might Cc me in
the report. Would that be ok, or is there some procedure for these kinds
of things?

-- 
	Philip K.



^ permalink raw reply	[flat|nested] 40+ messages in thread
* Cleaning up rcirc
@ 2021-06-04 15:16 Philip Kaludercic
  2021-06-04 16:55 ` Andreas Schwab
                   ` (2 more replies)
  0 siblings, 3 replies; 40+ messages in thread
From: Philip Kaludercic @ 2021-06-04 15:16 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 2549 bytes --]


Hi,

I attach a series of patches suggesting a few improvements and things
that can be cleaned up. The background is that I am planning to
implement support for IRCv3, and these are issues I noticed while
reading through the code.

I'll summarize the changes here:

- 0001: Use libera.chat instead of freenode.net. This might be
  controversial, but besides that it also checks if gnutls is
  available.
- 0002: Use auth-source to check if the user has a password for the
  current server. I suggest this because my personal bouncer has a
  server, and I am currently querying .authinfo.gpg every time during
  startup. This needlessly slows down my startup time.
- 0003: Instead of duplicating a regular expression for URLs, use the
  one defined in browse-url.
- 0004: This is big changeset attempting to document every variable and
  function. There was a lot of missing documentation, from what I see
  since the first time rcirc was imported ~16 years ago, that I guess
  nobody ever bothered to document.
- 0005: I merged the command formatting functionality into
  rcirc-send-string itself, while preserving backwards
  compatibility. This removes a lot of duplicate and hack'y code around
  formatting IRC commands
- 0006: Instead of having rcirc-process-input-line call
  rcirc-process-command that in turn calls rcirc-process-message if
  the command is escaped, check if a command was escaped in 
  rcirc-process-command.
- 0007: rcirc-mode was a function, and not a "derived mode". This patch
  tries to convert rcirc-mode into a proper major mode, but has to deal
  with the fact that rcirc-mode requires two arguments that have to
  fall away. Instead, rcirc-initialize is used for creating a new buffer
  and setting the major mode. This might require some more hacking to
  fix issues if some external code calls rcirc-mode directly.
- 0008: The function rcirc-delete-process just calls delete-process, and
  has no additional functionality.  From what I see, it used to do more,
  but that was removed a while back, so there should be no need for this
  function any more.
- 0009: The variable rcirc-last-sender appears to have never been used
  or defined, so I dared to remove it.
- 0010: Update the activity string directly after moving to the next
  active buffer. This avoids an annoyance where the mode line is not
  updated, even though you have read new messages.

There is more that can be done (particularly with using when, unless,
subr-x macros, ...), but this is what I managed to root out until now.

-- 
	Philip K.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Default-to-libera.chat-instead-of-freenode.net.patch --]
[-- Type: text/x-diff, Size: 1470 bytes --]

From aca90f1fb7cc2defc4c668b43b5934dacceb8453 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Fri, 4 Jun 2021 14:00:03 +0200
Subject: [PATCH 01/11] Default to libera.chat instead of freenode.net

---
 lisp/net/rcirc.el | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index 4fdb63e2eb..90b61badf0 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -56,10 +56,10 @@ rcirc
   :group 'applications)
 
 (defcustom rcirc-server-alist
-  '(("chat.freenode.net" :channels ("#rcirc")
-     ;; Don't use the TLS port by default, in case gnutls is not available.
-     ;; :port 7000 :encryption tls
-     ))
+  (if (gnutls-available-p)
+      '(("irc.libera.chat" :channels ("#rcirc")
+         :port 6697 :encryption tls))
+    '(("irc.libera.chat" :channels ("#rcirc"))))
   "An alist of IRC connections to establish when running `rcirc'.
 Each element looks like (SERVER-NAME PARAMETERS).
 
@@ -120,7 +120,8 @@ rcirc-server-alist
                                     (:channels (repeat string))
                                     (:encryption (choice (const tls)
                                                          (const plain)))
-                                    (:server-alias string)))))
+                                    (:server-alias string))))
+  :version "28.1")
 
 (defcustom rcirc-default-port 6667
   "The default port to connect to."
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Check-auth-source-for-server-password.patch --]
[-- Type: text/x-diff, Size: 1228 bytes --]

From 7d7c360ad9a7c249a19d8d8f7ac1afd2f9678a77 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Fri, 4 Jun 2021 14:03:54 +0200
Subject: [PATCH 02/11] Check auth-source for server password

---
 lisp/net/rcirc.el | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index 90b61badf0..67dcf3e4ea 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -44,6 +44,7 @@
 (require 'cl-lib)
 (require 'ring)
 (require 'time-date)
+(require 'auth-source)
 (eval-when-compile (require 'subr-x))
 
 (defconst rcirc-id-string (concat "rcirc on GNU Emacs " emacs-version))
@@ -500,6 +501,12 @@ rcirc
               (encryption (plist-get (cdr c) :encryption))
               (server-alias (plist-get (cdr c) :server-alias))
               contact)
+          (when-let (((not password))
+                     (auth (auth-source-search :host server
+                                               :user user-name
+                                               :port port))
+                     (fn (plist-get (car auth) :secret)))
+            (setq password (funcall fn)))
 	  (when server
 	    (let (connected)
 	      (dolist (p (rcirc-process-list))
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0003-Define-rcirc-url-regexp-using-browse-url-button-rege.patch --]
[-- Type: text/x-diff, Size: 1653 bytes --]

From 47e95361abb5ab7445feedf4a701ffaabde2dc44 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Fri, 4 Jun 2021 14:04:34 +0200
Subject: [PATCH 03/11] Define rcirc-url-regexp using browse-url-button-regexp

---
 lisp/net/rcirc.el | 21 ++-------------------
 1 file changed, 2 insertions(+), 19 deletions(-)

diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index 67dcf3e4ea..00d48ba0e2 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -45,6 +45,7 @@
 (require 'ring)
 (require 'time-date)
 (require 'auth-source)
+(require 'browse-url)
 (eval-when-compile (require 'subr-x))
 
 (defconst rcirc-id-string (concat "rcirc on GNU Emacs " emacs-version))
@@ -2414,25 +2415,7 @@ rcirc-facify
     (rcirc-add-face 0 (length string) face string)
     string))
 
-(defvar rcirc-url-regexp
-  (concat
-   "\\b\\(\\(www\\.\\|\\(s?https?\\|ftp\\|file\\|gopher\\|"
-   "nntp\\|news\\|telnet\\|wais\\|mailto\\|info\\):\\)"
-   "\\(//[-a-z0-9_.]+:[0-9]*\\)?"
-   (if (string-match "[[:digit:]]" "1") ;; Support POSIX?
-       (let ((chars "-a-z0-9_=#$@~%&*+\\/[:word:]")
-	     (punct "!?:;.,"))
-	 (concat
-	  "\\(?:"
-	  ;; Match paired parentheses, e.g. in Wikipedia URLs:
-	  "[" chars punct "]+" "(" "[" chars punct "]+" ")" "[" chars "]"
-	  "\\|"
-	  "[" chars punct     "]+" "[" chars "]"
-	  "\\)"))
-     (concat ;; XEmacs 21.4 doesn't support POSIX.
-      "\\([-a-z0-9_=!?#$@~%&*+\\/:;.,]\\|\\w\\)+"
-      "\\([-a-z0-9_=#$@~%&*+\\/]\\|\\w\\)"))
-   "\\)")
+(defvar rcirc-url-regexp browse-url-button-regexp
   "Regexp matching URLs.  Set to nil to disable URL features in rcirc.")
 
 ;; cf cl-remove-if-not
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0004-Fix-checkdoc-complaints-and-related-issues.patch --]
[-- Type: text/x-diff, Size: 47855 bytes --]

From 599cd7c092fe0f7675a93ba63b3b0af177ed1a5a Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Fri, 4 Jun 2021 14:14:35 +0200
Subject: [PATCH 04/11] Fix checkdoc complaints and related issues

---
 lisp/net/rcirc.el | 434 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 334 insertions(+), 100 deletions(-)

diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index 00d48ba0e2..1f925b00b1 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -25,7 +25,7 @@
 ;;; Commentary:
 
 ;; Internet Relay Chat (IRC) is a form of instant communication over
-;; the Internet. It is mainly designed for group (many-to-many)
+;; the Internet.  It is mainly designed for group (many-to-many)
 ;; communication in discussion forums called channels, but also allows
 ;; one-to-one communication.
 
@@ -47,6 +47,7 @@
 (require 'auth-source)
 (require 'browse-url)
 (eval-when-compile (require 'subr-x))
+(eval-when-compile (require 'rx))
 
 (defconst rcirc-id-string (concat "rcirc on GNU Emacs " emacs-version))
 
@@ -110,8 +111,9 @@ rcirc-server-alist
 
 `:server-alias'
 
-VALUE must be a string that will be used instead of the server name for
-display purposes. If absent, the real server name will be displayed instead."
+VALUE must be a string that will be used instead of the server
+name for display purposes.  If absent, the real server name will
+be displayed instead."
   :type '(alist :key-type string
 		:value-type (plist :options
                                    ((:nick string)
@@ -182,17 +184,18 @@ rcirc-url-max-length
                  (integer :tag "Number of characters")))
 
 (defvar-local rcirc-ignore-buffer-activity-flag nil
-  "If non-nil, ignore activity in this buffer.")
+  "Non-nil means ignore activity in this buffer.")
 
 (defvar-local rcirc-low-priority-flag nil
-  "If non-nil, activity in this buffer is considered low priority.")
+  "Non-nil means activity in this buffer is considered low priority.")
 
 (defcustom rcirc-omit-responses
   '("JOIN" "PART" "QUIT" "NICK")
   "Responses which will be hidden when `rcirc-omit-mode' is enabled."
   :type '(repeat string))
 
-(defvar rcirc-prompt-start-marker nil)
+(defvar rcirc-prompt-start-marker nil
+  "Marker indicating the beginning of the message prompt.")
 
 (define-minor-mode rcirc-omit-mode
   "Toggle the hiding of \"uninteresting\" lines.
@@ -231,8 +234,7 @@ rcirc-buffer-maximum-lines
                  (integer :tag "Number of lines")))
 
 (defcustom rcirc-scroll-show-maximum-output t
-  "If non-nil, scroll buffer to keep the point at the bottom of
-the window."
+  "Non-nil means scroll to keep the point at the bottom of the window."
   :type 'boolean)
 
 (defcustom rcirc-authinfo nil
@@ -293,8 +295,9 @@ rcirc-prompt
 %s is the server.
 %t is the buffer target, a channel or a user.
 
-Setting this alone will not affect the prompt;
-use either M-x customize or also call `rcirc-update-prompt'."
+Setting this alone will not affect the prompt; use either
+\\[execute-extended-command] customize or also call
+`rcirc-update-prompt'."
   :type 'string
   :set #'rcirc-set-changed
   :initialize 'custom-initialize-default)
@@ -388,11 +391,14 @@ rcirc-kill-channel-buffers
   :version "24.3"
   :type 'boolean)
 
-(defvar rcirc-nick nil)
+(defvar rcirc-nick nil
+  "The nickname used for the current connection.")
 
-(defvar rcirc-prompt-end-marker nil)
+(defvar rcirc-prompt-end-marker nil
+  "Marker indicating the end of the message prompt.")
 
-(defvar rcirc-nick-table nil)
+(defvar rcirc-nick-table nil
+  "Hash table mapping nicks to channels.")
 
 (defvar rcirc-recent-quit-alist nil
   "Alist of nicks that have recently quit or parted the channel.")
@@ -405,8 +411,8 @@ rcirc-nick-syntax-table
     table)
   "Syntax table which includes all nick characters as word constituents.")
 
-;; each process has an alist of (target . buffer) pairs
-(defvar rcirc-buffer-alist nil)
+(defvar rcirc-buffer-alist nil
+  "Alist of (TARGET . BUFFER) pairs.")
 
 (defvar rcirc-activity nil
   "List of buffers with unviewed activity.")
@@ -432,7 +438,8 @@ rcirc-timeout-seconds
   "Kill connection after this many seconds if there is no activity.")
 
 \f
-(defvar rcirc-startup-channels nil)
+(defvar rcirc-startup-channels nil
+  "List of channel names to join after authenticating.")
 
 (defvar rcirc-server-name-history nil
   "History variable for \\[rcirc] call.")
@@ -539,23 +546,43 @@ rcirc
 (defalias 'irc 'rcirc)
 
 \f
-(defvar rcirc-process-output nil)
-(defvar rcirc-topic nil)
-(defvar rcirc-keepalive-timer nil)
-(defvar rcirc-last-server-message-time nil)
-(defvar rcirc-server nil)		; server provided by server
-(defvar rcirc-server-name nil)		; server name given by 001 response
-(defvar rcirc-timeout-timer nil)
-(defvar rcirc-user-authenticated nil)
-(defvar rcirc-user-disconnect nil)
-(defvar rcirc-connecting nil)
-(defvar rcirc-connection-info nil)
-(defvar rcirc-process nil)
+(defvar rcirc-process-output nil
+  "Partial message response.")
+(defvar rcirc-topic nil
+  "Topic of the current channel.")
+(defvar rcirc-keepalive-timer nil
+  "Timer for sending KEEPALIVE message.")
+(defvar rcirc-last-server-message-time nil
+  "Timestamp for the last server response.")
+(defvar rcirc-server nil
+  "Server provided by server.")
+(defvar rcirc-server-name nil
+  "Server name given by 001 response.")
+(defvar rcirc-timeout-timer nil
+  "Timer for determining a network timeout.")
+(defvar rcirc-user-authenticated nil
+  "Flag indicating if the user is authenticated.")
+(defvar rcirc-user-disconnect nil
+  "Flag indicating if the connection was broken.")
+(defvar rcirc-connecting nil
+  "Flag indicating if the connection is being established.")
+(defvar rcirc-connection-info nil
+  "Information about the current connection.
+If defined, it is a list of this form (SERVER PORT NICK USER-NAME
+FULL-NAME STARTUP-CHANNELS PASSWORD ENCRYPTION SERVER-ALIAS).
+See `rcirc-connect' for more details on these variables.")
+(defvar rcirc-process nil
+  "Network process for the current connection.")
 
 ;;;###autoload
 (defun rcirc-connect (server &optional port nick user-name
                              full-name startup-channels password encryption
                              server-alias)
+  "Connect to SERVER.
+The arguments PORT, NICK, USER-NAME, FULL-NAME, PASSWORD,
+ENCRYPTION, SERVER-ALIAS are interpreted as in
+`rcirc-server-alist'.  STARTUP-CHANNELS is a list of channels
+that are joined after authentication."
   (save-excursion
     (message "Connecting to %s..." (or server-alias server))
     (let* ((inhibit-eol-conversion)
@@ -619,11 +646,13 @@ rcirc-connect
       process)))
 
 (defmacro with-rcirc-process-buffer (process &rest body)
+  "Evaluate BODY in the buffer of PROCESS."
   (declare (indent 1) (debug t))
   `(with-current-buffer (process-buffer ,process)
      ,@body))
 
 (defmacro with-rcirc-server-buffer (&rest body)
+  "Evaluate BODY in the server buffer of the current channel."
   (declare (indent 0) (debug t))
   `(with-current-buffer rcirc-server-buffer
      ,@body))
@@ -659,14 +688,18 @@ rcirc-keepalive
     (setq rcirc-keepalive-timer nil)))
 
 (defun rcirc-handler-ctcp-KEEPALIVE (process _target _sender message)
+  "Uptime header in PROCESS buffer.
+MESSAGE should contain a timestamp, indicating when the KEEPALIVE
+message was generated."
   (with-rcirc-process-buffer process
     (setq header-line-format
 	  (format "%f" (float-time
 			(time-since (string-to-number message)))))))
 
-(defvar rcirc-debug-buffer "*rcirc debug*")
+(defvar rcirc-debug-buffer "*rcirc debug*"
+  "Buffer name for debugging messages.")
 (defvar rcirc-debug-flag nil
-  "If non-nil, write information to `rcirc-debug-buffer'.")
+  "Non-nil means write information to `rcirc-debug-buffer'.")
 (defun rcirc-debug (process text)
   "Add an entry to the debug log including PROCESS and TEXT.
 Debug text is appended to `rcirc-debug-buffer' if `rcirc-debug-flag'
@@ -728,6 +761,8 @@ rcirc-sentinel
       (run-hook-with-args 'rcirc-sentinel-functions process sentinel))))
 
 (defun rcirc-disconnect-buffer (&optional buffer)
+  "Disconnect BUFFER.
+If BUFFER is nil, default to the current buffer."
   (with-current-buffer (or buffer (current-buffer))
     ;; set rcirc-target to nil for each channel so cleanup
     ;; doesn't happen when we reconnect
@@ -765,6 +800,7 @@ rcirc-filter
           (rcirc-process-server-response process line))))))
 
 (defun rcirc-reschedule-timeout (process)
+  "Update timeout indicator for PROCESS."
   (with-rcirc-process-buffer process
     (when (not rcirc-connecting)
       (with-rcirc-process-buffer process
@@ -776,8 +812,10 @@ rcirc-reschedule-timeout
 (defun rcirc-delete-process (process)
   (delete-process process))
 
-(defvar rcirc-trap-errors-flag t)
+(defvar rcirc-trap-errors-flag t
+  "Non-nil means Lisp errors are degraded to error messages.")
 (defun rcirc-process-server-response (process text)
+  "Parse TEXT as received from PROCESS."
   (if rcirc-trap-errors-flag
       (condition-case err
           (rcirc-process-server-response-1 process text)
@@ -786,13 +824,21 @@ rcirc-process-server-response
                       (format "\"%s\" %s" text err) t)))
     (rcirc-process-server-response-1 process text)))
 
-(defun rcirc-process-server-response-1 (process text)
+(defconst rcirc-process-regexp
   ;; See https://tools.ietf.org/html/rfc2812#section-2.3.1.  We're a
   ;; bit more accepting than the RFC: We allow any non-space
   ;; characters in the command name, multiple spaces between
   ;; arguments, and allow the last argument to omit the leading ":",
   ;; even if there are less than 15 arguments.
-  (if (string-match "^\\(:\\([^ ]+\\) \\)?\\([^ ]+\\)" text)
+  (rx line-start
+      (optional
+       (group ":" (group (one-or-more (not (any " ")))) " "))
+      (group (one-or-more (not (any " ")))))
+  "Regular expression used for parsing server response.")
+
+(defun rcirc-process-server-response-1 (process text)
+  "Parse TEXT as received from PROCESS."
+  (if (string-match rcirc-process-regexp text)
       (let* ((user (match-string 2 text))
 	     (sender (rcirc-user-nick user))
              (cmd (match-string 3 text))
@@ -820,12 +866,17 @@ rcirc-responses-no-activity
   "Responses that don't trigger activity in the mode-line indicator.")
 
 (defun rcirc-handler-generic (process response sender args _text)
-  "Generic server response handler."
+  "Generic server response handler.
+This handler is called, when no more specific handler could be
+found.  PROCESS, SENDER and RESPONSE are passed on to
+`rcirc-print'.  ARGS are concatenated into a single string and
+used as the message body."
   (rcirc-print process sender response nil
                (mapconcat 'identity (cdr args) " ")
 	       (not (member response rcirc-responses-no-activity))))
 
 (defun rcirc--connection-open-p (process)
+  "Check if PROCESS is open or running."
   (memq (process-status process) '(run open)))
 
 (defun rcirc-send-string (process string)
@@ -839,6 +890,7 @@ rcirc-send-string
     (process-send-string process string)))
 
 (defun rcirc-send-privmsg (process target string)
+  "Send TARGET the message in STRING via PROCESS."
   (cl-check-type target string)
   (rcirc-send-string process (format "PRIVMSG %s :%s" target string)))
 
@@ -846,6 +898,7 @@ rcirc-send-ctcp
   (let ((args (if args (concat " " args) "")))
     (rcirc-send-privmsg process target
                         (format "\C-a%s%s\C-a" request args))))
+  "Send TARGET a REQUEST via PROCESS."
 
 (defun rcirc-buffer-process (&optional buffer)
   "Return the process associated with channel BUFFER.
@@ -908,13 +961,18 @@ rcirc-send-message
       (unless silent
 	(rcirc-print process (rcirc-nick process) response target msg)))))
 
-(defvar rcirc-input-ring nil)
-(defvar rcirc-input-ring-index 0)
+(defvar rcirc-input-ring nil
+  "Ring object for input.")
+
+(defvar rcirc-input-ring-index 0
+  "Current position in the input ring.")
 
 (defun rcirc-prev-input-string (arg)
+  "Move ARG elements ahead in the input ring."
   (ring-ref rcirc-input-ring (+ rcirc-input-ring-index arg)))
 
 (defun rcirc-insert-prev-input ()
+  "Insert previous element in input ring."
   (interactive)
   (when (<= rcirc-prompt-end-marker (point))
     (delete-region rcirc-prompt-end-marker (point-max))
@@ -922,6 +980,7 @@ rcirc-insert-prev-input
     (setq rcirc-input-ring-index (1+ rcirc-input-ring-index))))
 
 (defun rcirc-insert-next-input ()
+  "Insert next element in input ring."
   (interactive)
   (when (<= rcirc-prompt-end-marker (point))
     (delete-region rcirc-prompt-end-marker (point-max))
@@ -966,8 +1025,11 @@ rcirc-completion-at-point
 					    rcirc-target))))
 	 (list beg (point) table))))
 
-(defvar rcirc-completions nil)
-(defvar rcirc-completion-start nil)
+(defvar rcirc-completions nil
+  "List of possible completions to cycle through.")
+
+(defvar rcirc-completion-start nil
+  "Point indicating where completion starts.")
 
 (defun rcirc-complete ()
   "Cycle through completions from list of nicks in channel or IRC commands.
@@ -997,12 +1059,12 @@ rcirc-complete
         (t completion))))))
 
 (defun set-rcirc-decode-coding-system (coding-system)
-  "Set the decode coding system used in this channel."
+  "Set the decode CODING-SYSTEM used in this channel."
   (interactive "zCoding system for incoming messages: ")
   (setq-local rcirc-decode-coding-system coding-system))
 
 (defun set-rcirc-encode-coding-system (coding-system)
-  "Set the encode coding system used in this channel."
+  "Set the encode CODING-SYSTEM used in this channel."
   (interactive "zCoding system for outgoing messages: ")
   (setq-local rcirc-encode-coding-system coding-system))
 
@@ -1040,7 +1102,8 @@ rcirc-short-buffer-name
 (defvar rcirc-mode-hook nil
   "Hook run when setting up rcirc buffer.")
 
-(defvar rcirc-last-post-time nil)
+(defvar rcirc-last-post-time nil
+  "Timestamp indicating last user action.")
 
 (defvar rcirc-log-alist nil
   "Alist of lines to log to disk when `rcirc-log-flag' is non-nil.
@@ -1161,7 +1224,7 @@ rcirc-update-prompt
 				       'front-sticky t 'rear-nonsticky t))))))))
 
 (defun rcirc-set-changed (option value)
-  "Set OPTION to VALUE and do updates after a customization change."
+  "Set OPTION to VALUE and update after a customization change."
   (set-default option value)
   (cond ((eq option 'rcirc-prompt)
 	 (rcirc-update-prompt 'all))
@@ -1204,10 +1267,11 @@ rcirc-kill-buffer-hook
 	(kill-buffer (cdr channel))))))
 
 (defun rcirc-change-major-mode-hook ()
-  "Part the channel when changing the major-mode."
+  "Part the channel when changing the major mode."
   (rcirc-clean-up-buffer "Changed major mode"))
 
 (defun rcirc-clean-up-buffer (reason)
+  "Clean up current buffer and part with REASON."
   (let ((buffer (current-buffer)))
     (rcirc-clear-activity buffer)
     (when (and (rcirc-buffer-process)
@@ -1296,6 +1360,8 @@ rcirc-send-input
 	  (setq rcirc-input-ring-index 0))))))
 
 (defun rcirc-fill-paragraph (&optional justify)
+  "Implementation for `fill-paragraph-function'.
+The argument JUSTIFY is passed on to `fill-region'."
   (interactive "P")
   (when (> (point) rcirc-prompt-end-marker)
     (save-restriction
@@ -1305,12 +1371,14 @@ rcirc-fill-paragraph
 
 (defun rcirc-process-input-line (line)
   (if (string-match "^/\\([^ ]+\\) ?\\(.*\\)$" line)
+  "Process LINE as a message or a command."
       (rcirc-process-command (match-string 1 line)
 			     (match-string 2 line)
 			     line)
     (rcirc-process-message line)))
 
 (defun rcirc-process-message (line)
+  "Process LINE as a message to be sent."
   (if (not rcirc-target)
       (message "Not joined (no target)")
     (delete-region rcirc-prompt-end-marker (point))
@@ -1329,6 +1397,9 @@ rcirc-process-command
 	(if (string= command "me")
 	    (rcirc-print process (rcirc-buffer-nick)
 			 "ACTION" rcirc-target args)
+  "Process COMMAND with arguments ARGS.
+LINE is the raw input, from which COMMAND and ARGS was
+extracted."
 	  (rcirc-print process (rcirc-buffer-nick)
 		       "COMMAND" rcirc-target line))
 	(set-marker rcirc-prompt-end-marker (point))
@@ -1337,9 +1408,14 @@ rcirc-process-command
 	  (rcirc-send-string process
 			     (concat command " :" args)))))))
 
-(defvar-local rcirc-parent-buffer nil)
+
+(defvar-local rcirc-parent-buffer nil
+  "Message buffer that requested a multiline buffer.")
 (put 'rcirc-parent-buffer 'permanent-local t)
-(defvar rcirc-window-configuration nil)
+
+(defvar rcirc-window-configuration nil
+  "Window configuration before creating multiline buffer.")
+
 (defun rcirc-edit-multiline ()
   "Move current edit to a dedicated buffer."
   (interactive)
@@ -1435,9 +1511,10 @@ rcirc-response-formats
                 :value-type string))
 
 (defun rcirc-format-response-string (process sender response target text)
-  "Return a nicely-formatted response string, incorporating TEXT
-\(and perhaps other arguments).  The specific formatting used
-is found by looking up RESPONSE in `rcirc-response-formats'."
+  "Return a formatted response string from SENDER, incorporating TEXT.
+The specific formatting used is found by looking up RESPONSE in
+`rcirc-response-formats'.  PROCESS is the process object used for
+communication."
   (with-temp-buffer
     (insert (or (cdr (assoc response rcirc-response-formats))
 		(cdr (assq t rcirc-response-formats))))
@@ -1491,7 +1568,8 @@ rcirc-format-response-string
       (buffer-substring (point-min) (point-max))))
 
 (defun rcirc-target-buffer (process sender response target _text)
-  "Return a buffer to print the server response."
+  "Return a buffer to print the server response from SENDER.
+PROCESS is the process object for the current connection."
   (cl-assert (not (bufferp target)))
   (with-rcirc-process-buffer process
     (cond ((not target)
@@ -1507,8 +1585,9 @@ rcirc-target-buffer
 	  ((or (rcirc-get-buffer process target)
 	       (rcirc-any-buffer process))))))
 
-(defvar-local rcirc-activity-types nil)
 (defvar-local rcirc-last-sender nil)
+(defvar-local rcirc-activity-types nil
+  "List of symbols designating kinds of activities in a buffer.")
 
 (defcustom rcirc-omit-threshold 100
   "Lines since last activity from a nick before `rcirc-omit-responses' are omitted."
@@ -1521,14 +1600,16 @@ rcirc-log-process-buffers
 
 (defun rcirc-last-quit-line (process nick target)
   "Return the line number where NICK left TARGET.
-Returns nil if the information is not recorded."
+Returns nil if the information is not recorded.
+PROCESS is the process object for the current connection."
   (let ((chanbuf (rcirc-get-buffer process target)))
     (when chanbuf
       (cdr (assoc-string nick (with-current-buffer chanbuf
 				rcirc-recent-quit-alist))))))
 
 (defun rcirc-last-line (process nick target)
-  "Return the line from the last activity from NICK in TARGET."
+  "Return the line from the last activity from NICK in TARGET.
+PROCESS is the process object for the current connection."
   (let ((line (or (cdr (assoc-string target
 				     (gethash nick (with-rcirc-server-buffer
 						     rcirc-nick-table)) t))
@@ -1539,7 +1620,8 @@ rcirc-last-line
       nil)))
 
 (defun rcirc-elapsed-lines (process nick target)
-  "Return the number of lines since activity from NICK in TARGET."
+  "Return the number of lines since activity from NICK in TARGET.
+PROCESS is the process object for the current connection."
   (let ((last-activity-line (rcirc-last-line process nick target)))
     (when (and last-activity-line
 	       (> last-activity-line 0))
@@ -1551,7 +1633,6 @@ rcirc-markup-text-functions
     rcirc-markup-urls
     rcirc-markup-keywords
     rcirc-markup-bright-nicks)
-
   "List of functions used to manipulate text before it is printed.
 
 Each function takes two arguments, SENDER, and RESPONSE.  The
@@ -1561,7 +1642,8 @@ rcirc-markup-text-functions
 (defun rcirc-print (process sender response target text &optional activity)
   "Print TEXT in the buffer associated with TARGET.
 Format based on SENDER and RESPONSE.  If ACTIVITY is non-nil,
-record activity."
+record activity.  PROCESS is the process object for the current
+connection."
   (or text (setq text ""))
   (unless (and (or (member sender rcirc-ignore-list)
 		   (member (with-syntax-table rcirc-nick-syntax-table
@@ -1690,6 +1772,7 @@ rcirc-print
 			    process sender response target text)))))
 
 (defun rcirc-generate-log-filename (process target)
+  "Return filename for log file based on PROCESS and TARGET."
   (if target
       (rcirc-generate-new-buffer-name process target)
     (process-name process)))
@@ -1711,7 +1794,9 @@ rcirc-log-filename-function
   :type 'function)
 
 (defun rcirc-log (process sender response target text)
-  "Record line in `rcirc-log', to be later written to disk."
+  "Record TEXT from SENDER to TARGET to be logged.
+The message is logged in `rcirc-log', and is later written to
+disk.  PROCESS is the process object for the current connection."
   (let ((filename (funcall rcirc-log-filename-function process target)))
     (unless (null filename)
       (let ((cell (assoc-string filename rcirc-log-alist))
@@ -1750,14 +1835,17 @@ rcirc-view-log-file
 		     rcirc-log-directory)))
 
 (defun rcirc-join-channels (process channels)
-  "Join CHANNELS."
+  "Join CHANNELS.
+PROCESS is the process object for the current connection."
   (save-window-excursion
     (dolist (channel channels)
       (with-rcirc-process-buffer process
 	(rcirc-cmd-join channel process)))))
 \f
 ;;; nick management
-(defvar rcirc-nick-prefix-chars "~&@%+")
+(defvar rcirc-nick-prefix-chars '(?~ ?& ?@ ?% ?+)
+  "List of junk characters to strip from nick prefixes.")
+
 (defun rcirc-user-nick (user)
   "Return the nick from USER.  Remove any non-nick junk."
   (save-match-data
@@ -1767,7 +1855,8 @@ rcirc-user-nick
       user)))
 
 (defun rcirc-nick-channels (process nick)
-  "Return list of channels for NICK."
+  "Return list of channels for NICK.
+PROCESS is the process object for the current connection."
   (with-rcirc-process-buffer process
     (mapcar (lambda (x) (car x))
 	    (gethash nick rcirc-nick-table))))
@@ -1777,7 +1866,7 @@ rcirc-put-nick-channel
 Update the associated linestamp if LINE is non-nil.
 
 If the record doesn't exist, and LINE is nil, set the linestamp
-to zero."
+to zero.  PROCESS is the process object for the current connection."
   (let ((nick (rcirc-user-nick nick)))
     (with-rcirc-process-buffer process
       (let* ((chans (gethash nick rcirc-nick-table))
@@ -1789,12 +1878,14 @@ rcirc-put-nick-channel
 		   rcirc-nick-table))))))
 
 (defun rcirc-nick-remove (process nick)
-  "Remove NICK from table."
+  "Remove NICK from table.
+PROCESS is the process object for the current connection."
   (with-rcirc-process-buffer process
     (remhash nick rcirc-nick-table)))
 
 (defun rcirc-remove-nick-channel (process nick channel)
-  "Remove the CHANNEL from list associated with NICK."
+  "Remove the CHANNEL from list associated with NICK.
+PROCESS is the process object for the current connection."
   (with-rcirc-process-buffer process
     (let* ((chans (gethash nick rcirc-nick-table))
            (newchans
@@ -1808,7 +1899,8 @@ rcirc-remove-nick-channel
         (remhash nick rcirc-nick-table)))))
 
 (defun rcirc-channel-nicks (process target)
-  "Return the list of nicks associated with TARGET sorted by last activity."
+  "Return the list of nicks associated with TARGET sorted by last activity.
+PROCESS is the process object for the current connection."
   (when target
     (if (rcirc-channel-p target)
 	(with-rcirc-process-buffer process
@@ -1827,8 +1919,9 @@ rcirc-channel-nicks
       (list target))))
 
 (defun rcirc-ignore-update-automatic (nick)
-  "Remove NICK from `rcirc-ignore-list'
-if NICK is also on `rcirc-ignore-list-automatic'."
+  "Check if NICK is in `rcirc-ignore-list-automatic'.
+If so, remove from `rcirc-ignore-list'.  PROCESS is the process
+object for the current connection."
   (when (member nick rcirc-ignore-list-automatic)
       (setq rcirc-ignore-list-automatic
 	    (delete nick rcirc-ignore-list-automatic)
@@ -1836,7 +1929,7 @@ rcirc-ignore-update-automatic
 	    (delete nick rcirc-ignore-list))))
 \f
 (defun rcirc-nickname< (s1 s2)
-  "Return t if IRC nickname S1 is less than S2, and nil otherwise.
+  "Return non-nil if IRC nickname S1 is less than S2, and nil otherwise.
 Operator nicknames (@) are considered less than voiced
 nicknames (+).  Any other nicknames are greater than voiced
 nicknames.  The comparison is case-insensitive."
@@ -2032,6 +2125,7 @@ rcirc-update-activity-string
     (run-hooks 'rcirc-update-activity-string-hook)))
 
 (defun rcirc-activity-string (buffers)
+  "Generate activity string for all BUFFERS."
   (mapconcat (lambda (b)
 	       (let ((s (substring-no-properties (rcirc-short-buffer-name b))))
 		 (with-current-buffer b
@@ -2050,7 +2144,7 @@ rcirc-short-buffer-name
     (or rcirc-short-buffer-name (buffer-name))))
 
 (defun rcirc-visible-buffers ()
-  "Return a list of the visible buffers that are in rcirc-mode."
+  "Return a list of the visible buffers that are in `rcirc-mode'."
   (let (acc)
     (walk-windows (lambda (w)
 		    (with-current-buffer (window-buffer w)
@@ -2058,13 +2152,16 @@ rcirc-visible-buffers
 			(push (current-buffer) acc)))))
     acc))
 
-(defvar rcirc-visible-buffers nil)
+(defvar rcirc-visible-buffers nil
+  "List of visible IRC buffers.")
+
 (defun rcirc-window-configuration-change ()
+  "Clear activity and overlay arrows, unless minibuffer is active."
   (unless (minibuffer-window-active-p (minibuffer-window))
     (rcirc-window-configuration-change-1)))
 
 (defun rcirc-window-configuration-change-1 ()
-  ;; clear activity and overlay arrows
+  "Clear activity and overlay arrows."
   (let* ((old-activity rcirc-activity)
 	 (hidden-buffers rcirc-visible-buffers))
 
@@ -2090,6 +2187,7 @@ rcirc-window-configuration-change-1
 \f
 ;;; buffer name abbreviation
 (defun rcirc-update-short-buffer-names ()
+  "Update variable `rcirc-short-buffer-name' for IRC buffers."
   (let ((bufalist
 	 (apply 'append (mapcar (lambda (process)
 				  (with-rcirc-process-buffer process
@@ -2101,10 +2199,15 @@ rcirc-update-short-buffer-names
 	  (setq rcirc-short-buffer-name (car i)))))))
 
 (defun rcirc-abbreviate (pairs)
+  "Generate alist of abbreviated buffer names to buffers.
+PAIRS is the concatenated value of all `rcirc-buffer-alist'
+values, from each process."
   (apply 'append (mapcar 'rcirc-rebuild-tree (rcirc-make-trees pairs))))
 
-(defun rcirc-rebuild-tree (tree &optional acc)
-  (let ((ch (char-to-string (car tree))))
+(defun rcirc-rebuild-tree (tree)
+  "Merge prefix TREE into alist of unique prefixes to buffers."
+  (let ((ch (char-to-string (car tree)))
+        acc)
     (dolist (x (cdr tree))
       (if (listp x)
 	  (setq acc (append acc
@@ -2116,6 +2219,12 @@ rcirc-rebuild-tree
     acc))
 
 (defun rcirc-make-trees (pairs)
+  "Generate tree prefix tree of buffer names.
+PAIRS is a list of (TARGET . BUFFER) entries.  The resulting tree
+is a list of (CHAR . CHILDREN) cons-cells, where CHAR is the
+leading character and CHILDREN is either BUFFER when a unique
+prefix could be found or another tree if it shares the same
+prefix with another element in PAIRS."
   (let (alist)
     (mapc (lambda (pair)
 	    (if (consp pair)
@@ -2148,9 +2257,13 @@ rcirc-make-trees
 ;; the current buffer/channel/user, and ARGS, which is a string
 ;; containing the text following the /cmd.
 
-(defmacro defun-rcirc-command (command argument docstring interactive-form
-				       &rest body)
-  "Define a command."
+(defmacro defun-rcirc-command (command argument
+                                       docstring interactive-form
+			               &rest body)
+  "Define COMMAND that operates on ARGUMENT.
+This macro internally defines an interactive function, prefixing
+COMMAND with `rcirc-cmd-'.  DOCSTRING, INTERACTIVE-FORM and BODY
+are passed directly to `defun'."
   `(progn
      (add-to-list 'rcirc-client-commands ,(concat "/" (symbol-name command)))
      (defun ,(intern (concat "rcirc-cmd-" (symbol-name command)))
@@ -2323,6 +2436,8 @@ kick
     (rcirc-send-string process (concat "KICK " target " " argstring))))
 
 (defun rcirc-cmd-ctcp (args &optional process _target)
+  "Handle ARGS as a CTCP command.
+PROCESS is the process object for the current connection."
   (if (string-match "^\\([^ ]+\\)\\s-+\\(.+\\)$" args)
       (let* ((target (match-string 1 args))
              (request (upcase (match-string 2 args)))
@@ -2334,11 +2449,14 @@ rcirc-cmd-ctcp
                  "usage: /ctcp NICK REQUEST")))
 
 (defun rcirc-ctcp-sender-PING (process target _request)
-  "Send a CTCP PING message to TARGET."
+  "Send a CTCP PING message to TARGET.
+PROCESS is the process object for the current connection."
   (let ((timestamp (format-time-string "%s")))
     (rcirc-send-ctcp process target "PING" timestamp)))
 
 (defun rcirc-cmd-me (args process target)
+  "Send an action message ARGS to TARGET.
+PROCESS is the process object for the current connection."
   (when target (rcirc-send-ctcp process target "ACTION" args)))
 
 (defun rcirc-add-or-remove (set &rest elements)
@@ -2348,6 +2466,7 @@ rcirc-add-or-remove
 		      (delete elt set)
 		    (cons elt set)))))
   set)
+  "Toggle membership of ELEMENTS in SET."
 
 (defun-rcirc-command ignore (nick)
   "Manage the ignore list.
@@ -2441,11 +2560,13 @@ rcirc-browse-url
                 arg)))
 \f
 (defun rcirc-markup-timestamp (_sender _response)
+  "Insert a timestamp."
   (goto-char (point-min))
   (insert (rcirc-facify (format-time-string rcirc-time-format)
 			'rcirc-timestamp)))
 
 (defun rcirc-markup-attributes (_sender _response)
+  "Highlight IRC markup, indicated by ASCII control codes."
   (while (re-search-forward "\\([\C-b\C-_\C-v]\\).*?\\(\\1\\|\C-o\\)" nil t)
     (rcirc-add-face (match-beginning 0) (match-end 0)
 		    (cl-case (char-after (match-beginning 1))
@@ -2463,6 +2584,9 @@ rcirc-markup-attributes
     (delete-region (match-beginning 0) (match-end 0))))
 
 (defun rcirc-markup-my-nick (_sender response)
+  "Highlight the users nick.
+If RESPONSE indicates that the nick was mentioned in a message,
+highlight the entire line and record the activity."
   (with-syntax-table rcirc-nick-syntax-table
     (while (re-search-forward (concat "\\b"
 				      (regexp-quote (rcirc-nick
@@ -2477,6 +2601,7 @@ rcirc-markup-my-nick
 	(rcirc-record-activity (current-buffer) 'nick)))))
 
 (defun rcirc-markup-urls (_sender _response)
+  "Highlight and activate URLs."
   (while (and rcirc-url-regexp ; nil means disable URL catching.
               (re-search-forward rcirc-url-regexp nil t))
     (let* ((start (match-beginning 0))
@@ -2500,6 +2625,10 @@ rcirc-markup-urls
         (push (cons url start) rcirc-urls)))))
 
 (defun rcirc-markup-keywords (sender response)
+  "Highlight keywords as specified by `rcirc-keywords'.
+Keywords are only highlighted in messages (as indicated by
+RESPONSE) when they were not written by the user (as indicated by
+SENDER)."
   (when (and (string= response "PRIVMSG")
 	     (not (string= sender (rcirc-nick (rcirc-buffer-process)))))
     (let* ((target (or rcirc-target ""))
@@ -2514,6 +2643,9 @@ rcirc-markup-keywords
 	  (rcirc-record-activity (current-buffer) 'keyword))))))
 
 (defun rcirc-markup-bright-nicks (_sender response)
+  "Highlight nicks brightly as specified by `rcirc-bright-nicks'.
+This highlighting only takes place in name lists (as indicated by
+RESPONSE)."
   (when (and rcirc-bright-nicks
 	     (string= response "NAMES"))
     (with-syntax-table rcirc-nick-syntax-table
@@ -2523,6 +2655,8 @@ rcirc-markup-bright-nicks
 
 (defun rcirc-markup-fill (_sender response)
   (when (not (string= response "372")) 	; /motd
+  "Fill messages as configured by `rcirc-fill-column'.
+MOTD messages are not filled (as indicated by RESPONSE)."
     (let ((fill-prefix
 	   (or rcirc-fill-prefix
 	       (make-string (- (point) (line-beginning-position)) ?\s)))
@@ -2539,8 +2673,11 @@ rcirc-markup-fill
 ;; server or a user, depending on the command, the ARGS, which is a
 ;; list of strings, and the TEXT, which is the original server text,
 ;; verbatim
-(defun rcirc-handler-001 (process sender args text)
-  (rcirc-handler-generic process "001" sender args text)
+(defun rcirc-handler-001 (process sender args _text)
+  "Handle welcome message.
+SENDER and ARGS are used to initialize the current connection.
+PROCESS is the process object for the current connection."
+  (rcirc-handler-generic process "001" sender args nil)
   (with-rcirc-process-buffer process
     (setq rcirc-connecting nil)
     (rcirc-reschedule-timeout process)
@@ -2564,11 +2701,16 @@ rcirc-handler-001
       (rcirc-join-channels process rcirc-startup-channels))))
 
 (defun rcirc-join-channels-post-auth (process)
-  "Join `rcirc-startup-channels' after authenticating."
+  "Join `rcirc-startup-channels' after authenticating.
+PROCESS is the process object for the current connection."
   (with-rcirc-process-buffer process
     (rcirc-join-channels process rcirc-startup-channels)))
 
 (defun rcirc-handler-PRIVMSG (process sender args text)
+  "Handle a (private) message from SENDER.
+ARGS should have the form (TARGET MESSAGE).  TEXT is the verbatim
+message as received from the server.  PROCESS is the process
+object for the current connection."
   (rcirc-check-auth-status process sender args text)
   (let ((target (if (rcirc-channel-p (car args))
                     (car args)
@@ -2582,6 +2724,10 @@ rcirc-handler-PRIVMSG
       (rcirc-put-nick-channel process sender target rcirc-current-line))))
 
 (defun rcirc-handler-NOTICE (process sender args text)
+  "Handle a notice message from SENDER.
+ARGS should have the form (TARGET MESSAGE).
+TEXT is the verbatim message as received from the server.
+PROCESS is the process object for the current connection."
   (rcirc-check-auth-status process sender args text)
   (let ((target (car args))
         (message (cadr args)))
@@ -2591,7 +2737,7 @@ rcirc-handler-NOTICE
       (rcirc-print process sender "NOTICE"
 		   (cond ((rcirc-channel-p target)
 			  target)
-			 ;;; -ChanServ- [#gnu] Welcome...
+                         ;; -ChanServ- [#gnu] Welcome...
 			 ((string-match "\\[\\(#[^] ]+\\)\\]" message)
 			  (match-string 1 message))
 			 (sender
@@ -2603,7 +2749,9 @@ rcirc-handler-NOTICE
 (defun rcirc-check-auth-status (process sender args _text)
   "Check if the user just authenticated.
 If authenticated, runs `rcirc-authenticated-hook' with PROCESS as
-the only argument."
+the only argument.  ARGS should have the form (TARGET MESSAGE).
+SENDER is used the determine the authentication method.  PROCESS
+is the process object for the current connection."
   (with-rcirc-process-buffer process
     (when (and (not rcirc-user-authenticated)
                rcirc-authenticate-before-join
@@ -2633,9 +2781,17 @@ rcirc-check-auth-status
           (remove-hook 'rcirc-authenticated-hook 'rcirc-join-channels-post-auth t))))))
 
 (defun rcirc-handler-WALLOPS (process sender args _text)
+  "Handle WALLOPS message from SENDER.
+ARGS should have the form (MESSAGE).
+PROCESS is the process object for the current
+connection."
   (rcirc-print process sender "WALLOPS" sender (car args) t))
 
 (defun rcirc-handler-JOIN (process sender args _text)
+  "Handle JOIN message from SENDER.
+ARGS should have the form (CHANNEL).
+PROCESS is the process object for the current
+connection."
   (let ((channel (car args)))
     (with-current-buffer (rcirc-get-buffer-create process channel)
       ;; when recently rejoining, restore the linestamp
@@ -2657,6 +2813,8 @@ rcirc-handler-JOIN
 
 ;; PART and KICK are handled the same way
 (defun rcirc-handler-PART-or-KICK (process _response channel _sender nick _args)
+  "Remove NICK from CHANNEL.
+PROCESS is the process object for the current connection."
   (rcirc-ignore-update-automatic nick)
   (if (not (string= nick (rcirc-nick process)))
       ;; this is someone else leaving
@@ -2674,6 +2832,9 @@ rcirc-handler-PART-or-KICK
 	(rcirc-disconnect-buffer buffer)))))
 
 (defun rcirc-handler-PART (process sender args _text)
+  "Handle PART message from SENDER.
+ARGS should have the form (CHANNEL REASON).
+PROCESS is the process object for the current connection."
   (let* ((channel (car args))
 	 (reason (cadr args))
 	 (message (concat channel " " reason)))
@@ -2685,6 +2846,9 @@ rcirc-handler-PART
     (rcirc-handler-PART-or-KICK process "PART" channel sender sender reason)))
 
 (defun rcirc-handler-KICK (process sender args _text)
+  "Handle PART message from SENDER.
+ARGS should have the form (CHANNEL NICK REASON).
+PROCESS is the process object for the current connection."
   (let* ((channel (car args))
 	 (nick (cadr args))
 	 (reason (nth 2 args))
@@ -2697,7 +2861,8 @@ rcirc-handler-KICK
     (rcirc-handler-PART-or-KICK process "KICK" channel sender nick reason)))
 
 (defun rcirc-maybe-remember-nick-quit (process nick channel)
-  "Remember NICK as leaving CHANNEL if they recently spoke."
+  "Remember NICK as leaving CHANNEL if they recently spoke.
+PROCESS is the process object for the current connection."
   (let ((elapsed-lines (rcirc-elapsed-lines process nick channel)))
     (when (and elapsed-lines
 	       (< elapsed-lines rcirc-omit-threshold))
@@ -2713,6 +2878,8 @@ rcirc-maybe-remember-nick-quit
 			    rcirc-recent-quit-alist))))))))))
 
 (defun rcirc-handler-QUIT (process sender args _text)
+  "Handle QUIT message from SENDER.
+PROCESS is the process object for the current connection."
   (rcirc-ignore-update-automatic sender)
   (mapc (lambda (channel)
 	  ;; broadcast quit message each channel
@@ -2723,6 +2890,9 @@ rcirc-handler-QUIT
   (rcirc-nick-remove process sender))
 
 (defun rcirc-handler-NICK (process sender args _text)
+  "Handle NICK message from SENDER.
+ARGS should have the form (NEW-NICK).
+PROCESS is the process object for the current connection."
   (let* ((old-nick sender)
          (new-nick (car args))
          (channels (rcirc-nick-channels process old-nick)))
@@ -2755,20 +2925,29 @@ rcirc-handler-NICK
 
 (defun rcirc-handler-PING (process _sender args _text)
   (rcirc-send-string process (concat "PONG :" (car args))))
+  "Respond to a PING with a PONG.
+ARGS should have the form (MESSAGE).  MESSAGE is relayed back to
+the server.  PROCESS is the process object for the current
+connection."
 
 (defun rcirc-handler-PONG (_process _sender _args _text)
-  ;; do nothing
-  )
+  "Ignore all incoming PONG messages.")
 
 (defun rcirc-handler-TOPIC (process sender args _text)
+  "Note the topic change from SENDER.
+PROCESS is the process object for the current connection."
   (let ((topic (cadr args)))
     (rcirc-print process sender "TOPIC" (car args) topic)
     (with-current-buffer (rcirc-get-buffer process (car args))
       (setq rcirc-topic topic))))
 
-(defvar rcirc-nick-away-alist nil)
+(defvar rcirc-nick-away-alist nil
+  "Alist from nicks to away messages.")
+
 (defun rcirc-handler-301 (process _sender args text)
-  "RPL_AWAY"
+  "Handle away messages (RPL_AWAY).
+ARGS should have the form (NICK AWAY-MESSAGE).
+PROCESS is the process object for the current connection."
   (let* ((nick (cadr args))
 	 (rec (assoc-string nick rcirc-nick-away-alist))
 	 (away-message (nth 2 args)))
@@ -2782,7 +2961,9 @@ rcirc-handler-301
 					  rcirc-nick-away-alist))))))
 
 (defun rcirc-handler-317 (process sender args _text)
-  "RPL_WHOISIDLE"
+  "Handle idle messages from SENDER (RPL_WHOISIDLE).
+ARGS should have the form (NICK IDLE-SECS SIGNON-TIME).
+PROCESS is the process object for the current connection."
   (let* ((nick (nth 1 args))
          (idle-secs (string-to-number (nth 2 args)))
          (idle-string (format-seconds "%yy %dd %hh %mm %z%ss" idle-secs))
@@ -2793,15 +2974,20 @@ rcirc-handler-317
     (rcirc-print process sender "317" nil message t)))
 
 (defun rcirc-handler-332 (process _sender args _text)
-  "RPL_TOPIC"
+  "Update topic when notified by server (RPL_TOPIC).
+ARGS should have the form (CHANNEL TOPIC).
+PROCESS is the process object for the current connection."
   (let ((buffer (or (rcirc-get-buffer process (cadr args))
 		    (rcirc-get-temp-buffer-create process (cadr args)))))
     (with-current-buffer buffer
       (setq rcirc-topic (nth 2 args)))))
 
 (defun rcirc-handler-333 (process sender args _text)
-  "333 says who set the topic and when.
-Not in rfc1459.txt"
+  "Update when and who set the current topic.
+ARGS has the form (CHANNEL SETTER TIME).  SENDER is passed on to
+`rcirc-print'.  PROCESS is the process object for the current
+connection.  This is a non-standard extension, not specified in
+RFC1459."
   (let ((buffer (or (rcirc-get-buffer process (cadr args))
 		    (rcirc-get-temp-buffer-create process (cadr args)))))
     (with-current-buffer buffer
@@ -2812,10 +2998,17 @@ rcirc-handler-333
 		     (format "%s (%s on %s)" rcirc-topic setter time))))))
 
 (defun rcirc-handler-477 (process sender args _text)
-  "ERR_NOCHANMODES"
+  "Notify user that CHANNEL does not support modes (ERR_NOCHANMODES).
+ARGS has the form (CHANNEL MESSAGE).  SENDER is passed on to
+`rcirc-print'.  PROCESS is the process object for the current
+connection."
   (rcirc-print process sender "477" (cadr args) (nth 2 args)))
 
 (defun rcirc-handler-MODE (process sender args _text)
+  "Handle MODE messages.
+ARGS should have the form (TARGET . MESSAGE-LIST).
+SENDER is passed on to `rcirc-print'.
+PROCESS is the process object for the current connection."
   (let ((target (car args))
         (msg (mapconcat 'identity (cdr args) " ")))
     (rcirc-print process sender "MODE"
@@ -2836,7 +3029,9 @@ rcirc-get-temp-buffer-create
     (get-buffer-create tmpnam)))
 
 (defun rcirc-handler-353 (process _sender args _text)
-  "RPL_NAMREPLY"
+  "Start handling list of users (RPL_NAMREPLY).
+ARGS should have the form (TYPE CHANNEL . NICK-LIST).
+PROCESS is the process object for the current connection."
   (let ((channel (nth 2 args))
 	(names (or (nth 3 args) "")))
     (mapc (lambda (nick)
@@ -2849,7 +3044,9 @@ rcirc-handler-353
       (insert (car (last args)) " "))))
 
 (defun rcirc-handler-366 (process sender args _text)
-  "RPL_ENDOFNAMES"
+  "Handle end of user list (RPL_ENDOFNAMES).
+SENDER is passed on to `rcirc-print'.
+PROCESS is the process object for the current connection."
   (let* ((channel (cadr args))
          (buffer (rcirc-get-temp-buffer-create process channel)))
     (with-current-buffer buffer
@@ -2859,7 +3056,10 @@ rcirc-handler-366
     (kill-buffer buffer)))
 
 (defun rcirc-handler-433 (process sender args text)
-  "ERR_NICKNAMEINUSE"
+  "Warn user that nick is used (ERR_NICKNAMEINUSE).
+ARGS should have the form (NICK CHANNEL WARNING).
+SENDER is passed on to `rcirc-handler-generic'.
+PROCESS is the process object for the current connection."
   (rcirc-handler-generic process "433" sender args text)
   (with-rcirc-process-buffer process
     (let* ((length (string-to-number
@@ -2868,8 +3068,10 @@ rcirc-handler-433
       (rcirc-cmd-nick (rcirc--make-new-nick (cadr args) length) nil process))))
 
 (defun rcirc--make-new-nick (nick length)
-  ;; If we already have some ` chars at the end, then shorten the
-  ;; non-` bit of the name.
+  "Attempt to create a unused nickname out of NICK.
+A new nick may at most be LENGTH characters long.  If we already
+have some ` chars at the end, then shorten the non-` bit of the
+name."
   (when (= (length nick) length)
     (setq nick (replace-regexp-in-string "[^`]\\(`+\\)\\'" "\\1" nick)))
   (concat
@@ -2879,7 +3081,14 @@ rcirc--make-new-nick
    "`"))
 
 (defun rcirc-handler-005 (process sender args text)
-  "ERR_NICKNAMEINUSE"
+  "Register supported server features (RPL_ISUPPORT).
+ARGS should be a list of string feature parameters, either of the
+form \"PARAMETER\" to enable a feature, \"PARAMETER=VALUE\" to
+configure a specific option or \"-PARAMETER\" to disable a
+previously specified feature.  SENDER is passed on to
+`rcirc-handler-generic'.  PROCESS is the process object for the
+current connection.  Note that this is not the behaviour as
+specified in RFC2812, where 005 stood for RPL_BOUNCE."
   (rcirc-handler-generic process "005" sender args text)
   (with-rcirc-process-buffer process
     (setq rcirc-server-parameters (append rcirc-server-parameters args))))
@@ -2924,12 +3133,27 @@ rcirc-authenticate
                (format "AUTH %s %s" nick (car args))))))))))
 
 (defun rcirc-handler-INVITE (process sender args _text)
+  "Notify user of an invitation.
+SENDER and ARGS (in concatenated form) are passed on to
+`rcirc-print'.  PROCESS is the process object for the current
+connection."
   (rcirc-print process sender "INVITE" nil (mapconcat 'identity args " ") t))
 
 (defun rcirc-handler-ERROR (process sender args _text)
+  "Print a error message.
+SENDER and ARGS (in concatenated form) are passed on to
+`rcirc-print'.  PROCESS is the process object for the current
+connection."
   (rcirc-print process sender "ERROR" nil (mapconcat 'identity args " ")))
 
 (defun rcirc-handler-CTCP (process target sender text)
+  "Handle Client-To-Client-Protocol message TEXT.
+The message is addressed from SENDER to TARGET.  Attempt to find
+an appropriate handler, by invoicing the function
+`rcirc-handler-ctcp-REQUEST', where REQUEST is the message type
+as extracted from TEXT.  If no handler was found, an error
+message will be printed.  PROCESS is the process object for the
+current connection."
   (if (string-match "^\\([^ ]+\\) *\\(.*\\)$" text)
       (let* ((request (upcase (match-string 1 text)))
              (args (match-string 2 text))
@@ -2944,22 +3168,31 @@ rcirc-handler-CTCP
               (rcirc-print process sender "CTCP" target
 			   (format "%s" text) t))))))
 
-(defun rcirc-handler-ctcp-VERSION (process _target sender _args)
+(defun rcirc-handler-ctcp-VERSION (process _target sender _message)
+  "Handle a CTCP VERSION message from SENDER.
+PROCESS is the process object for the current connection."
   (rcirc-send-string process
                      (concat "NOTICE " sender
                              " :\C-aVERSION " rcirc-id-string
                              "\C-a")))
 
-(defun rcirc-handler-ctcp-ACTION (process target sender args)
+(defun rcirc-handler-ctcp-ACTION (process target sender message)
+  "Handle a CTCP ACTION MESSAGE from SENDER to TARGET.
+PROCESS is the process object for the current connection."
   (rcirc-print process sender "ACTION" target args t))
 
-(defun rcirc-handler-ctcp-TIME (process _target sender _args)
+(defun rcirc-handler-ctcp-TIME (process _target sender _message)
+  "Respond to CTCP TIME message from SENDER.
+PROCESS is the process object for the current connection."
   (rcirc-send-string process
                      (concat "NOTICE " sender
                              " :\C-aTIME " (current-time-string) "\C-a")))
 
 (defun rcirc-handler-CTCP-response (process _target sender message)
+  "Handle CTCP response MESSAGE from SENDER.
+PROCESS is the process object for the current connection."
   (rcirc-print process sender "CTCP" nil message t))
+
 \f
 (defgroup rcirc-faces nil
   "Faces for rcirc."
@@ -3075,11 +3308,12 @@ rcirc-keyword
 ;; When using M-x flyspell-mode, only check words after the prompt
 (put 'rcirc-mode 'flyspell-mode-predicate 'rcirc-looking-at-input)
 (defun rcirc-looking-at-input ()
-  "Return true if point is past the input marker."
+  "Return non-nil if point is past the input marker."
   (>= (point) rcirc-prompt-end-marker))
 \f
 
 (defun rcirc-server-parameter-value (parameter)
+  "Traverse `rcirc-server-parameters' for PARAMETER."
   (cl-loop for elem in rcirc-server-parameters
            for setting = (split-string elem "=")
            when (and (= (length setting) 2)
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #6: 0005-Improve-formatting-of-rcirc-send-string.patch --]
[-- Type: text/x-diff, Size: 10378 bytes --]

From ec58a1a3cd3fb60bb5f0d14bde535cb1d5c0a457 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Fri, 4 Jun 2021 16:29:27 +0200
Subject: [PATCH 05/11] Improve formatting of rcirc-send-string

---
 lisp/net/rcirc.el | 91 ++++++++++++++++++++++++++---------------------
 1 file changed, 50 insertions(+), 41 deletions(-)

diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index 1f925b00b1..ab5634d75d 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -630,10 +630,9 @@ rcirc-connect
 
       ;; identify
       (unless (zerop (length password))
-        (rcirc-send-string process (concat "PASS " password)))
-      (rcirc-send-string process (concat "NICK " nick))
-      (rcirc-send-string process (concat "USER " user-name
-                                         " 0 * :" full-name))
+        (rcirc-send-string process "PASS" password))
+      (rcirc-send-string process "NICK" nick)
+      (rcirc-send-string process "USER" user-name 0 "*" : full-name)
 
       ;; setup ping timer if necessary
       (unless rcirc-keepalive-timer
@@ -879,9 +878,23 @@ rcirc--connection-open-p
   "Check if PROCESS is open or running."
   (memq (process-status process) '(run open)))
 
-(defun rcirc-send-string (process string)
-  "Send PROCESS a STRING plus a newline."
-  (let ((string (concat (encode-coding-string string rcirc-encode-coding-system)
+(defun rcirc-send-string (process &rest parts)
+  "Send PROCESS a PARTS plus a newline.
+PARTS may contain a `:' symbol, to designate that the next string
+is the message, that should be prefixed by a colon.  If the last
+element in PARTS is a list, append it to PARTS."
+  (let ((last (car (last parts))))
+    (when (listp last)
+      (setf parts (append (butlast parts) last))))
+  (when-let (message (memq : parts))
+    (cl-check-type (cadr message) 'string)
+    (setf (cadr message) (concat ":" (cadr message))
+          parts (remq : parts)))
+  (let ((string (concat (encode-coding-string
+                         (mapconcat
+                          (apply-partially #'format "%s")
+                          parts " ")
+                         rcirc-encode-coding-system)
                         "\n")))
     (unless (rcirc--connection-open-p process)
       (error "Network connection to %s is not open"
@@ -892,13 +905,15 @@ rcirc-send-string
 (defun rcirc-send-privmsg (process target string)
   "Send TARGET the message in STRING via PROCESS."
   (cl-check-type target string)
-  (rcirc-send-string process (format "PRIVMSG %s :%s" target string)))
+  (rcirc-send-string process "PRIVMSG" target : string))
+
+(defun rcirc-ctcp-wrap (&rest args)
+  "Join ARGS into a string wrapped by ASCII 1 charterers."
+  (concat "\C-a" (string-join (delq nil args) " ") "\C-a"))
 
 (defun rcirc-send-ctcp (process target request &optional args)
-  (let ((args (if args (concat " " args) "")))
-    (rcirc-send-privmsg process target
-                        (format "\C-a%s%s\C-a" request args))))
   "Send TARGET a REQUEST via PROCESS."
+  (rcirc-send-privmsg process target (rcirc-ctcp-wrap request args)))
 
 (defun rcirc-buffer-process (&optional buffer)
   "Return the process associated with channel BUFFER.
@@ -957,7 +972,7 @@ rcirc-send-message
   (let ((response (if noticep "NOTICE" "PRIVMSG")))
     (rcirc-get-buffer-create process target)
     (dolist (msg (rcirc-split-message message))
-      (rcirc-send-string process (concat response " " target " :" msg))
+      (rcirc-send-string process response target : msg)
       (unless silent
 	(rcirc-print process (rcirc-nick process) response target msg)))))
 
@@ -1282,7 +1297,7 @@ rcirc-clean-up-buffer
       (rcirc-update-short-buffer-names)
       (if (rcirc-channel-p rcirc-target)
 	  (rcirc-send-string (rcirc-buffer-process)
-			     (concat "PART " rcirc-target " :" reason))
+                             "PART" rcirc-target : reason)
 	(when rcirc-target
 	  (rcirc-remove-nick-channel (rcirc-buffer-process)
 				     (rcirc-buffer-nick)
@@ -2313,7 +2328,7 @@ join
                             (rcirc-get-buffer-create process ch))
                           split-channels))
          (channels (mapconcat 'identity split-channels ",")))
-    (rcirc-send-string process (concat "JOIN " channels))
+    (rcirc-send-string process "JOIN" channels)
     (when (not (eq (selected-window) (minibuffer-window)))
       (dolist (b buffers) ;; order the new channel buffers in the buffer list
         (switch-to-buffer b)))))
@@ -2326,7 +2341,7 @@ invite
 				  (with-rcirc-server-buffer rcirc-nick-table))
 		 " "
 		 (read-string "Channel: "))))
-  (rcirc-send-string process (concat "INVITE " nick-channel)))
+  (rcirc-send-string process "INVITE" nick-channel))
 
 (defun-rcirc-command part (channel)
   "Part CHANNEL.
@@ -2342,15 +2357,14 @@ part
       (setq channel (if (match-beginning 1)
                         (match-string 1 channel)
                       target)))
-    (rcirc-send-string process (concat "PART " channel " :" msg))))
+    (rcirc-send-string process "PART" : msg)))
 
 (defun-rcirc-command quit (reason)
   "Send a quit message to server with REASON."
   (interactive "sQuit reason: ")
-  (rcirc-send-string process (concat "QUIT :"
-				     (if (not (zerop (length reason)))
+  (rcirc-send-string process "QUIT" : (if (not (zerop (length reason)))
 					 reason
-                                       rcirc-default-quit-reason))))
+                                       rcirc-default-quit-reason)))
 
 (defun-rcirc-command reconnect (_)
   "Reconnect to current server."
@@ -2370,7 +2384,7 @@ nick
   (interactive "i")
   (when (null nick)
     (setq nick (read-string "New nick: " (rcirc-nick process))))
-  (rcirc-send-string process (concat "NICK " nick)))
+  (rcirc-send-string process "NICK" nick))
 
 (defun-rcirc-command names (channel)
   "Display list of names in CHANNEL or in current channel if CHANNEL is nil.
@@ -2382,7 +2396,7 @@ names
   (let ((channel (if (> (length channel) 0)
                      channel
                    target)))
-    (rcirc-send-string process (concat "NAMES " channel))))
+    (rcirc-send-string process "NAMES" channel)))
 
 (defun-rcirc-command topic (topic)
   "List TOPIC for the TARGET channel.
@@ -2390,32 +2404,32 @@ topic
   (interactive "P")
   (if (and (called-interactively-p 'interactive) topic)
       (setq topic (read-string "New Topic: " rcirc-topic)))
-  (rcirc-send-string process (concat "TOPIC " target
-                                     (when (> (length topic) 0)
-                                       (concat " :" topic)))))
+  (if (> (length topic) 0)
+      (rcirc-send-string process "TOPIC" : topic)
+    (rcirc-send-string process "TOPIC")))
 
 (defun-rcirc-command whois (nick)
   "Request information from server about NICK."
   (interactive (list
                 (completing-read "Whois: "
                                  (with-rcirc-server-buffer rcirc-nick-table))))
-  (rcirc-send-string process (concat "WHOIS " nick)))
+  (rcirc-send-string process "WHOIS" nick))
 
 (defun-rcirc-command mode (args)
   "Set mode with ARGS."
   (interactive (list (concat (read-string "Mode nick or channel: ")
                              " " (read-string "Mode: "))))
-  (rcirc-send-string process (concat "MODE " args)))
+  (rcirc-send-string process "MODE" args))
 
 (defun-rcirc-command list (channels)
   "Request information on CHANNELS from server."
   (interactive "sList Channels: ")
-  (rcirc-send-string process (concat "LIST " channels)))
+  (rcirc-send-string process "LIST" channels))
 
 (defun-rcirc-command oper (args)
   "Send operator command to server."
   (interactive "sOper args: ")
-  (rcirc-send-string process (concat "OPER " args)))
+  (rcirc-send-string process "OPER" args))
 
 (defun-rcirc-command quote (message)
   "Send MESSAGE literally to server."
@@ -2430,10 +2444,8 @@ kick
 					  (rcirc-buffer-process)
 					  rcirc-target))
                         (read-from-minibuffer "Kick reason: "))))
-  (let* ((arglist (split-string arg))
-         (argstring (concat (car arglist) " :"
-                            (mapconcat 'identity (cdr arglist) " "))))
-    (rcirc-send-string process (concat "KICK " target " " argstring))))
+  (let ((args (split-string arg)))
+    (rcirc-send-string process "KICK" target (car args) : (cdr args))))
 
 (defun rcirc-cmd-ctcp (args &optional process _target)
   "Handle ARGS as a CTCP command.
@@ -2924,11 +2936,11 @@ rcirc-handler-NICK
         (when rcirc-auto-authenticate-flag (rcirc-authenticate))))))
 
 (defun rcirc-handler-PING (process _sender args _text)
-  (rcirc-send-string process (concat "PONG :" (car args))))
   "Respond to a PING with a PONG.
 ARGS should have the form (MESSAGE).  MESSAGE is relayed back to
 the server.  PROCESS is the process object for the current
 connection."
+  (rcirc-send-string process "PONG" : (car args)))
 
 (defun rcirc-handler-PONG (_process _sender _args _text)
   "Ignore all incoming PONG messages.")
@@ -3171,22 +3183,19 @@ rcirc-handler-CTCP
 (defun rcirc-handler-ctcp-VERSION (process _target sender _message)
   "Handle a CTCP VERSION message from SENDER.
 PROCESS is the process object for the current connection."
-  (rcirc-send-string process
-                     (concat "NOTICE " sender
-                             " :\C-aVERSION " rcirc-id-string
-                             "\C-a")))
+  (rcirc-send-string process "NOTICE" sender :
+                     (rcirc-ctcp-wrap "VERSION" rcirc-id-string)))
 
 (defun rcirc-handler-ctcp-ACTION (process target sender message)
   "Handle a CTCP ACTION MESSAGE from SENDER to TARGET.
 PROCESS is the process object for the current connection."
-  (rcirc-print process sender "ACTION" target args t))
+  (rcirc-print process sender "ACTION" target message t))
 
 (defun rcirc-handler-ctcp-TIME (process _target sender _message)
   "Respond to CTCP TIME message from SENDER.
 PROCESS is the process object for the current connection."
-  (rcirc-send-string process
-                     (concat "NOTICE " sender
-                             " :\C-aTIME " (current-time-string) "\C-a")))
+  (rcirc-send-string process "NOTICE" sender :
+                     (rcirc-ctcp-wrap "TIME" (current-time-string))))
 
 (defun rcirc-handler-CTCP-response (process _target sender message)
   "Handle CTCP response MESSAGE from SENDER.
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #7: 0006-Recognize-quoted-commands-in-rcirc-process-input-lin.patch --]
[-- Type: text/x-diff, Size: 2496 bytes --]

From 195d57c93b1fa23b51b6feb7a8f0973c0051a508 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Fri, 4 Jun 2021 16:32:14 +0200
Subject: [PATCH 06/11] Recognize quoted commands in rcirc-process-input-line

---
 lisp/net/rcirc.el | 33 ++++++++++++++-------------------
 1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index ab5634d75d..040eb60538 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -1385,8 +1385,8 @@ rcirc-fill-paragraph
 	(fill-region (point-min) (point-max) justify)))))
 
 (defun rcirc-process-input-line (line)
-  (if (string-match "^/\\([^ ]+\\) ?\\(.*\\)$" line)
   "Process LINE as a message or a command."
+  (if (string-match "^/\\([^/ ][^ ]*\\) ?\\(.*\\)$" line)
       (rcirc-process-command (match-string 1 line)
 			     (match-string 2 line)
 			     line)
@@ -1401,28 +1401,23 @@ rcirc-process-message
     (setq rcirc-last-post-time (current-time))))
 
 (defun rcirc-process-command (command args line)
-  (if (eq (aref command 0) ?/)
-      ;; "//text" will send "/text" as a message
-      (rcirc-process-message (substring line 1))
-    (let ((fun (intern-soft (concat "rcirc-cmd-" command)))
-	  (process (rcirc-buffer-process)))
-      (newline)
-      (with-current-buffer (current-buffer)
-	(delete-region rcirc-prompt-end-marker (point))
-	(if (string= command "me")
-	    (rcirc-print process (rcirc-buffer-nick)
-			 "ACTION" rcirc-target args)
   "Process COMMAND with arguments ARGS.
 LINE is the raw input, from which COMMAND and ARGS was
 extracted."
+  (let ((fun (intern-soft (concat "rcirc-cmd-" command)))
+	(process (rcirc-buffer-process)))
+    (newline)
+    (with-current-buffer (current-buffer)
+      (delete-region rcirc-prompt-end-marker (point))
+      (if (string= command "me")
 	  (rcirc-print process (rcirc-buffer-nick)
-		       "COMMAND" rcirc-target line))
-	(set-marker rcirc-prompt-end-marker (point))
-	(if (fboundp fun)
-	    (funcall fun args process rcirc-target)
-	  (rcirc-send-string process
-			     (concat command " :" args)))))))
-
+		       "ACTION" rcirc-target args)
+	(rcirc-print process (rcirc-buffer-nick)
+		     "COMMAND" rcirc-target line))
+      (set-marker rcirc-prompt-end-marker (point))
+      (if (fboundp fun)
+	  (funcall fun args process rcirc-target)
+	(rcirc-send-string process command : args)))))
 
 (defvar-local rcirc-parent-buffer nil
   "Message buffer that requested a multiline buffer.")
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #8: 0007-Define-rcirc-mode-using-rcirc-initialize.patch --]
[-- Type: text/x-diff, Size: 6009 bytes --]

From 32b1f35ada7006fabf9a7c8d7302769662250a0e Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Fri, 4 Jun 2021 16:35:05 +0200
Subject: [PATCH 07/11] Define rcirc-mode using rcirc-initialize

---
 lisp/net/rcirc.el | 56 ++++++++++++++++++++++++++---------------------
 1 file changed, 31 insertions(+), 25 deletions(-)

diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index 040eb60538..92d7b383d8 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -774,7 +774,7 @@ rcirc-process-list
     (mapc (lambda (p)
             (when (buffer-live-p (process-buffer p))
               (with-rcirc-process-buffer p
-                (when (eq major-mode 'rcirc-mode)
+                (when (derived-mode-p 'rcirc-mode)
                   (setq ps (cons p ps))))))
           (process-list))
     ps))
@@ -1128,17 +1128,22 @@ rcirc-current-line
   "The current number of responses printed in this channel.
 This number is independent of the number of lines in the buffer.")
 
-(defun rcirc-mode (process target)
-  ;; FIXME: Use define-derived-mode.
-  "Major mode for IRC channel buffers.
+(defun rcirc-initialize (process target)
+  "Initialize current buffer for IRC.
+PROCESS is the process object that the buffer uses to
+communicate.  TARGET designates who the buffer is used to
+communicate to (channel, username)."
+  (let ((rcirc-process process)
+        (rcirc-target target))
+    (rcirc-mode)))
+
+(define-derived-mode rcirc-mode text-mode "rcirc"
+  "Major mode for IRC channel buffers."
+  :interactive nil
+  (cl-assert rcirc-process nil "The variable `rcirc-process' must by bound and non-nil")
+  (cl-assert rcirc-target nil "The variable `rcirc-target' must by bound and non-nil")
 
-\\{rcirc-mode-map}"
-  (kill-all-local-variables)
-  (use-local-map rcirc-mode-map)
-  (setq mode-name "rcirc")
-  (setq major-mode 'rcirc-mode)
   (setq mode-line-process nil)
-
   (setq-local rcirc-input-ring
 	      ;; If rcirc-input-ring is already a ring with desired
 	      ;; size do not re-initialize.
@@ -1147,8 +1152,8 @@ rcirc-mode
 			  rcirc-input-ring-size))
 		  rcirc-input-ring
 		(make-ring rcirc-input-ring-size)))
-  (setq-local rcirc-server-buffer (process-buffer process))
-  (setq-local rcirc-target target)
+  (setq-local rcirc-server-buffer (process-buffer rcirc-process))
+  (setq-local rcirc-target rcirc-target)
   (setq-local rcirc-topic nil)
   (setq-local rcirc-last-post-time (current-time))
   (setq-local fill-paragraph-function 'rcirc-fill-paragraph)
@@ -1171,8 +1176,8 @@ rcirc-mode
   (dolist (i rcirc-coding-system-alist)
     (let ((chan (if (consp (car i)) (caar i) (car i)))
 	  (serv (if (consp (car i)) (cdar i) "")))
-      (when (and (string-match chan (or target ""))
-		 (string-match serv (rcirc-server-name process)))
+      (when (and (string-match chan (or rcirc-target ""))
+		 (string-match serv (rcirc-server-name rcirc-process)))
 	(setq-local rcirc-decode-coding-system
 		    (if (consp (cdr i)) (cadr i) (cdr i)))
         (setq-local rcirc-encode-coding-system
@@ -1192,17 +1197,17 @@ rcirc-mode
   (add-hook 'kill-buffer-hook 'rcirc-kill-buffer-hook nil t)
 
   ;; add to buffer list, and update buffer abbrevs
-  (when target				; skip server buffer
+  (when rcirc-target                    ; skip server buffer
     (let ((buffer (current-buffer)))
-      (with-rcirc-process-buffer process
-	(setq rcirc-buffer-alist (cons (cons target buffer)
+      (with-rcirc-process-buffer rcirc-process
+	(setq rcirc-buffer-alist (cons (cons rcirc-target buffer)
 				       rcirc-buffer-alist))))
     (rcirc-update-short-buffer-names))
 
   (add-hook 'completion-at-point-functions
-            'rcirc-completion-at-point nil 'local)
+            'rcirc-completion-at-point nil 'local))
 
-  (run-mode-hooks 'rcirc-mode-hook))
+(set-advertised-calling-convention 'rcirc-mode '() "28.1")
 
 (defun rcirc-update-prompt (&optional all)
   "Reset the prompt string in the current buffer.
@@ -1269,7 +1274,7 @@ rcirc-kill-buffer-hook
 If `rcirc-kill-channel-buffers' is non-nil and the killed buffer
 is a server buffer, kills all of the channel buffers associated
 with it."
-  (when (eq major-mode 'rcirc-mode)
+  (when (derived-mode-p 'rcirc-mode)
     (when (and rcirc-log-flag
                rcirc-log-directory)
       (rcirc-log-write))
@@ -1337,7 +1342,7 @@ rcirc-get-buffer-create
 	(let ((new-buffer (get-buffer-create
 			   (rcirc-generate-new-buffer-name process target))))
 	  (with-current-buffer new-buffer
-	    (rcirc-mode process target)
+	    (rcirc-initialize process target)
 	    (rcirc-put-nick-channel process (rcirc-nick process) target
 				    rcirc-current-line))
 	  new-buffer)))))
@@ -1486,7 +1491,7 @@ rcirc-any-buffer
     (let ((buffer (window-buffer)))
       (if (and buffer
 	       (with-current-buffer buffer
-		 (and (eq major-mode 'rcirc-mode)
+		 (and (derived-mode-p 'rcirc-mode)
 		      (eq (rcirc-buffer-process) process))))
 	  buffer
 	(process-buffer process)))))
@@ -1750,7 +1755,7 @@ rcirc-print
 	    (let ((window (get-buffer-window)))
 	      (when window
 		(with-selected-window window
-		  (when (eq major-mode 'rcirc-mode)
+		  (when (derived-mode-p 'rcirc-mode)
 		    (when (<= (- (window-height)
 				 (count-screen-lines (window-point)
 						     (window-start))
@@ -2034,7 +2039,8 @@ rcirc-bury-buffers
   "Bury all RCIRC buffers."
   (interactive)
   (dolist (buf (buffer-list))
-    (when (eq 'rcirc-mode (with-current-buffer buf major-mode))
+    (when (provided-mode-derived-p (buffer-local-value buf 'major-mode)
+                                   'rcirc-mode)
       (bury-buffer buf)         ; buffers not shown
       (quit-windows-on buf))))  ; buffers shown in a window
 
@@ -2158,7 +2164,7 @@ rcirc-visible-buffers
   (let (acc)
     (walk-windows (lambda (w)
 		    (with-current-buffer (window-buffer w)
-		      (when (eq major-mode 'rcirc-mode)
+		      (when (derived-mode-p 'rcirc-mode)
 			(push (current-buffer) acc)))))
     acc))
 
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #9: 0008-Replace-rcirc-delete-process-with-delete-process.patch --]
[-- Type: text/x-diff, Size: 988 bytes --]

From 7682fa1e9f9128fe1dcfb9dddb60d476a2daa099 Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Fri, 4 Jun 2021 16:41:10 +0200
Subject: [PATCH 08/11] Replace rcirc-delete-process with delete-process

---
 lisp/net/rcirc.el | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index 92d7b383d8..073dbc118c 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -805,12 +805,9 @@ rcirc-reschedule-timeout
       (with-rcirc-process-buffer process
 	(when rcirc-timeout-timer (cancel-timer rcirc-timeout-timer))
 	(setq rcirc-timeout-timer (run-at-time rcirc-timeout-seconds nil
-					       'rcirc-delete-process
+					       'delete-process
 					       process))))))
 
-(defun rcirc-delete-process (process)
-  (delete-process process))
-
 (defvar rcirc-trap-errors-flag t
   "Non-nil means Lisp errors are degraded to error messages.")
 (defun rcirc-process-server-response (process text)
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #10: 0009-Remove-unused-variable-rcirc-last-sender.patch --]
[-- Type: text/x-diff, Size: 701 bytes --]

From 5704a82a77733dc077043121f3e28fadfc71bbaa Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Fri, 4 Jun 2021 16:41:30 +0200
Subject: [PATCH 09/11] Remove unused variable rcirc-last-sender

---
 lisp/net/rcirc.el | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index 073dbc118c..944df4a1bf 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -1597,7 +1597,6 @@ rcirc-target-buffer
 	  ((or (rcirc-get-buffer process target)
 	       (rcirc-any-buffer process))))))
 
-(defvar-local rcirc-last-sender nil)
 (defvar-local rcirc-activity-types nil
   "List of symbols designating kinds of activities in a buffer.")
 
-- 
2.30.2


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #11: 0010-Call-rcirc-update-activity-string-after-rcirc-next-a.patch --]
[-- Type: text/x-diff, Size: 850 bytes --]

From 1c967de181a14787fa9579c45ac2af9a2400b8eb Mon Sep 17 00:00:00 2001
From: Philip Kaludercic <philipk@posteo.net>
Date: Fri, 4 Jun 2021 16:41:57 +0200
Subject: [PATCH 10/11] Call rcirc-update-activity-string after
 rcirc-next-active-buffer

---
 lisp/net/rcirc.el | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index 944df4a1bf..202d12b892 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -2059,7 +2059,8 @@ rcirc-next-active-buffer
                    (concat
                     "  Type C-u " (key-description (this-command-keys))
                     " for low priority activity.")
-                 "")))))
+                 ""))))
+  (rcirc-update-activity-string))
 
 (define-obsolete-variable-alias 'rcirc-activity-hooks
   'rcirc-activity-functions "24.3")
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2021-09-26  8:20 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-11 16:21 Cleaning up rcirc Philip Kaludercic
2021-09-11 16:49 ` Tassilo Horn
2021-09-11 17:49   ` Philip Kaludercic
2021-09-11 18:32     ` Tassilo Horn
2021-09-11 20:13       ` Philip Kaludercic
2021-09-11 21:01         ` Tassilo Horn
2021-09-13 22:59           ` chad
2021-09-21 18:52           ` Tassilo Horn
2021-09-21 19:18             ` Philip Kaludercic
2021-09-21 19:47               ` Tassilo Horn
2021-09-25 16:34                 ` Philip Kaludercic
2021-09-26  8:20                   ` Tassilo Horn
2021-09-11 17:56 ` Stefan Monnier
2021-09-11 20:16 ` Philip Kaludercic
2021-09-13  8:50 ` Lars Ingebrigtsen
2021-09-13  9:53   ` Stefan Kangas
2021-09-13 10:20     ` Tassilo Horn
2021-09-13 15:00       ` Amin Bandali
  -- strict thread matches above, loose matches on Subject: below --
2021-06-04 15:16 Philip Kaludercic
2021-06-04 16:55 ` Andreas Schwab
2021-06-04 18:09   ` Philip Kaludercic
2021-06-06 18:41     ` Tassilo Horn
2021-06-06 21:09       ` Philip Kaludercic
2021-06-10 15:50       ` Philip Kaludercic
2021-06-10 19:13         ` Tassilo Horn
2021-06-10 21:54           ` Philip Kaludercic
2021-06-11  5:02             ` Tassilo Horn
2021-06-11  6:35               ` Tassilo Horn
2021-06-11  9:08                 ` Philip Kaludercic
2021-06-11  9:27                   ` Tassilo Horn
2021-06-11  9:44                     ` Philip Kaludercic
2021-06-11 11:10                       ` Tassilo Horn
2021-06-11 14:51                         ` Philip Kaludercic
2021-06-11  8:09               ` Philip Kaludercic
2021-06-07  9:55     ` Lars Ingebrigtsen
2021-07-22 22:14       ` Philip Kaludercic
2021-07-22 22:18         ` Lars Ingebrigtsen
2021-06-06 17:53 ` Bone Baboon
2021-06-07 13:08 ` Zhiwei Chen
2021-06-07 13:20   ` Philip Kaludercic

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).