Document with-wrapper-hook.

* doc/emacs/modes.texi (Running Hooks): Document with-wrapper-hook.

* lisp/subr.el (with-wrapper-hook): Rewrite doc.
This commit is contained in:
Chong Yidong 2011-10-26 08:44:06 +08:00
parent 507ea2587e
commit b1f6fa2666
3 changed files with 35 additions and 17 deletions

View file

@ -1169,7 +1169,13 @@ must also be supplied.
** pre/post-command-hook are not reset to nil upon error.
Instead, the offending function is removed.
** New low-level function run-hook-wrapped.
** New hook types
*** New function `run-hook-wrapped' for running an abnormal hook by
passing the hook functions as arguments to a "wrapping" function.
+++
*** New macro `with-wrapper-hook' for running an abnormal hook as a
set of "wrapping" filters, similar to around advice.
** `server-eval-at' is provided to allow evaluating forms on different
Emacs server instances.

View file

@ -1,3 +1,7 @@
2011-10-26 Chong Yidong <cyd@gnu.org>
* subr.el (with-wrapper-hook): Rewrite doc.
2011-10-25 Michael Albinus <michael.albinus@gmx.de>
* net/tramp-sh.el (tramp-sh-handle-file-directory-p): Return t for

View file

@ -1364,18 +1364,26 @@ All symbols are bound before the VALUEFORMs are evalled."
,@(mapcar (lambda (binder) `(setq ,@binder)) binders)
,@body))
(defmacro with-wrapper-hook (var args &rest body)
"Run BODY wrapped with the VAR hook.
VAR is a special hook: its functions are called with a first argument
which is the \"original\" code (the BODY), so the hook function can wrap
the original function, or call it any number of times (including not calling
it at all). This is similar to an `around' advice.
VAR is normally a symbol (a variable) in which case it is treated like
a hook, with a buffer-local and a global part. But it can also be an
arbitrary expression.
ARGS is a list of variables which will be passed as additional arguments
to each function, after the initial argument, and which the first argument
expects to receive when called."
(defmacro with-wrapper-hook (hook args &rest body)
"Run BODY, using wrapper functions from HOOK with additional ARGS.
HOOK is an abnormal hook. Each hook function in HOOK \"wraps\"
around the preceding ones, like a set of nested `around' advices.
Each hook function should accept an argument list consisting of a
function FUN, followed by the additional arguments in ARGS.
The FUN passed to the first hook function in HOOK performs BODY,
if it is called with arguments ARGS. The FUN passed to each
successive hook function is defined based on the preceding hook
functions; if called with arguments ARGS, it does what the
`with-wrapper-hook' call would do if the preceding hook functions
were the only ones present in HOOK.
In the function definition of each hook function, FUN can be
called any number of times (including not calling it at all).
That function definition is then used to construct the FUN passed
to the next hook function, if any. The last (or \"outermost\")
FUN is then called once."
(declare (indent 2) (debug (form sexp body)))
;; We need those two gensyms because CL's lexical scoping is not available
;; for function arguments :-(
@ -1404,11 +1412,11 @@ expects to receive when called."
;; Once there are no more functions on the hook, run
;; the original body.
(apply (lambda ,args ,@body) ,argssym)))))
(funcall ,runrestofhook ,var
(funcall ,runrestofhook ,hook
;; The global part of the hook, if any.
,(if (symbolp var)
`(if (local-variable-p ',var)
(default-value ',var)))
,(if (symbolp hook)
`(if (local-variable-p ',hook)
(default-value ',hook)))
(list ,@args)))))
(defun add-to-list (list-var element &optional append compare-fn)