Mercurial > emacs
diff lisp/simple.el @ 106109:42ca82b4620b
* abbrev.el (abbrev-with-wrapper-hook): (re)move...
* simple.el (with-wrapper-hook): ...to here. Add argument `args'.
* minibuffer.el (completion-in-region-functions): New hook.
(completion-in-region): New function.
* emacs-lisp/lisp.el (lisp-complete-symbol):
* pcomplete.el (pcomplete-std-complete): Use it.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Thu, 19 Nov 2009 03:12:51 +0000 |
parents | 11d369ec41c4 |
children | 62c0a89cd695 |
line wrap: on
line diff
--- a/lisp/simple.el Thu Nov 19 01:40:22 2009 +0000 +++ b/lisp/simple.el Thu Nov 19 03:12:51 2009 +0000 @@ -6479,6 +6479,7 @@ (setq buffer-invisibility-spec nil))) ;; Partial application of functions (similar to "currying"). +;; This function is here rather than in subr.el because it uses CL. (defun apply-partially (fun &rest args) "Return a function that is a partial application of FUN to ARGS. ARGS is a list of the first N arguments to pass to FUN. @@ -6487,6 +6488,52 @@ was called." (lexical-let ((fun fun) (args1 args)) (lambda (&rest args2) (apply fun (append args1 args2))))) + +;; This function is here rather than in subr.el because it uses CL. +(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 inital argument, and which the first argument +expects to receive when called." + (declare (indent 2) (debug t)) + ;; We need those two gensyms because CL's lexical scoping is not available + ;; for function arguments :-( + (let ((funs (make-symbol "funs")) + (global (make-symbol "global")) + (argssym (make-symbol "args"))) + ;; Since the hook is a wrapper, the loop has to be done via + ;; recursion: a given hook function will call its parameter in order to + ;; continue looping. + `(labels ((runrestofhook (,funs ,global ,argssym) + ;; `funs' holds the functions left on the hook and `global' + ;; holds the functions left on the global part of the hook + ;; (in case the hook is local). + (lexical-let ((funs ,funs) + (global ,global)) + (if (consp funs) + (if (eq t (car funs)) + (apply 'runrestofhook + (append global (cdr funs)) nil ,argssym) + (apply (car funs) + (lambda (&rest args) + (runrestofhook (cdr funs) global args)) + ,argssym)) + ;; Once there are no more functions on the hook, run + ;; the original body. + (apply (lambda ,args ,@body) ,argssym))))) + (runrestofhook ,var + ;; The global part of the hook, if any. + ,(if (symbolp var) + `(if (local-variable-p ',var) + (default-value ',var))) + (list ,@args))))) ;; Minibuffer prompt stuff.