Function: define-erc-response-handler

define-erc-response-handler is a macro defined in erc-backend.el.gz.

Signature

(define-erc-response-handler (NAME &rest ALIASES) &optional EXTRA-FN-DOC EXTRA-VAR-DOC &rest FN-BODY)

Documentation

Define an ERC handler hook/function pair.

NAME is the response name as sent by the server (see the IRC RFC for meanings).

This creates:
 - a hook variable erc-server-NAME-functions initialized to
   erc-server-NAME.
 - a function erc-server-NAME with body FN-BODY.

If ALIASES is non-nil, each alias in ALIASES is defaliased to erc-server-NAME. Alias hook variables are created as erc-server-ALIAS-functions and initialized to the same default value as erc-server-NAME-functions.

FN-BODY is the body of erc-server-NAME it may refer to the two function arguments PROC and PARSED.

If EXTRA-FN-DOC is non-nil, it is inserted at the beginning of the defined function's docstring.

If EXTRA-VAR-DOC is non-nil, it is inserted at the beginning of the defined variable's docstring.

As an example:

  (define-erc-response-handler (311 WHOIS WI)
    "Some non-generic function documentation."
    "Some non-generic variable documentation."
    (do-stuff-with-whois proc parsed))

Would expand to:

  (prog2
      (defvar erc-server-311-functions 'erc-server-311
        "Some non-generic variable documentation.

  Hook called upon receiving a 311 server response.
  Each function is called with two arguments, the process associated
  with the response and the parsed response.
  See also `erc-server-311'.")

      (defun erc-server-311 (proc parsed)
        "Some non-generic function documentation.

  Handler for a 311 server response.
  PROC is the server process which returned the response.
  PARSED is the actual response as an `erc-response' struct.
  If you want to add responses don't modify this function, but rather
  add things to `erc-server-311-functions' instead."
        (do-stuff-with-whois proc parsed))

    (puthash "311" 'erc-server-311-functions erc-server-responses)
    (puthash "WHOIS" 'erc-server-WHOIS-functions erc-server-responses)
    (puthash "WI" 'erc-server-WI-functions erc-server-responses)

    (defalias 'erc-server-WHOIS 'erc-server-311)
    (defvar erc-server-WHOIS-functions 'erc-server-311
      "Some non-generic variable documentation.

  Hook called upon receiving a WHOIS server response.

  Each function is called with two arguments, the process associated
  with the response and the parsed response. If the function returns
  non-nil, stop processing the hook. Otherwise, continue.

  See also `erc-server-311'.")

    (defalias 'erc-server-WI 'erc-server-311)
    (defvar erc-server-WI-functions 'erc-server-311
      "Some non-generic variable documentation.

  Hook called upon receiving a WI server response.
  Each function is called with two arguments, the process associated
  with the response and the parsed response. If the function returns
  non-nil, stop processing the hook. Otherwise, continue.

  See also `erc-server-311'."))

Source Code

;; Defined in /usr/src/emacs/lisp/erc/erc-backend.el.gz
(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.
NAME is the response name as sent by the server (see the IRC RFC for
meanings).

This creates:
 - a hook variable `erc-server-NAME-functions' initialized to
   `erc-server-NAME'.
 - a function `erc-server-NAME' with body FN-BODY.

If ALIASES is non-nil, each alias in ALIASES is `defalias'ed to
`erc-server-NAME'.
Alias hook variables are created as `erc-server-ALIAS-functions' and
initialized to the same default value as `erc-server-NAME-functions'.

FN-BODY is the body of `erc-server-NAME' it may refer to the two
function arguments PROC and PARSED.

If EXTRA-FN-DOC is non-nil, it is inserted at the beginning of the
defined function's docstring.

If EXTRA-VAR-DOC is non-nil, it is inserted at the beginning of the
defined variable's docstring.

As an example:

  (define-erc-response-handler (311 WHOIS WI)
    \"Some non-generic function documentation.\"
    \"Some non-generic variable documentation.\"
    (do-stuff-with-whois proc parsed))

Would expand to:

  (prog2
      (defvar erc-server-311-functions \\='erc-server-311
        \"Some non-generic variable documentation.

  Hook called upon receiving a 311 server response.
  Each function is called with two arguments, the process associated
  with the response and the parsed response.
  See also `erc-server-311'.\")

      (defun erc-server-311 (proc parsed)
        \"Some non-generic function documentation.

  Handler for a 311 server response.
  PROC is the server process which returned the response.
  PARSED is the actual response as an `erc-response' struct.
  If you want to add responses don't modify this function, but rather
  add things to `erc-server-311-functions' instead.\"
        (do-stuff-with-whois proc parsed))

    (puthash \"311\" \\='erc-server-311-functions erc-server-responses)
    (puthash \"WHOIS\" \\='erc-server-WHOIS-functions erc-server-responses)
    (puthash \"WI\" \\='erc-server-WI-functions erc-server-responses)

    (defalias \\='erc-server-WHOIS \\='erc-server-311)
    (defvar erc-server-WHOIS-functions \\='erc-server-311
      \"Some non-generic variable documentation.

  Hook called upon receiving a WHOIS server response.

  Each function is called with two arguments, the process associated
  with the response and the parsed response.  If the function returns
  non-nil, stop processing the hook.  Otherwise, continue.

  See also `erc-server-311'.\")

    (defalias \\='erc-server-WI \\='erc-server-311)
    (defvar erc-server-WI-functions \\='erc-server-311
      \"Some non-generic variable documentation.

  Hook called upon receiving a WI server response.
  Each function is called with two arguments, the process associated
  with the response and the parsed response.  If the function returns
  non-nil, stop processing the hook.  Otherwise, continue.

  See also `erc-server-311'.\"))

\(fn (NAME &rest ALIASES) &optional EXTRA-FN-DOC EXTRA-VAR-DOC &rest FN-BODY)"
  (declare (debug (&define [&name "erc-response-handler@"
                                  (symbolp &rest symbolp)]
                           &optional sexp sexp def-body))
           (indent defun))
  (if (numberp name) (setq name (intern (format "%03i" name))))
  (setq aliases (mapcar (lambda (a)
                          (if (numberp a)
                              (format "%03i" a)
                            a))
                        aliases))
  (let* ((hook-name (intern (format "erc-server-%s-functions" name)))
         (fn-name (intern (format "erc-server-%s" name)))
         (hook-doc (format "\
%sHook called upon receiving a %%s server response.
Each function is called with two arguments, the process associated
with the response and the parsed response.  If the function returns
non-nil, stop processing the hook.  Otherwise, continue.

See also `%s'."
                           (if extra-var-doc
                               (concat extra-var-doc "\n\n")
                             "")
                           fn-name))
         (fn-doc (format "\
%sHandler for a %s server response.
PROC is the server process which returned the response.
PARSED is the actual response as an `erc-response' struct.
If you want to add responses don't modify this function, but rather
add things to `%s' instead."
                         (if extra-fn-doc
                             (concat extra-fn-doc "\n\n")
                           "")
                         name hook-name))
         (fn-alternates
          (cl-loop for alias in aliases
                   collect (intern (format "erc-server-%s" alias))))
         (var-alternates
          (cl-loop for alias in aliases
                   collect (intern (format "erc-server-%s-functions" alias)))))
    `(prog2
         ;; Normal hook variable.  The variable may already have a
         ;; value at this point, so I default to nil, and (add-hook)
         ;; unconditionally
         (defvar ,hook-name nil ,(format hook-doc name))
         (add-hook ',hook-name #',fn-name)
         ;; Handler function
         (defun ,fn-name (proc parsed)
           ,fn-doc
           (ignore proc parsed)
           ,@fn-body)

       ;; Make find-function and find-variable find them
       (put ',fn-name 'definition-name ',name)
       (put ',hook-name 'definition-name ',name)

       ;; Hash table map of responses to hook variables
       ,@(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.
       ,@(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))))))