diff options
| author | Stefan Monnier | 2014-05-10 16:07:01 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2014-05-10 16:07:01 -0400 |
| commit | 5d03fb436fcfb1fe704cc7a66dec7bd2d21d49f1 (patch) | |
| tree | 7884824b46c957bc5bfce46066e756d4ae4992db /lisp | |
| parent | 4a5c71d7c275b93238c629601526a87eca08e6fd (diff) | |
| download | emacs-5d03fb436fcfb1fe704cc7a66dec7bd2d21d49f1.tar.gz emacs-5d03fb436fcfb1fe704cc7a66dec7bd2d21d49f1.zip | |
* lisp/emacs-lisp/nadvice.el: Support adding a given function multiple times.
(advice--member-p): If name is given, only compare the name.
(advice--remove-function): Don't stop at the first match.
(advice--normalize-place): New function.
(add-function, remove-function): Use it.
(advice--add-function): Pass the name, if any, to
advice--remove-function.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 10 | ||||
| -rw-r--r-- | lisp/emacs-lisp/nadvice.el | 41 |
2 files changed, 31 insertions, 20 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 3f47c077f5c..0fa0c93915a 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2014-05-10 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * emacs-lisp/nadvice.el: Support adding a given function multiple times. | ||
| 4 | (advice--member-p): If name is given, only compare the name. | ||
| 5 | (advice--remove-function): Don't stop at the first match. | ||
| 6 | (advice--normalize-place): New function. | ||
| 7 | (add-function, remove-function): Use it. | ||
| 8 | (advice--add-function): Pass the name, if any, to | ||
| 9 | advice--remove-function. | ||
| 10 | |||
| 1 | 2014-05-09 Philipp Rumpf <prumpf@gmail.com> (tiny change) | 11 | 2014-05-09 Philipp Rumpf <prumpf@gmail.com> (tiny change) |
| 2 | 12 | ||
| 3 | * electric.el (electric-indent-post-self-insert-function): Don't use | 13 | * electric.el (electric-indent-post-self-insert-function): Don't use |
diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el index 0e2536f8179..332d1ed61b6 100644 --- a/lisp/emacs-lisp/nadvice.el +++ b/lisp/emacs-lisp/nadvice.el | |||
| @@ -183,9 +183,9 @@ WHERE is a symbol to select an entry in `advice--where-alist'." | |||
| 183 | (defun advice--member-p (function name definition) | 183 | (defun advice--member-p (function name definition) |
| 184 | (let ((found nil)) | 184 | (let ((found nil)) |
| 185 | (while (and (not found) (advice--p definition)) | 185 | (while (and (not found) (advice--p definition)) |
| 186 | (if (or (equal function (advice--car definition)) | 186 | (if (if name |
| 187 | (when name | 187 | (equal name (cdr (assq 'name (advice--props definition)))) |
| 188 | (equal name (cdr (assq 'name (advice--props definition)))))) | 188 | (equal function (advice--car definition))) |
| 189 | (setq found definition) | 189 | (setq found definition) |
| 190 | (setq definition (advice--cdr definition)))) | 190 | (setq definition (advice--cdr definition)))) |
| 191 | found)) | 191 | found)) |
| @@ -209,8 +209,8 @@ WHERE is a symbol to select an entry in `advice--where-alist'." | |||
| 209 | (lambda (first rest props) | 209 | (lambda (first rest props) |
| 210 | (cond ((not first) rest) | 210 | (cond ((not first) rest) |
| 211 | ((or (equal function first) | 211 | ((or (equal function first) |
| 212 | (equal function (cdr (assq 'name props)))) | 212 | (equal function (cdr (assq 'name props)))) |
| 213 | (list rest)))))) | 213 | (list (advice--remove-function rest function))))))) |
| 214 | 214 | ||
| 215 | (defvar advice--buffer-local-function-sample nil | 215 | (defvar advice--buffer-local-function-sample nil |
| 216 | "keeps an example of the special \"run the default value\" functions. | 216 | "keeps an example of the special \"run the default value\" functions. |
| @@ -232,6 +232,12 @@ different, but `function-equal' will hopefully ignore those differences.") | |||
| 232 | ;; This function acts like the t special value in buffer-local hooks. | 232 | ;; This function acts like the t special value in buffer-local hooks. |
| 233 | (lambda (&rest args) (apply (default-value var) args))))) | 233 | (lambda (&rest args) (apply (default-value var) args))))) |
| 234 | 234 | ||
| 235 | (defun advice--normalize-place (place) | ||
| 236 | (cond ((eq 'local (car-safe place)) `(advice--buffer-local ,@(cdr place))) | ||
| 237 | ((eq 'var (car-safe place)) (nth 1 place)) | ||
| 238 | ((symbolp place) `(default-value ',place)) | ||
| 239 | (t place))) | ||
| 240 | |||
| 235 | ;;;###autoload | 241 | ;;;###autoload |
| 236 | (defmacro add-function (where place function &optional props) | 242 | (defmacro add-function (where place function &optional props) |
| 237 | ;; TODO: | 243 | ;; TODO: |
| @@ -267,8 +273,9 @@ a special meaning: | |||
| 267 | the advice should be innermost (i.e. at the end of the list), | 273 | the advice should be innermost (i.e. at the end of the list), |
| 268 | whereas a depth of -100 means that the advice should be outermost. | 274 | whereas a depth of -100 means that the advice should be outermost. |
| 269 | 275 | ||
| 270 | If PLACE is a simple variable, only its global value will be affected. | 276 | If PLACE is a symbol, its `default-value' will be affected. |
| 271 | Use (local 'VAR) if you want to apply FUNCTION to VAR buffer-locally. | 277 | Use (local 'SYMBOL) if you want to apply FUNCTION to SYMBOL buffer-locally. |
| 278 | Use (var VAR) if you want to apply FUNCTION to the (lexical) VAR. | ||
| 272 | 279 | ||
| 273 | If one of FUNCTION or OLDFUN is interactive, then the resulting function | 280 | If one of FUNCTION or OLDFUN is interactive, then the resulting function |
| 274 | is also interactive. There are 3 cases: | 281 | is also interactive. There are 3 cases: |
| @@ -278,20 +285,18 @@ is also interactive. There are 3 cases: | |||
| 278 | `advice-eval-interactive-spec') and return the list of arguments to use. | 285 | `advice-eval-interactive-spec') and return the list of arguments to use. |
| 279 | - Else, use the interactive spec of FUNCTION and ignore the one of OLDFUN." | 286 | - Else, use the interactive spec of FUNCTION and ignore the one of OLDFUN." |
| 280 | (declare (debug t)) ;;(indent 2) | 287 | (declare (debug t)) ;;(indent 2) |
| 281 | (cond ((eq 'local (car-safe place)) | 288 | `(advice--add-function ,where (gv-ref ,(advice--normalize-place place)) |
| 282 | (setq place `(advice--buffer-local ,@(cdr place)))) | 289 | ,function ,props)) |
| 283 | ((symbolp place) | ||
| 284 | (setq place `(default-value ',place)))) | ||
| 285 | `(advice--add-function ,where (gv-ref ,place) ,function ,props)) | ||
| 286 | 290 | ||
| 287 | ;;;###autoload | 291 | ;;;###autoload |
| 288 | (defun advice--add-function (where ref function props) | 292 | (defun advice--add-function (where ref function props) |
| 289 | (let ((a (advice--member-p function (cdr (assq 'name props)) | 293 | (let* ((name (cdr (assq 'name props))) |
| 290 | (gv-deref ref)))) | 294 | (a (advice--member-p function name (gv-deref ref)))) |
| 291 | (when a | 295 | (when a |
| 292 | ;; The advice is already present. Remove the old one, first. | 296 | ;; The advice is already present. Remove the old one, first. |
| 293 | (setf (gv-deref ref) | 297 | (setf (gv-deref ref) |
| 294 | (advice--remove-function (gv-deref ref) (advice--car a)))) | 298 | (advice--remove-function (gv-deref ref) |
| 299 | (or name (advice--car a))))) | ||
| 295 | (setf (gv-deref ref) | 300 | (setf (gv-deref ref) |
| 296 | (advice--make where function (gv-deref ref) props)))) | 301 | (advice--make where function (gv-deref ref) props)))) |
| 297 | 302 | ||
| @@ -302,11 +307,7 @@ If FUNCTION was not added to PLACE, do nothing. | |||
| 302 | Instead of FUNCTION being the actual function, it can also be the `name' | 307 | Instead of FUNCTION being the actual function, it can also be the `name' |
| 303 | of the piece of advice." | 308 | of the piece of advice." |
| 304 | (declare (debug t)) | 309 | (declare (debug t)) |
| 305 | (cond ((eq 'local (car-safe place)) | 310 | (gv-letplace (getter setter) (advice--normalize-place place) |
| 306 | (setq place `(advice--buffer-local ,@(cdr place)))) | ||
| 307 | ((symbolp place) | ||
| 308 | (setq place `(default-value ',place)))) | ||
| 309 | (gv-letplace (getter setter) place | ||
| 310 | (macroexp-let2 nil new `(advice--remove-function ,getter ,function) | 311 | (macroexp-let2 nil new `(advice--remove-function ,getter ,function) |
| 311 | `(unless (eq ,new ,getter) ,(funcall setter new))))) | 312 | `(unless (eq ,new ,getter) ,(funcall setter new))))) |
| 312 | 313 | ||