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.
(Note that here, NAME merely refers to the parameter NAME rather than
an actual IRC response or server-sent command.)
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.
ERC uses FN-BODY as the body of the default response handler
erc-server-NAME, which handles all incoming IRC "NAME" responses,
unless overridden (see below). ERC calls the function with two
arguments, PROC and PARSED, whose symbols (lowercase) are bound to the
current erc-server-process and erc-response instance within FN-BODY.
Implementers should take care not to shadow them inadvertently. In all
cases, FN-BODY should return nil to allow third parties to run code
after erc-server-NAME returns. For historical reasons, ERC does not
currently enforce this, however future versions very well may.
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'."))
Note that while all ALIASES share the same handler function, each gets
its own distinct hook variable. The default value of these variables
may be a list or a function. Robust code should handle both.
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.
\(Note that here, NAME merely refers to the parameter NAME rather than
an actual IRC response or server-sent command.)
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'.
ERC uses FN-BODY as the body of the default response handler
`erc-server-NAME', which handles all incoming IRC \"NAME\" responses,
unless overridden (see below). ERC calls the function with two
arguments, PROC and PARSED, whose symbols (lowercase) are bound to the
current `erc-server-process' and `erc-response' instance within FN-BODY.
Implementers should take care not to shadow them inadvertently. In all
cases, FN-BODY should return nil to allow third parties to run code
after `erc-server-NAME' returns. For historical reasons, ERC does not
currently enforce this, however future versions very well may.
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'.\"))
Note that while all ALIASES share the same handler function, each gets
its own distinct hook variable. The default value of these variables
may be a list or a function. Robust code should handle both.
\(fn (NAME &rest ALIASES) &optional EXTRA-FN-DOC EXTRA-VAR-DOC &rest FN-BODY)"
(declare (debug (&define [&name "erc-response-handler@"
;; No `def-edebug-elem-spec' in 27.
([&or integerp symbolp]
&rest [&or integerp symbolp])]
&optional sexp sexp def-body))
(doc-string 2)
(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))))))