Replace "Maintainer: FSF" with the emacs-devel mailing address
[bpt/emacs.git] / lisp / erc / erc-backend.el
index 75f0047..01fdfc5 100644 (file)
@@ -1,10 +1,10 @@
 ;;; erc-backend.el --- Backend network communication for ERC
 
-;; Copyright (C) 2004-2012 Free Software Foundation, Inc.
+;; Copyright (C) 2004-2014 Free Software Foundation, Inc.
 
 ;; Filename: erc-backend.el
 ;; Author: Lawrence Mitchell <wence@gmx.li>
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
 ;; Created: 2004-05-7
 ;; Keywords: IRC chat client internet
 
 ;;; Code:
 
 (require 'erc-compat)
-(eval-when-compile (require 'cl))
-(autoload 'erc-with-buffer "erc" nil nil 'macro)
-(autoload 'erc-log "erc" nil nil 'macro)
+(eval-when-compile (require 'cl-lib))
+;; There's a fairly strong mutual dependency between erc.el and erc-backend.el.
+;; Luckily, erc.el does not need erc-backend.el for macroexpansion whereas the
+;; reverse is true:
+(provide 'erc-backend)
+(require 'erc)
 
 ;;;; Variables and options
 
 (defvar erc-server-responses (make-hash-table :test #'equal)
   "Hashtable mapping server responses to their handler hooks.")
 
-(defstruct (erc-response (:conc-name erc-response.))
+(cl-defstruct (erc-response (:conc-name erc-response.))
   (unparsed "" :type string)
   (sender "" :type string)
   (command "" :type string)
@@ -494,11 +497,12 @@ The current buffer is given by BUFFER."
                                                     erc-server-ping-handler)
                                               erc-server-ping-timer-alist)))))
 
-(defun erc-server-process-alive ()
-  "Return non-nil when `erc-server-process' is open or running."
-  (and erc-server-process
-       (processp erc-server-process)
-       (memq (process-status erc-server-process) '(run open))))
+(defun erc-server-process-alive (&optional buffer)
+  "Return non-nil when BUFFER has an `erc-server-process' open or running."
+  (with-current-buffer (or buffer (current-buffer))
+    (and erc-server-process
+         (processp erc-server-process)
+         (memq (process-status erc-server-process) '(run open)))))
 
 ;;;; Connecting to a server
 
@@ -948,7 +952,7 @@ PROCs `process-buffer' is `current-buffer' when this function is called."
         (push str (erc-response.command-args msg))))
 
     (setf (erc-response.contents msg)
-          (first (erc-response.command-args msg)))
+          (car (erc-response.command-args msg)))
 
     (setf (erc-response.command-args msg)
           (nreverse (erc-response.command-args msg)))
@@ -1043,7 +1047,7 @@ Finds hooks by looking in the `erc-server-responses' hashtable."
                (name &rest name)
                &optional sexp sexp def-body))
 
-(defmacro* define-erc-response-handler ((name &rest aliases)
+(cl-defmacro define-erc-response-handler ((name &rest aliases)
                                         &optional extra-fn-doc extra-var-doc
                                         &rest fn-body)
   "Define an ERC handler hook/function pair.
@@ -1152,11 +1156,11 @@ add things to `%s' instead."
                            "")
                          name hook-name))
          (fn-alternates
-          (loop for alias in aliases
-                collect (intern (format "erc-server-%s" alias))))
+          (cl-loop for alias in aliases
+                   collect (intern (format "erc-server-%s" alias))))
          (var-alternates
-          (loop for alias in aliases
-                collect (intern (format "erc-server-%s-functions" alias)))))
+          (cl-loop for alias in aliases
+                   collect (intern (format "erc-server-%s-functions" alias)))))
     `(prog2
          ;; Normal hook variable.
          (defvar ,hook-name ',fn-name ,(format hook-doc name))
@@ -1170,19 +1174,19 @@ add things to `%s' instead."
        (put ',hook-name 'definition-name ',name)
 
        ;; Hashtable map of responses to hook variables
-       ,@(loop for response in (cons name aliases)
-               for var in (cons hook-name var-alternates)
-               collect `(puthash ,(format "%s" response) ',var
-                                 erc-server-responses))
+       ,@(cl-loop for response in (cons name aliases)
+                  for var in (cons hook-name var-alternates)
+                  collect `(puthash ,(format "%s" response) ',var
+                                    erc-server-responses))
        ;; Alternates.
        ;; Functions are defaliased, hook variables are defvared so we
        ;; can add hooks to one alias, but not another.
-       ,@(loop for fn in fn-alternates
-               for var in var-alternates
-               for a in aliases
-               nconc (list `(defalias ',fn ',fn-name)
-                           `(defvar ,var ',fn-name ,(format hook-doc a))
-                           `(put ',var 'definition-name ',hook-name))))))
+       ,@(cl-loop for fn in fn-alternates
+                  for var in var-alternates
+                  for a in aliases
+                  nconc (list `(defalias ',fn ',fn-name)
+                              `(defvar ,var ',fn-name ,(format hook-doc a))
+                              `(put ',var 'definition-name ',hook-name))))))
 
 (define-erc-response-handler (ERROR)
   "Handle an ERROR command from the server." nil
@@ -1194,10 +1198,10 @@ add things to `%s' instead."
 (define-erc-response-handler (INVITE)
   "Handle invitation messages."
   nil
-  (let ((target (first (erc-response.command-args parsed)))
+  (let ((target (car (erc-response.command-args parsed)))
         (chnl (erc-response.contents parsed)))
-    (multiple-value-bind (nick login host)
-        (values-list (erc-parse-user (erc-response.sender parsed)))
+    (pcase-let ((`(,nick ,login ,host)
+                 (erc-parse-user (erc-response.sender parsed))))
       (setq erc-invitation chnl)
       (when (string= target (erc-current-nick))
         (erc-display-message
@@ -1210,8 +1214,8 @@ add things to `%s' instead."
   nil
   (let ((chnl (erc-response.contents parsed))
         (buffer nil))
-    (multiple-value-bind (nick login host)
-        (values-list (erc-parse-user (erc-response.sender parsed)))
+    (pcase-let ((`(,nick ,login ,host)
+                 (erc-parse-user (erc-response.sender parsed))))
       ;; strip the stupid combined JOIN facility (IRC 2.9)
       (if (string-match "^\\(.*\\)?\^g.*$" chnl)
           (setq chnl (match-string 1 chnl)))
@@ -1247,12 +1251,12 @@ add things to `%s' instead."
 
 (define-erc-response-handler (KICK)
   "Handle kick messages received from the server." nil
-  (let* ((ch (first (erc-response.command-args parsed)))
-         (tgt (second (erc-response.command-args parsed)))
+  (let* ((ch (nth 0 (erc-response.command-args parsed)))
+         (tgt (nth 1 (erc-response.command-args parsed)))
          (reason (erc-trim-string (erc-response.contents parsed)))
          (buffer (erc-get-buffer ch proc)))
-    (multiple-value-bind (nick login host)
-        (values-list (erc-parse-user (erc-response.sender parsed)))
+    (pcase-let ((`(,nick ,login ,host)
+                 (erc-parse-user (erc-response.sender parsed))))
       (erc-remove-channel-member buffer tgt)
       (cond
        ((string= tgt (erc-current-nick))
@@ -1275,11 +1279,11 @@ add things to `%s' instead."
 
 (define-erc-response-handler (MODE)
   "Handle server mode changes." nil
-  (let ((tgt (first (erc-response.command-args parsed)))
+  (let ((tgt (car (erc-response.command-args parsed)))
         (mode (mapconcat 'identity (cdr (erc-response.command-args parsed))
                          " ")))
-    (multiple-value-bind (nick login host)
-        (values-list (erc-parse-user (erc-response.sender parsed)))
+    (pcase-let ((`(,nick ,login ,host)
+                 (erc-parse-user (erc-response.sender parsed))))
       (erc-log (format "MODE: %s -> %s: %s" nick tgt mode))
       ;; dirty hack
       (let ((buf (cond ((erc-channel-p tgt)
@@ -1303,8 +1307,8 @@ add things to `%s' instead."
   "Handle nick change messages." nil
   (let ((nn (erc-response.contents parsed))
         bufs)
-    (multiple-value-bind (nick login host)
-        (values-list (erc-parse-user (erc-response.sender parsed)))
+    (pcase-let ((`(,nick ,login ,host)
+                 (erc-parse-user (erc-response.sender parsed))))
       (setq bufs (erc-buffer-list-with-nick nick proc))
       (erc-log (format "NICK: %s -> %s" nick nn))
       ;; if we had a query with this user, make sure future messages will be
@@ -1316,7 +1320,7 @@ add things to `%s' instead."
          (when (equal (erc-default-target) nick)
            (setq erc-default-recipients
                  (cons nn (cdr erc-default-recipients)))
-           (rename-buffer nn)
+           (rename-buffer nn t)         ; bug#12002
            (erc-update-mode-line)
            (add-to-list 'bufs (current-buffer)))))
       (erc-update-user-nick nick nn host nil nil login)
@@ -1338,11 +1342,11 @@ add things to `%s' instead."
 
 (define-erc-response-handler (PART)
   "Handle part messages." nil
-  (let* ((chnl (first (erc-response.command-args parsed)))
+  (let* ((chnl (car (erc-response.command-args parsed)))
          (reason (erc-trim-string (erc-response.contents parsed)))
          (buffer (erc-get-buffer chnl proc)))
-    (multiple-value-bind (nick login host)
-        (values-list (erc-parse-user (erc-response.sender parsed)))
+    (pcase-let ((`(,nick ,login ,host)
+                 (erc-parse-user (erc-response.sender parsed))))
       (erc-remove-channel-member buffer nick)
       (erc-display-message parsed 'notice buffer
                            'PART ?n nick ?u login
@@ -1359,7 +1363,7 @@ add things to `%s' instead."
 
 (define-erc-response-handler (PING)
   "Handle ping messages." nil
-  (let ((pinger (first (erc-response.command-args parsed))))
+  (let ((pinger (car (erc-response.command-args parsed))))
     (erc-log (format "PING: %s" pinger))
     ;; ping response to the server MUST be forced, or you can lose big
     (erc-server-send (format "PONG :%s" pinger) t)
@@ -1377,7 +1381,7 @@ add things to `%s' instead."
       (when erc-verbose-server-ping
         (erc-display-message
          parsed 'notice proc 'PONG
-         ?h (first (erc-response.command-args parsed)) ?i erc-server-lag
+         ?h (car (erc-response.command-args parsed)) ?i erc-server-lag
          ?s (if (/= erc-server-lag 1) "s" "")))
       (erc-update-mode-line))))
 
@@ -1449,8 +1453,8 @@ add things to `%s' instead."
   "Another user has quit IRC." nil
   (let ((reason (erc-response.contents parsed))
         bufs)
-    (multiple-value-bind (nick login host)
-        (values-list (erc-parse-user (erc-response.sender parsed)))
+    (pcase-let ((`(,nick ,login ,host)
+                 (erc-parse-user (erc-response.sender parsed))))
       (setq bufs (erc-buffer-list-with-nick nick proc))
       (erc-remove-user nick)
       (setq reason (erc-wash-quit-reason reason nick login host))
@@ -1460,12 +1464,12 @@ add things to `%s' instead."
 
 (define-erc-response-handler (TOPIC)
   "The channel topic has changed." nil
-  (let* ((ch (first (erc-response.command-args parsed)))
+  (let* ((ch (car (erc-response.command-args parsed)))
          (topic (erc-trim-string (erc-response.contents parsed)))
          (time (format-time-string erc-server-timestamp-format
                                    (current-time))))
-    (multiple-value-bind (nick login host)
-        (values-list (erc-parse-user (erc-response.sender parsed)))
+    (pcase-let ((`(,nick ,login ,host)
+                 (erc-parse-user (erc-response.sender parsed))))
       (erc-update-channel-member ch nick nick nil nil nil host login)
       (erc-update-channel-topic ch (format "%s\C-o (%s, %s)" topic nick time))
       (erc-display-message parsed 'notice (erc-get-buffer ch proc)
@@ -1475,8 +1479,8 @@ add things to `%s' instead."
 (define-erc-response-handler (WALLOPS)
   "Display a WALLOPS message." nil
   (let ((message (erc-response.contents parsed)))
-    (multiple-value-bind (nick login host)
-        (values-list (erc-parse-user (erc-response.sender parsed)))
+    (pcase-let ((`(,nick ,login ,host)
+                 (erc-parse-user (erc-response.sender parsed))))
       (erc-display-message
        parsed 'notice nil
        'WALLOPS ?n nick ?m message))))
@@ -1484,7 +1488,7 @@ add things to `%s' instead."
 (define-erc-response-handler (001)
   "Set `erc-server-current-nick' to reflect server settings and display the welcome message."
   nil
-  (erc-set-current-nick (first (erc-response.command-args parsed)))
+  (erc-set-current-nick (car (erc-response.command-args parsed)))
   (erc-update-mode-line)                ; needed here?
   (setq erc-nick-change-attempt-count 0)
   (setq erc-default-nicks (if (consp erc-nick) erc-nick (list erc-nick)))
@@ -1505,16 +1509,16 @@ add things to `%s' instead."
 
 (define-erc-response-handler (004)
   "Display the server's identification." nil
-  (multiple-value-bind (server-name server-version)
-      (values-list (cdr (erc-response.command-args parsed)))
+  (pcase-let ((`(,server-name ,server-version)
+               (cdr (erc-response.command-args parsed))))
     (setq erc-server-version server-version)
     (setq erc-server-announced-name server-name)
     (erc-update-mode-line-buffer (process-buffer proc))
     (erc-display-message
      parsed 'notice proc
      's004 ?s server-name ?v server-version
-     ?U (fourth (erc-response.command-args parsed))
-     ?C (fifth (erc-response.command-args parsed)))))
+     ?U (nth 3 (erc-response.command-args parsed))
+     ?C (nth 4 (erc-response.command-args parsed)))))
 
 (define-erc-response-handler (005)
   "Set the variable `erc-server-parameters' and display the received message.
@@ -1545,7 +1549,7 @@ A server may send more than one 005 message."
 
 (define-erc-response-handler (221)
   "Display the current user modes." nil
-  (let* ((nick (first (erc-response.command-args parsed)))
+  (let* ((nick (car (erc-response.command-args parsed)))
          (modes (mapconcat 'identity
                            (cdr (erc-response.command-args parsed)) " ")))
     (erc-set-modes nick modes)
@@ -1554,17 +1558,17 @@ A server may send more than one 005 message."
 (define-erc-response-handler (252)
   "Display the number of IRC operators online." nil
   (erc-display-message parsed 'notice 'active 's252
-                       ?i (second (erc-response.command-args parsed))))
+                       ?i (cadr (erc-response.command-args parsed))))
 
 (define-erc-response-handler (253)
   "Display the number of unknown connections." nil
   (erc-display-message parsed 'notice 'active 's253
-                       ?i (second (erc-response.command-args parsed))))
+                       ?i (cadr (erc-response.command-args parsed))))
 
 (define-erc-response-handler (254)
   "Display the number of channels formed." nil
   (erc-display-message parsed 'notice 'active 's254
-                       ?i (second (erc-response.command-args parsed))))
+                       ?i (cadr (erc-response.command-args parsed))))
 
 (define-erc-response-handler (250 251 255 256 257 258 259 265 266 377 378)
   "Generic display of server messages as notices.
@@ -1574,8 +1578,8 @@ See `erc-display-server-message'." nil
 
 (define-erc-response-handler (275)
   "Display secure connection message." nil
-  (multiple-value-bind (nick user message)
-      (values-list (cdr (erc-response.command-args parsed)))
+  (pcase-let ((`(,nick ,user ,message)
+               (cdr (erc-response.command-args parsed))))
     (erc-display-message
      parsed 'notice 'active 's275
      ?n nick
@@ -1588,13 +1592,13 @@ See `erc-display-server-message'." nil
 (define-erc-response-handler (301)
   "AWAY notice." nil
   (erc-display-message parsed 'notice 'active 's301
-                       ?n (second (erc-response.command-args parsed))
+                       ?n (cadr (erc-response.command-args parsed))
                        ?r (erc-response.contents parsed)))
 
 (define-erc-response-handler (303)
   "ISON reply" nil
   (erc-display-message parsed 'notice 'active 's303
-                       ?n (second (erc-response.command-args parsed))))
+                       ?n (cadr (erc-response.command-args parsed))))
 
 (define-erc-response-handler (305)
   "Return from AWAYness." nil
@@ -1610,8 +1614,8 @@ See `erc-display-server-message'." nil
 
 (define-erc-response-handler (307)
   "Display nick-identified message." nil
-  (multiple-value-bind (nick user message)
-      (values-list (cdr (erc-response.command-args parsed)))
+  (pcase-let ((`(,nick ,user ,message)
+               (cdr (erc-response.command-args parsed))))
     (erc-display-message
      parsed 'notice 'active 's307
      ?n nick
@@ -1622,8 +1626,8 @@ See `erc-display-server-message'." nil
   "WHOIS/WHOWAS notices." nil
   (let ((fname (erc-response.contents parsed))
         (catalog-entry (intern (format "s%s" (erc-response.command parsed)))))
-    (multiple-value-bind (nick user host)
-        (values-list (cdr (erc-response.command-args parsed)))
+    (pcase-let ((`(,nick ,user ,host)
+                 (cdr (erc-response.command-args parsed))))
       (erc-update-user-nick nick nick host nil fname user)
       (erc-display-message
        parsed 'notice 'active catalog-entry
@@ -1631,8 +1635,8 @@ See `erc-display-server-message'." nil
 
 (define-erc-response-handler (312)
   "Server name response in WHOIS." nil
-  (multiple-value-bind (nick server-host)
-      (values-list (cdr (erc-response.command-args parsed)))
+  (pcase-let ((`(,nick ,server-host)
+              (cdr (erc-response.command-args parsed))))
     (erc-display-message
      parsed 'notice 'active 's312
      ?n nick ?s server-host ?c (erc-response.contents parsed))))
@@ -1641,7 +1645,7 @@ See `erc-display-server-message'." nil
   "IRC Operator response in WHOIS." nil
   (erc-display-message
    parsed 'notice 'active 's313
-   ?n (second (erc-response.command-args parsed))))
+   ?n (cadr (erc-response.command-args parsed))))
 
 (define-erc-response-handler (315 318 323 369)
   ;; 315 - End of WHO
@@ -1653,8 +1657,8 @@ See `erc-display-server-message'." nil
 
 (define-erc-response-handler (317)
   "IDLE notice." nil
-  (multiple-value-bind (nick seconds-idle on-since time)
-      (values-list (cdr (erc-response.command-args parsed)))
+  (pcase-let ((`(,nick ,seconds-idle ,on-since ,time)
+               (cdr (erc-response.command-args parsed))))
     (setq time (when on-since
                  (format-time-string erc-server-timestamp-format
                                      (erc-string-to-emacs-time on-since))))
@@ -1672,14 +1676,14 @@ See `erc-display-server-message'." nil
   "Channel names in WHOIS response." nil
   (erc-display-message
    parsed 'notice 'active 's319
-   ?n (second (erc-response.command-args parsed))
+   ?n (cadr (erc-response.command-args parsed))
    ?c (erc-response.contents parsed)))
 
 (define-erc-response-handler (320)
   "Identified user in WHOIS." nil
   (erc-display-message
    parsed 'notice 'active 's320
-   ?n (second (erc-response.command-args parsed))))
+   ?n (cadr (erc-response.command-args parsed))))
 
 (define-erc-response-handler (321)
   "LIST header." nil
@@ -1694,16 +1698,16 @@ See `erc-display-server-message'." nil
 (define-erc-response-handler (322)
   "LIST notice." nil
   (let ((topic (erc-response.contents parsed)))
-    (multiple-value-bind (channel num-users)
-        (values-list (cdr (erc-response.command-args parsed)))
+    (pcase-let ((`(,channel ,num-users)
+                 (cdr (erc-response.command-args parsed))))
       (add-to-list 'erc-channel-list (list channel))
       (erc-update-channel-topic channel topic))))
 
 (defun erc-server-322-message (proc parsed)
   "Display a message for the 322 event."
   (let ((topic (erc-response.contents parsed)))
-    (multiple-value-bind (channel num-users)
-        (values-list (cdr (erc-response.command-args parsed)))
+    (pcase-let ((`(,channel ,num-users)
+                 (cdr (erc-response.command-args parsed))))
       (erc-display-message
        parsed 'notice proc 's322
        ?c channel ?u num-users ?t (or topic "")))))
@@ -1711,7 +1715,7 @@ See `erc-display-server-message'." nil
 
 (define-erc-response-handler (324)
   "Channel or nick modes." nil
-  (let ((channel (second (erc-response.command-args parsed)))
+  (let ((channel (cadr (erc-response.command-args parsed)))
         (modes (mapconcat 'identity (cddr (erc-response.command-args parsed))
                           " ")))
     (erc-set-modes channel modes)
@@ -1721,16 +1725,16 @@ See `erc-display-server-message'." nil
 
 (define-erc-response-handler (328)
   "Channel URL (on freenode network)." nil
-  (let ((channel (second (erc-response.command-args parsed)))
+  (let ((channel (cadr (erc-response.command-args parsed)))
         (url (erc-response.contents parsed)))
     (erc-display-message parsed 'notice (erc-get-buffer channel proc)
                          's328 ?c channel ?u url)))
 
 (define-erc-response-handler (329)
   "Channel creation date." nil
-  (let ((channel (second (erc-response.command-args parsed)))
+  (let ((channel (cadr (erc-response.command-args parsed)))
         (time (erc-string-to-emacs-time
-               (third (erc-response.command-args parsed)))))
+               (nth 2 (erc-response.command-args parsed)))))
     (erc-display-message
      parsed 'notice (erc-get-buffer channel proc)
      's329 ?c channel ?t (format-time-string erc-server-timestamp-format
@@ -1746,22 +1750,22 @@ See `erc-display-server-message'." nil
   ;; authaccount == (aref parsed 4)
   ;; authmsg == (aref parsed 5)
   ;; The guesses below are, well, just that. -- Lawrence 2004/05/10
-  (let ((nick (second (erc-response.command-args parsed)))
-        (authaccount (third (erc-response.command-args parsed)))
+  (let ((nick (cadr (erc-response.command-args parsed)))
+        (authaccount (nth 2 (erc-response.command-args parsed)))
         (authmsg (erc-response.contents parsed)))
     (erc-display-message parsed 'notice 'active 's330
                          ?n nick ?a authmsg ?i authaccount)))
 
 (define-erc-response-handler (331)
   "No topic set for channel." nil
-  (let ((channel (second (erc-response.command-args parsed)))
+  (let ((channel (cadr (erc-response.command-args parsed)))
         (topic (erc-response.contents parsed)))
     (erc-display-message parsed 'notice (erc-get-buffer channel proc)
                          's331 ?c channel)))
 
 (define-erc-response-handler (332)
   "TOPIC notice." nil
-  (let ((channel (second (erc-response.command-args parsed)))
+  (let ((channel (cadr (erc-response.command-args parsed)))
         (topic (erc-response.contents parsed)))
     (erc-update-channel-topic channel topic)
     (erc-display-message parsed 'notice (erc-get-buffer channel proc)
@@ -1769,8 +1773,8 @@ See `erc-display-server-message'." nil
 
 (define-erc-response-handler (333)
   "Who set the topic, and when." nil
-  (multiple-value-bind (channel nick time)
-      (values-list (cdr (erc-response.command-args parsed)))
+  (pcase-let ((`(,channel ,nick ,time)
+               (cdr (erc-response.command-args parsed))))
     (setq time (format-time-string erc-server-timestamp-format
                                    (erc-string-to-emacs-time time)))
     (erc-update-channel-topic channel
@@ -1782,15 +1786,15 @@ See `erc-display-server-message'." nil
 (define-erc-response-handler (341)
   "Let user know when an INVITE attempt has been sent successfully."
   nil
-  (multiple-value-bind (nick channel)
-      (values-list (cdr (erc-response.command-args parsed)))
+  (pcase-let ((`(,nick ,channel)
+               (cdr (erc-response.command-args parsed))))
     (erc-display-message parsed 'notice (erc-get-buffer channel proc)
                          's341 ?n nick ?c channel)))
 
 (define-erc-response-handler (352)
   "WHO notice." nil
-  (multiple-value-bind (channel user host server nick away-flag)
-      (values-list (cdr (erc-response.command-args parsed)))
+  (pcase-let ((`(,channel ,user ,host ,server ,nick ,away-flag)
+               (cdr (erc-response.command-args parsed))))
     (let ((full-name (erc-response.contents parsed))
           hopcount)
       (when (string-match "\\(^[0-9]+ \\)\\(.*\\)$" full-name)
@@ -1804,7 +1808,7 @@ See `erc-display-server-message'." nil
 
 (define-erc-response-handler (353)
   "NAMES notice." nil
-  (let ((channel (third (erc-response.command-args parsed)))
+  (let ((channel (nth 2 (erc-response.command-args parsed)))
         (users (erc-response.contents parsed)))
     (erc-display-message parsed 'notice (or (erc-get-buffer channel proc)
                                             'active)
@@ -1814,13 +1818,13 @@ See `erc-display-server-message'." nil
 
 (define-erc-response-handler (366)
   "End of NAMES." nil
-  (erc-with-buffer ((second (erc-response.command-args parsed)) proc)
+  (erc-with-buffer ((cadr (erc-response.command-args parsed)) proc)
     (erc-channel-end-receiving-names)))
 
 (define-erc-response-handler (367)
   "Channel ban list entries." nil
-  (multiple-value-bind (channel banmask setter time)
-      (values-list (cdr (erc-response.command-args parsed)))
+  (pcase-let ((`(,channel ,banmask ,setter ,time)
+               (cdr (erc-response.command-args parsed))))
     ;; setter and time are not standard
     (if setter
         (erc-display-message parsed 'notice 'active 's367-set-by
@@ -1834,7 +1838,7 @@ See `erc-display-server-message'." nil
 
 (define-erc-response-handler (368)
   "End of channel ban list." nil
-  (let ((channel (second (erc-response.command-args parsed))))
+  (let ((channel (cadr (erc-response.command-args parsed))))
     (erc-display-message parsed 'notice 'active 's368
                          ?c channel)))
 
@@ -1843,8 +1847,8 @@ See `erc-display-server-message'." nil
   ;; FIXME: Yet more magic numbers in original code, I'm guessing this
   ;; command takes two arguments, and doesn't have any "contents". --
   ;; Lawrence 2004/05/10
-  (multiple-value-bind (from to)
-      (values-list (cdr (erc-response.command-args parsed)))
+  (pcase-let ((`(,from ,to)
+               (cdr (erc-response.command-args parsed))))
     (erc-display-message parsed 'notice 'active
                          's379 ?c from ?f to)))
 
@@ -1852,12 +1856,12 @@ See `erc-display-server-message'." nil
   "Server's time string." nil
   (erc-display-message
    parsed 'notice 'active
-   's391 ?s (second (erc-response.command-args parsed))
-   ?t (third (erc-response.command-args parsed))))
+   's391 ?s (cadr (erc-response.command-args parsed))
+   ?t (nth 2 (erc-response.command-args parsed))))
 
 (define-erc-response-handler (401)
   "No such nick/channel." nil
-  (let ((nick/channel (second (erc-response.command-args parsed))))
+  (let ((nick/channel (cadr (erc-response.command-args parsed))))
     (when erc-whowas-on-nosuchnick
       (erc-log (format "cmd: WHOWAS: %s" nick/channel))
       (erc-server-send (format "WHOWAS %s 1" nick/channel)))
@@ -1867,23 +1871,23 @@ See `erc-display-server-message'." nil
 (define-erc-response-handler (403)
   "No such channel." nil
   (erc-display-message parsed '(notice error) 'active
-                       's403 ?c (second (erc-response.command-args parsed))))
+                       's403 ?c (cadr (erc-response.command-args parsed))))
 
 (define-erc-response-handler (404)
   "Cannot send to channel." nil
   (erc-display-message parsed '(notice error) 'active
-                       's404 ?c (second (erc-response.command-args parsed))))
+                       's404 ?c (cadr (erc-response.command-args parsed))))
 
 
 (define-erc-response-handler (405)
   "Can't join that many channels." nil
   (erc-display-message parsed '(notice error) 'active
-                       's405 ?c (second (erc-response.command-args parsed))))
+                       's405 ?c (cadr (erc-response.command-args parsed))))
 
 (define-erc-response-handler (406)
   "No such nick." nil
   (erc-display-message parsed '(notice error) 'active
-                       's406 ?n (second (erc-response.command-args parsed))))
+                       's406 ?n (cadr (erc-response.command-args parsed))))
 
 (define-erc-response-handler (412)
   "No text to send." nil
@@ -1892,33 +1896,33 @@ See `erc-display-server-message'." nil
 (define-erc-response-handler (421)
   "Unknown command." nil
   (erc-display-message parsed '(notice error) 'active 's421
-                       ?c (second (erc-response.command-args parsed))))
+                       ?c (cadr (erc-response.command-args parsed))))
 
 (define-erc-response-handler (432)
   "Bad nick." nil
   (erc-display-message parsed '(notice error) 'active 's432
-                       ?n (second (erc-response.command-args parsed))))
+                       ?n (cadr (erc-response.command-args parsed))))
 
 (define-erc-response-handler (433)
   "Login-time \"nick in use\"." nil
-  (erc-nickname-in-use (second (erc-response.command-args parsed))
+  (erc-nickname-in-use (cadr (erc-response.command-args parsed))
                        "already in use"))
 
 (define-erc-response-handler (437)
   "Nick temporarily unavailable (on IRCnet)." nil
-  (let ((nick/channel (second (erc-response.command-args parsed))))
+  (let ((nick/channel (cadr (erc-response.command-args parsed))))
     (unless (erc-channel-p nick/channel)
       (erc-nickname-in-use nick/channel "temporarily unavailable"))))
 
 (define-erc-response-handler (442)
   "Not on channel." nil
   (erc-display-message parsed '(notice error) 'active 's442
-                       ?c (second (erc-response.command-args parsed))))
+                       ?c (cadr (erc-response.command-args parsed))))
 
 (define-erc-response-handler (461)
   "Not enough parameters for command." nil
   (erc-display-message parsed '(notice error)  'active 's461
-                       ?c (second (erc-response.command-args parsed))
+                       ?c (cadr (erc-response.command-args parsed))
                        ?m (erc-response.contents parsed)))
 
 (define-erc-response-handler (465)
@@ -1934,37 +1938,37 @@ See `erc-display-server-message'." nil
   (erc-display-message parsed '(notice error) nil
                        (intern (format "s%s"
                                        (erc-response.command parsed)))
-                       ?c (second (erc-response.command-args parsed))))
+                       ?c (cadr (erc-response.command-args parsed))))
 
 (define-erc-response-handler (475)
   "Channel key needed." nil
   (erc-display-message parsed '(notice error) nil 's475
-                       ?c (second (erc-response.command-args parsed)))
+                       ?c (cadr (erc-response.command-args parsed)))
   (when erc-prompt-for-channel-key
-    (let ((channel (second (erc-response.command-args parsed)))
+    (let ((channel (cadr (erc-response.command-args parsed)))
           (key (read-from-minibuffer
                 (format "Channel %s is mode +k.  Enter key (RET to cancel): "
-                        (second (erc-response.command-args parsed))))))
+                        (cadr (erc-response.command-args parsed))))))
       (when (and key (> (length key) 0))
           (erc-cmd-JOIN channel key)))))
 
 (define-erc-response-handler (477)
   "Channel doesn't support modes." nil
-  (let ((channel (second (erc-response.command-args parsed)))
+  (let ((channel (cadr (erc-response.command-args parsed)))
         (message (erc-response.contents parsed)))
     (erc-display-message parsed 'notice (erc-get-buffer channel proc)
                          (format "%s: %s" channel message))))
 
 (define-erc-response-handler (482)
   "You need to be a channel operator to do that." nil
-  (let ((channel (second (erc-response.command-args parsed)))
+  (let ((channel (cadr (erc-response.command-args parsed)))
         (message (erc-response.contents parsed)))
     (erc-display-message parsed '(error notice) 'active 's482
                          ?c channel ?m message)))
 
 (define-erc-response-handler (671)
   "Secure connection response in WHOIS." nil
-  (let ((nick (second (erc-response.command-args parsed)))
+  (let ((nick (cadr (erc-response.command-args parsed)))
         (securemsg (erc-response.contents parsed)))
     (erc-display-message parsed 'notice 'active 's671
                          ?n nick ?a securemsg)))