Commit | Line | Data |
---|---|---|
6e2f6f45 | 1 | ;;; advice.el --- an overloading mechanism for Emacs Lisp functions |
ee7bf2ad | 2 | |
6e2f6f45 | 3 | ;; Copyright (C) 1993, 1994 Free Software Foundation, Inc. |
ee7bf2ad RM |
4 | |
5 | ;; Author: Hans Chalupsky <hans@cs.buffalo.edu> | |
6 | ;; Created: 12 Dec 1992 | |
f643a891 | 7 | ;; Version: advice.el,v 2.11 1994/02/24 22:51:43 hans Exp |
b7f66977 | 8 | ;; Keywords: extensions, lisp, tools |
ee7bf2ad RM |
9 | |
10 | ;; This file is part of GNU Emacs. | |
11 | ||
12 | ;; GNU Emacs is free software; you can redistribute it and/or modify | |
13 | ;; it under the terms of the GNU General Public License as published by | |
14 | ;; the Free Software Foundation; either version 2, or (at your option) | |
15 | ;; any later version. | |
16 | ||
17 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | ;; GNU General Public License for more details. | |
21 | ||
22 | ;; You should have received a copy of the GNU General Public License | |
23 | ;; along with GNU Emacs; see the file COPYING. If not, write to | |
24 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
25 | ||
26 | ;; LCD Archive Entry: | |
27 | ;; advice|Hans Chalupsky|hans@cs.buffalo.edu| | |
6e2f6f45 | 28 | ;; Overloading mechanism for Emacs Lisp functions| |
f643a891 | 29 | ;; 1994/02/24 22:51:43|2.11|~/packages/advice.el.Z| |
ee7bf2ad RM |
30 | |
31 | ||
32 | ;;; Commentary: | |
33 | ||
6e2f6f45 RS |
34 | ;; NOTE: This documentation is slightly out of date. In particular, all the |
35 | ;; references to Emacs-18 are obsolete now, because it is not any longer | |
36 | ;; supported by this version of Advice. An up-to-date version will soon be | |
37 | ;; available as an info file (thanks to the kind help of Jack Vinson and | |
38 | ;; David M. Smith). | |
39 | ||
ee7bf2ad RM |
40 | ;; @ Introduction: |
41 | ;; =============== | |
42 | ;; This package implements a full-fledged Lisp-style advice mechanism | |
43 | ;; for Emacs Lisp. Advice is a clean and efficient way to modify the | |
44 | ;; behavior of Emacs Lisp functions without having to keep personal | |
45 | ;; modified copies of such functions around. A great number of such | |
46 | ;; modifications can be achieved by treating the original function as a | |
47 | ;; black box and specifying a different execution environment for it | |
48 | ;; with a piece of advice. Think of a piece of advice as a kind of fancy | |
49 | ;; hook that you can attach to any function/macro/subr. | |
50 | ||
51 | ;; @ Highlights: | |
52 | ;; ============= | |
53 | ;; - Clean definition of multiple, named before/around/after advices | |
54 | ;; for functions, macros, subrs and special forms | |
55 | ;; - Full control over the arguments an advised function will receive, | |
56 | ;; the binding environment in which it will be executed, as well as the | |
57 | ;; value it will return. | |
58 | ;; - Allows re/definition of interactive behavior for functions and subrs | |
59 | ;; - Every piece of advice can have its documentation string which will be | |
60 | ;; combined with the original documentation of the advised function at | |
61 | ;; call-time of `documentation' for proper command-key substitution. | |
62 | ;; - The execution of every piece of advice can be protected against error | |
63 | ;; and non-local exits in preceding code or advices. | |
64 | ;; - Simple argument access either by name, or, more portable but as | |
65 | ;; efficient, via access macros | |
66 | ;; - Allows the specification of a different argument list for the advised | |
67 | ;; version of a function. | |
68 | ;; - Advised functions can be byte-compiled either at file-compile time | |
69 | ;; (see preactivation) or activation time. | |
70 | ;; - Separation of advice definition and activation | |
71 | ;; - Provides generally accessible function definition (after) hooks | |
72 | ;; - Forward advice is possible (an application of definition hooks), that is | |
73 | ;; as yet undefined or autoload functions can be advised without having to | |
74 | ;; preload the file in which they are defined. | |
75 | ;; - Forward redefinition is possible because around advice can be used to | |
76 | ;; completely redefine a function. | |
77 | ;; - A caching mechanism for advised definition provides for cheap deactivation | |
78 | ;; and reactivation of advised functions. | |
79 | ;; - Preactivation allows efficient construction and compilation of advised | |
80 | ;; definitions at file compile time without giving up the flexibility of | |
81 | ;; the advice mechanism. | |
82 | ;; - En/disablement mechanism allows the use of different "views" of advised | |
83 | ;; functions depending on what pieces of advice are currently en/disabled | |
84 | ;; - Provides manipulation mechanisms for sets of advised functions via | |
85 | ;; regular expressions that match advice names | |
86 | ;; - Allows definition of load-hooks for arbitrary Emacs Lisp files without | |
87 | ;; modification of these files | |
88 | ||
6e2f6f45 RS |
89 | ;; @ How to get Advice for Emacs-18: |
90 | ;; ================================= | |
91 | ;; `advice18.el', a version of Advice that also works in Emacs-18 is available | |
92 | ;; either via anonymous ftp from `ftp.cs.buffalo.edu (128.205.32.9)' with | |
93 | ;; pathname `/pub/Emacs/advice18.el', or from one of the Emacs Lisp archive | |
94 | ;; sites, or send email to <hans@cs.buffalo.edu> and I'll mail it to you. | |
ee7bf2ad RM |
95 | |
96 | ;; @ Overview, or how to read this file: | |
97 | ;; ===================================== | |
6e2f6f45 RS |
98 | ;; NOTE: This documentation is slightly out of date. In particular, all the |
99 | ;; references to Emacs-18 are obsolete now, because it is not any longer | |
100 | ;; supported by this version of Advice. An up-to-date version will soon be | |
101 | ;; available as an info file (thanks to the kind help of Jack Vinson and | |
102 | ;; David M. Smith). Until then you can use `outline-mode' to help you read | |
103 | ;; this documentation (set `outline-regexp' to `";; @+"'). | |
ee7bf2ad RM |
104 | ;; |
105 | ;; The four major sections of this file are: | |
106 | ;; | |
107 | ;; @ This initial information ...installation, customization etc. | |
108 | ;; @ Advice documentation: ...general documentation | |
6e2f6f45 | 109 | ;; @ Foo games: An advice tutorial ...teaches about Advice by example |
ee7bf2ad RM |
110 | ;; @ Advice implementation: ...actual code, yeah!! |
111 | ;; | |
112 | ;; The latter three are actual headings which you can search for | |
6e2f6f45 | 113 | ;; directly in case `outline-mode' doesn't work for you. |
ee7bf2ad RM |
114 | |
115 | ;; @ Restrictions: | |
116 | ;; =============== | |
6e2f6f45 | 117 | ;; - This version of Advice only works for Emacs-19 or Lucid Emacs. |
ee7bf2ad RM |
118 | ;; - Advised functions/macros/subrs will only exhibit their advised behavior |
119 | ;; when they are invoked via their function cell. This means that advice will | |
120 | ;; not work for the following: | |
121 | ;; + advised subrs that are called directly from other subrs or C-code | |
122 | ;; + advised subrs that got replaced with their byte-code during | |
123 | ;; byte-compilation (e.g., car) | |
124 | ;; + advised macros which were expanded during byte-compilation before | |
125 | ;; their advice was activated. | |
6e2f6f45 RS |
126 | |
127 | ;; @ Known bug: | |
128 | ;; ============ | |
129 | ;; - Using automatic activation of (forward) advice will break the | |
130 | ;; function `interactive-p' when it is used in the body of a `catch' | |
131 | ;; (this problem will go away once automatic advice activation gets | |
132 | ;; supported by built-in functions). | |
ee7bf2ad RM |
133 | |
134 | ;; @ Credits: | |
135 | ;; ========== | |
136 | ;; This package is an extension and generalization of packages such as | |
137 | ;; insert-hooks.el written by Noah S. Friedman, and advise.el written by | |
138 | ;; Raul J. Acevedo. Some ideas used in here come from these packages, | |
139 | ;; others come from the various Lisp advice mechanisms I've come across | |
140 | ;; so far, and a few are simply mine. | |
141 | ||
142 | ;; @ Comments, suggestions, bug reports: | |
143 | ;; ===================================== | |
144 | ;; If you find any bugs, have suggestions for new advice features, find the | |
145 | ;; documentation wrong, confusing, incomplete, or otherwise unsatisfactory, | |
6e2f6f45 | 146 | ;; have any questions about Advice, or have otherwise enlightening |
ee7bf2ad RM |
147 | ;; comments feel free to send me email at <hans@cs.buffalo.edu>. |
148 | ||
149 | ;; @ Safety Rules and Emergency Exits: | |
150 | ;; =================================== | |
151 | ;; Before we begin: CAUTION!! | |
6e2f6f45 | 152 | ;; Advice provides you with a lot of rope to hang yourself on very |
ee7bf2ad | 153 | ;; easily accessible trees, so, here are a few important things you |
6e2f6f45 | 154 | ;; should know: Once Advice has been started with `ad-start-advice' it |
ee7bf2ad RM |
155 | ;; generates advised definitions of the `documentation' function, and, |
156 | ;; if definition hooks are enabled (e.g., for forward advice), also of | |
157 | ;; `defun', `defmacro' and `fset' (if you use Jamie Zawinski's (jwz) | |
6e2f6f45 | 158 | ;; optimizing byte-compiler as standardly used in Emacs-19 and |
ee7bf2ad RM |
159 | ;; Lucid Emacs-19 (Lemacs), then enabling definition hooks will also |
160 | ;; redefine the `byte-code' subr). All these changes can be undone at | |
161 | ;; any time with `M-x ad-stop-advice'. | |
162 | ;; | |
163 | ;; If you experience any strange behavior/errors etc. that you attribute to | |
6e2f6f45 | 164 | ;; Advice or to some ill-advised function do one of the following: |
ee7bf2ad RM |
165 | |
166 | ;; - M-x ad-deactivate FUNCTION (if you have a definite suspicion what | |
167 | ;; function gives you problems) | |
168 | ;; - M-x ad-deactivate-all (if you don't have a clue what's going wrong) | |
169 | ;; - M-x ad-stop-advice (if you think the problem is related to the | |
6e2f6f45 | 170 | ;; advised functions used by Advice itself) |
ee7bf2ad | 171 | ;; - M-x ad-recover-normality (for real emergencies) |
6e2f6f45 | 172 | ;; - If none of the above solves your Advice-related problem go to another |
ee7bf2ad RM |
173 | ;; terminal, kill your Emacs process and send me some hate mail. |
174 | ||
175 | ;; The first three measures have restarts, i.e., once you've figured out | |
176 | ;; the problem you can reactivate advised functions with either `ad-activate', | |
177 | ;; `ad-activate-all', or `ad-start-advice'. `ad-recover-normality' unadvises | |
178 | ;; everything so you won't be able to reactivate any advised functions, you'll | |
179 | ;; have to stick with their standard incarnations for the rest of the session. | |
180 | ||
6e2f6f45 | 181 | ;; IMPORTANT: With Advice loaded always do `M-x ad-deactivate-all' before |
ee7bf2ad RM |
182 | ;; you byte-compile a file, because advised special forms and macros can lead |
183 | ;; to unwanted compilation results. When you are done compiling use | |
184 | ;; `M-x ad-activate-all' to go back to the advised state of all your | |
185 | ;; advised functions. | |
186 | ||
6e2f6f45 | 187 | ;; RELAX: Advice is pretty safe even if you are oblivious to the above. |
ee7bf2ad RM |
188 | ;; I use it extensively and haven't run into any serious trouble in a long |
189 | ;; time. Just wanted you to be warned. | |
190 | ||
ee7bf2ad RM |
191 | ;; @ Customization: |
192 | ;; ================ | |
193 | ;; Part of the advice magic does not start until you call `ad-start-advice' | |
194 | ;; which you can either do interactively, explicitly in your .emacs, or by | |
195 | ;; putting | |
196 | ;; | |
197 | ;; (setq ad-start-advice-on-load t) | |
198 | ;; | |
199 | ;; into your .emacs which will automatically start advice when the file gets | |
200 | ;; loaded. | |
201 | ||
202 | ;; If you want to be able to forward advise functions, that is to advise them | |
203 | ;; when they are not yet defined or defined as autoloads, then you should put | |
204 | ;; the following into your .emacs | |
205 | ;; | |
206 | ;; (setq ad-activate-on-definition t) | |
207 | ;; | |
208 | ;; which will activate all advice at the time the function gets actually | |
209 | ;; defined/loaded. The value of this variable will not have any effect until | |
210 | ;; `ad-start-advice' gets executed. | |
211 | ||
ee7bf2ad RM |
212 | ;; Look at the documentation of `ad-redefinition-action' for possible values |
213 | ;; of this variable. Its default value is `warn' which will print a warning | |
214 | ;; message when an already defined advised function gets redefined with a | |
215 | ;; new original definition and de/activated. | |
216 | ||
217 | ;; @ Motivation: | |
218 | ;; ============= | |
219 | ;; Before I go on explaining how advice works, here are four simple examples | |
220 | ;; how this package can be used. The first three are very useful, the last one | |
221 | ;; is just a joke: | |
222 | ||
223 | ;;(defadvice switch-to-buffer (before existing-buffers-only activate) | |
224 | ;; "When called interactively switch to existing buffers only, unless | |
225 | ;;when called with a prefix argument." | |
226 | ;; (interactive | |
227 | ;; (list (read-buffer "Switch to buffer: " (other-buffer) | |
228 | ;; (null current-prefix-arg))))) | |
229 | ;; | |
230 | ;;(defadvice switch-to-buffer (around confirm-non-existing-buffers activate) | |
231 | ;; "Switch to non-existing buffers only upon confirmation." | |
232 | ;; (interactive "BSwitch to buffer: ") | |
233 | ;; (if (or (get-buffer (ad-get-arg 0)) | |
234 | ;; (y-or-n-p (format "`%s' does not exist, create? " (ad-get-arg 0)))) | |
235 | ;; ad-do-it)) | |
236 | ;; | |
237 | ;;(defadvice find-file (before existing-files-only activate) | |
238 | ;; "Find existing files only" | |
239 | ;; (interactive "fFind file: ")) | |
240 | ;; | |
241 | ;;(defadvice car (around interactive activate) | |
242 | ;; "Make `car' an interactive function." | |
243 | ;; (interactive "xCar of list: ") | |
244 | ;; ad-do-it | |
245 | ;; (if (interactive-p) | |
246 | ;; (message "%s" ad-return-value))) | |
247 | ||
248 | ||
249 | ;; @ Advice documentation: | |
250 | ;; ======================= | |
251 | ;; Below is general documentation of the various features of advice. For more | |
252 | ;; concrete examples check the corresponding sections in the tutorial part. | |
253 | ||
254 | ;; @@ Terminology: | |
255 | ;; =============== | |
6e2f6f45 | 256 | ;; - Emacs, Emacs-19: FSF's version of Emacs with major version 19 |
ee7bf2ad RM |
257 | ;; - Lemacs: Lucid's version of Emacs with major version 19 |
258 | ;; - v18: Any Emacs with major version 18 or built as an extension to that | |
259 | ;; (such as Epoch) | |
260 | ;; - v19: Any Emacs with major version 19 | |
261 | ;; - jwz: Jamie Zawinski - keeper of Lemacs and creator of the optimizing | |
262 | ;; byte-compiler used in v19s. | |
6e2f6f45 | 263 | ;; - Advice: The name of this package. |
ee7bf2ad RM |
264 | ;; - advices: Short for "pieces of advice". |
265 | ||
266 | ;; @@ Defining a piece of advice with `defadvice': | |
267 | ;; =============================================== | |
268 | ;; The main means of defining a piece of advice is the macro `defadvice', | |
269 | ;; there is no interactive way of specifying a piece of advice. A call to | |
270 | ;; `defadvice' has the following syntax which is similar to the syntax of | |
271 | ;; `defun/defmacro': | |
272 | ;; | |
273 | ;; (defadvice <function> (<class> <name> [<position>] [<arglist>] {<flags>}*) | |
274 | ;; [ [<documentation-string>] [<interactive-form>] ] | |
275 | ;; {<body-form>}* ) | |
276 | ||
277 | ;; <function> is the name of the function/macro/subr to be advised. | |
278 | ||
279 | ;; <class> is the class of the advice which has to be one of `before', | |
280 | ;; `around', `after', `activation' or `deactivation' (the last two allow | |
281 | ;; definition of special act/deactivation hooks). | |
282 | ||
6e2f6f45 | 283 | ;; <name> is the name of the advice which has to be a non-nil symbol. |
ee7bf2ad RM |
284 | ;; Names uniquely identify a piece of advice in a certain advice class, |
285 | ;; hence, advices can be redefined by defining an advice with the same class | |
286 | ;; and name. Advice names are global symbols, hence, the same name space | |
287 | ;; conventions used for function names should be applied. | |
288 | ||
289 | ;; An optional <position> specifies where in the current list of advices of | |
290 | ;; the specified <class> this new advice will be placed. <position> has to | |
291 | ;; be either `first', `last' or a number that specifies a zero-based | |
292 | ;; position (`first' is equivalent to 0). If no position is specified | |
293 | ;; `first' will be used as a default. If this call to `defadvice' redefines | |
294 | ;; an already existing advice (see above) then the position argument will | |
295 | ;; be ignored and the position of the already existing advice will be used. | |
296 | ||
297 | ;; An optional <arglist> which has to be a list can be used to define the | |
298 | ;; argument list of the advised function. This argument list should of | |
299 | ;; course be compatible with the argument list of the original function, | |
300 | ;; otherwise functions that call the advised function with the original | |
301 | ;; argument list in mind will break. If more than one advice specify an | |
302 | ;; argument list then the first one (the one with the smallest position) | |
303 | ;; found in the list of before/around/after advices will be used. | |
304 | ||
305 | ;; <flags> is a list of symbols that specify further information about the | |
306 | ;; advice. All flags can be specified with unambiguous initial substrings. | |
307 | ;; `activate': Specifies that the advice information of the advised | |
308 | ;; function should be activated right after this advice has been | |
309 | ;; defined. In forward advices `activate' will be ignored. | |
310 | ;; `protect': Specifies that this advice should be protected against | |
311 | ;; non-local exits and errors in preceding code/advices. | |
312 | ;; `compile': Specifies that the advised function should be byte-compiled. | |
313 | ;; This flag will be ignored unless `activate' is also specified. | |
314 | ;; `disable': Specifies that the defined advice should be disabled, hence, | |
315 | ;; it will not be used in an activation until somebody enables it. | |
316 | ;; `preactivate': Specifies that the advised function should get preactivated | |
317 | ;; at macro-expansion/compile time of this `defadvice'. This | |
318 | ;; generates a compiled advised definition according to the | |
319 | ;; current advice state which will be used during activation | |
320 | ;; if appropriate. Only use this if the `defadvice' gets | |
321 | ;; actually compiled (with a v18 byte-compiler put the `defadvice' | |
322 | ;; into the body of a `defun' to accomplish proper compilation). | |
323 | ||
324 | ;; An optional <documentation-string> can be supplied to document the advice. | |
325 | ;; On call of the `documentation' function it will be combined with the | |
326 | ;; documentation strings of the original function and other advices. | |
327 | ||
328 | ;; An optional <interactive-form> form can be supplied to change/add | |
329 | ;; interactive behavior of the original function. If more than one advice | |
330 | ;; has an `(interactive ...)' specification then the first one (the one | |
331 | ;; with the smallest position) found in the list of before/around/after | |
332 | ;; advices will be used. | |
333 | ||
334 | ;; A possibly empty list of <body-forms> specifies the body of the advice in | |
335 | ;; an implicit progn. The body of an advice can access/change arguments, | |
336 | ;; the return value, the binding environment, and can have all sorts of | |
337 | ;; other side effects. | |
338 | ||
339 | ;; @@ Assembling advised definitions: | |
340 | ;; ================================== | |
341 | ;; Suppose a function/macro/subr/special-form has N pieces of before advice, | |
342 | ;; M pieces of around advice and K pieces of after advice. Assuming none of | |
343 | ;; the advices is protected, its advised definition will look like this | |
344 | ;; (body-form indices correspond to the position of the respective advice in | |
345 | ;; that advice class): | |
346 | ||
347 | ;; ([macro] lambda <arglist> | |
348 | ;; [ [<advised-docstring>] [(interactive ...)] ] | |
349 | ;; (let (ad-return-value) | |
350 | ;; {<before-0-body-form>}* | |
351 | ;; .... | |
352 | ;; {<before-N-1-body-form>}* | |
353 | ;; {<around-0-body-form>}* | |
354 | ;; {<around-1-body-form>}* | |
355 | ;; .... | |
356 | ;; {<around-M-1-body-form>}* | |
357 | ;; (setq ad-return-value | |
358 | ;; <apply original definition to <arglist>>) | |
359 | ;; {<other-around-M-1-body-form>}* | |
360 | ;; .... | |
361 | ;; {<other-around-1-body-form>}* | |
362 | ;; {<other-around-0-body-form>}* | |
363 | ;; {<after-0-body-form>}* | |
364 | ;; .... | |
365 | ;; {<after-K-1-body-form>}* | |
366 | ;; ad-return-value)) | |
367 | ||
368 | ;; Macros and special forms will be redefined as macros, hence the optional | |
369 | ;; [macro] in the beginning of the definition. | |
370 | ||
371 | ;; <arglist> is either the argument list of the original function or the | |
372 | ;; first argument list defined in the list of before/around/after advices. | |
373 | ;; The values of <arglist> variables can be accessed/changed in the body of | |
374 | ;; an advice by simply referring to them by their original name, however, | |
375 | ;; more portable argument access macros are also provided (see below). For | |
376 | ;; subrs/special-forms for which neither explicit argument list definitions | |
377 | ;; are available, nor their documentation strings contain such definitions | |
378 | ;; (as they do v19s), `(&rest ad-subr-args)' will be used. | |
379 | ||
380 | ;; <advised-docstring> is an optional, special documentation string which will | |
381 | ;; be expanded into a proper documentation string upon call of `documentation'. | |
382 | ||
383 | ;; (interactive ...) is an optional interactive form either taken from the | |
384 | ;; original function or from a before/around/after advice. For advised | |
385 | ;; interactive subrs that do not have an interactive form specified in any | |
386 | ;; advice we have to use (interactive) and then call the subr interactively | |
387 | ;; if the advised function was called interactively, because the | |
388 | ;; interactive specification of subrs is not accessible. This is the only | |
389 | ;; case where changing the values of arguments will not have an affect | |
390 | ;; because they will be reset by the interactive specification of the subr. | |
391 | ;; If this is a problem one can always specify an interactive form in a | |
392 | ;; before/around/after advice to gain control over argument values that | |
393 | ;; were supplied interactively. | |
394 | ;; | |
395 | ;; Then the body forms of the various advices in the various classes of advice | |
396 | ;; are assembled in order. The forms of around advice L are normally part of | |
397 | ;; one of the forms of around advice L-1. An around advice can specify where | |
398 | ;; the forms of the wrapped or surrounded forms should go with the special | |
399 | ;; keyword `ad-do-it', which will be substituted with a `progn' containing the | |
400 | ;; forms of the surrounded code. | |
401 | ||
402 | ;; The innermost part of the around advice onion is | |
403 | ;; <apply original definition to <arglist>> | |
404 | ;; whose form depends on the type of the original function. The variable | |
405 | ;; `ad-return-value' will be set to its result. This variable is visible to | |
406 | ;; all pieces of advice which can access and modify it before it gets returned. | |
407 | ;; | |
408 | ;; The semantic structure of advised functions that contain protected pieces | |
409 | ;; of advice is the same. The only difference is that `unwind-protect' forms | |
410 | ;; make sure that the protected advice gets executed even if some previous | |
411 | ;; piece of advice had an error or a non-local exit. If any around advice is | |
412 | ;; protected then the whole around advice onion will be protected. | |
413 | ||
414 | ;; @@ Argument access in advised functions: | |
415 | ;; ======================================== | |
416 | ;; As already mentioned, the simplest way to access the arguments of an | |
417 | ;; advised function in the body of an advice is to refer to them by name. To | |
418 | ;; do that, the advice programmer needs to know either the names of the | |
419 | ;; argument variables of the original function, or the names used in the | |
420 | ;; argument list redefinition given in a piece of advice. While this simple | |
421 | ;; method might be sufficient in many cases, it has the disadvantage that it | |
422 | ;; is not very portable because it hardcodes the argument names into the | |
423 | ;; advice. If the definition of the original function changes the advice | |
424 | ;; might break even though the code might still be correct. Situations like | |
425 | ;; that arise, for example, if one advises a subr like `eval-region' which | |
426 | ;; gets redefined in a non-advice style into a function by the edebug | |
427 | ;; package. If the advice assumes `eval-region' to be a subr it might break | |
428 | ;; once edebug is loaded. Similar situations arise when one wants to use the | |
429 | ;; same piece of advice across different versions of Emacs. Some subrs in a | |
430 | ;; v18 Emacs are functions in v19 and vice versa, but for the most part the | |
431 | ;; semantics remain the same, hence, the same piece of advice might be usable | |
432 | ;; in both Emacs versions. | |
433 | ||
434 | ;; As a solution to that advice provides argument list access macros that get | |
435 | ;; translated into the proper access forms at activation time, i.e., when the | |
436 | ;; advised definition gets constructed. Access macros access actual arguments | |
437 | ;; by position regardless of how these actual argument get distributed onto | |
438 | ;; the argument variables of a function. The rational behind this is that in | |
439 | ;; Emacs Lisp the semantics of an argument is strictly determined by its | |
440 | ;; position (there are no keyword arguments). | |
441 | ||
442 | ;; Suppose the function `foo' is defined as | |
443 | ;; | |
444 | ;; (defun foo (x y &optional z &rest r) ....) | |
445 | ;; | |
446 | ;; and is then called with | |
447 | ;; | |
448 | ;; (foo 0 1 2 3 4 5 6) | |
449 | ||
450 | ;; which means that X=0, Y=1, Z=2 and R=(3 4 5 6). The assumption is that | |
451 | ;; the semantics of an actual argument is determined by its position. It is | |
452 | ;; this semantics that has to be known by the advice programmer. Then s/he | |
453 | ;; can access these arguments in a piece of advice with some of the | |
454 | ;; following macros (the arrows indicate what value they will return): | |
455 | ||
456 | ;; (ad-get-arg 0) -> 0 | |
457 | ;; (ad-get-arg 1) -> 1 | |
458 | ;; (ad-get-arg 2) -> 2 | |
459 | ;; (ad-get-arg 3) -> 3 | |
460 | ;; (ad-get-args 2) -> (2 3 4 5 6) | |
461 | ;; (ad-get-args 4) -> (4 5 6) | |
462 | ||
463 | ;; `(ad-get-arg <position>)' will return the actual argument that was supplied | |
464 | ;; at <position>, `(ad-get-args <position>)' will return the list of actual | |
465 | ;; arguments supplied starting at <position>. Note that these macros can be | |
466 | ;; used without any knowledge about the form of the actual argument list of | |
467 | ;; the original function. | |
468 | ||
469 | ;; Similarly, `(ad-set-arg <position> <value-form>)' can be used to set the | |
470 | ;; value of the actual argument at <position> to <value-form>. For example, | |
471 | ;; | |
472 | ;; (ad-set-arg 5 "five") | |
473 | ;; | |
474 | ;; will have the effect that R=(3 4 "five" 6) once the original function is | |
475 | ;; called. `(ad-set-args <position> <value-list-form>)' can be used to set | |
476 | ;; the list of actual arguments starting at <position> to <value-list-form>. | |
477 | ;; For example, | |
478 | ;; | |
479 | ;; (ad-set-args 0 '(5 4 3 2 1 0)) | |
480 | ;; | |
481 | ;; will have the effect that X=5, Y=4, Z=3 and R=(2 1 0) once the original | |
482 | ;; function is called. | |
483 | ||
484 | ;; All these access macros are text macros rather than real Lisp macros. When | |
485 | ;; the advised definition gets constructed they get replaced with actual access | |
486 | ;; forms depending on the argument list of the advised function, i.e., after | |
487 | ;; that argument access is in most cases as efficient as using the argument | |
488 | ;; variable names directly. | |
489 | ||
490 | ;; @@@ Accessing argument bindings of arbitrary functions: | |
491 | ;; ======================================================= | |
492 | ;; Some functions (such as `trace-function' defined in trace.el) need a | |
493 | ;; method of accessing the names and bindings of the arguments of an | |
494 | ;; arbitrary advised function. To do that within an advice one can use the | |
495 | ;; special keyword `ad-arg-bindings' which is a text macro that will be | |
496 | ;; substituted with a form that will evaluate to a list of binding | |
497 | ;; specifications, one for every argument variable. These binding | |
498 | ;; specifications can then be examined in the body of the advice. For | |
499 | ;; example, somewhere in an advice we could do this: | |
500 | ;; | |
501 | ;; (let* ((bindings ad-arg-bindings) | |
502 | ;; (firstarg (car bindings)) | |
503 | ;; (secondarg (car (cdr bindings)))) | |
504 | ;; ;; Print info about first argument | |
505 | ;; (print (format "%s=%s (%s)" | |
506 | ;; (ad-arg-binding-field firstarg 'name) | |
507 | ;; (ad-arg-binding-field firstarg 'value) | |
508 | ;; (ad-arg-binding-field firstarg 'type))) | |
509 | ;; ....) | |
510 | ;; | |
511 | ;; The `type' of an argument is either `required', `optional' or `rest'. | |
512 | ;; Wherever `ad-arg-bindings' appears a form will be inserted that evaluates | |
513 | ;; to the list of bindings, hence, in order to avoid multiple unnecessary | |
514 | ;; evaluations one should always bind it to some variable. | |
515 | ||
516 | ;; @@@ Argument list mapping: | |
517 | ;; ========================== | |
518 | ;; Because `defadvice' allows the specification of the argument list of the | |
519 | ;; advised function we need a mapping mechanism that maps this argument list | |
520 | ;; onto that of the original function. For example, somebody might specify | |
521 | ;; `(sym newdef)' as the argument list of `fset', while advice might use | |
522 | ;; `(&rest ad-subr-args)' as the argument list of the original function | |
523 | ;; (depending on what Emacs version is used). Hence SYM and NEWDEF have to | |
524 | ;; be properly mapped onto the &rest variable when the original definition is | |
525 | ;; called. Advice automatically takes care of that mapping, hence, the advice | |
526 | ;; programmer can specify an argument list without having to know about the | |
527 | ;; exact structure of the original argument list as long as the new argument | |
528 | ;; list takes a compatible number/magnitude of actual arguments. | |
529 | ||
530 | ;; @@@ Definition of subr argument lists: | |
531 | ;; ====================================== | |
532 | ;; When advice constructs the advised definition of a function it has to | |
533 | ;; know the argument list of the original function. For functions and macros | |
534 | ;; the argument list can be determined from the actual definition, however, | |
535 | ;; for subrs there is no such direct access available. In Lemacs and for some | |
6e2f6f45 | 536 | ;; subrs in Emacs-19 the argument list of a subr can be determined from |
ee7bf2ad RM |
537 | ;; its documentation string, in a v18 Emacs even that is not possible. If |
538 | ;; advice cannot at all determine the argument list of a subr it uses | |
539 | ;; `(&rest ad-subr-args)' which will always work but is inefficient because | |
540 | ;; it conses up arguments. The macro `ad-define-subr-args' can be used by | |
541 | ;; the advice programmer to explicitly tell advice about the argument list | |
542 | ;; of a certain subr, for example, | |
543 | ;; | |
544 | ;; (ad-define-subr-args 'fset '(sym newdef)) | |
545 | ;; | |
546 | ;; is used by advice itself to tell a v18 Emacs about the arguments of `fset'. | |
547 | ;; The following can be used to undo such a definition: | |
548 | ;; | |
549 | ;; (ad-undefine-subr-args 'fset) | |
550 | ;; | |
551 | ;; The argument list definition is stored on the property list of the subr | |
552 | ;; name symbol. When an argument list could be determined from the | |
553 | ;; documentation string it will be cached under that property. The general | |
554 | ;; mechanism for looking up the argument list of a subr is the following: | |
555 | ;; 1) look for a definition stored on the property list | |
556 | ;; 2) if that failed try to infer it from the documentation string and | |
557 | ;; if successful cache it on the property list | |
558 | ;; 3) otherwise use `(&rest ad-subr-args)' | |
559 | ||
560 | ;; @@ Activation and deactivation: | |
561 | ;; =============================== | |
562 | ;; The definition of an advised function does not change until all its advice | |
563 | ;; gets actually activated. Activation can either happen with the `activate' | |
564 | ;; flag specified in the `defadvice', with an explicit call or interactive | |
565 | ;; invocation of `ad-activate', or if forward advice is enabled (i.e., the | |
566 | ;; value of `ad-activate-on-definition' is t) at the time an already advised | |
567 | ;; function gets defined. | |
568 | ||
569 | ;; When a function gets first activated its original definition gets saved, | |
570 | ;; all defined and enabled pieces of advice will get combined with the | |
571 | ;; original definition, the resulting definition might get compiled depending | |
572 | ;; on some conditions described below, and then the function will get | |
573 | ;; redefined with the advised definition. This also means that undefined | |
574 | ;; functions cannot get activated even though they might be already advised. | |
575 | ||
576 | ;; The advised definition will get compiled either if `ad-activate' was called | |
577 | ;; interactively with a prefix argument, or called explicitly with its second | |
578 | ;; argument as t, or, if this was a case of forward advice if the original | |
579 | ;; definition of the function was compiled. If the advised definition was | |
580 | ;; constructed during "preactivation" (see below) then that definition will | |
581 | ;; be already compiled because it was constructed during byte-compilation of | |
582 | ;; the file that contained the `defadvice' with the `preactivate' flag. | |
583 | ||
584 | ;; `ad-deactivate' can be used to back-define an advised function to its | |
585 | ;; original definition. It can be called interactively or directly. Because | |
586 | ;; `ad-activate' caches the advised definition the function can be | |
587 | ;; reactivated via `ad-activate' with only minor overhead (it is checked | |
588 | ;; whether the current advice state is consistent with the cached | |
589 | ;; definition, see the section on caching below). | |
590 | ||
591 | ;; `ad-activate-regexp' and `ad-deactivate-regexp' can be used to de/activate | |
592 | ;; all currently advised function that have a piece of advice with a name that | |
593 | ;; contains a match for a regular expression. These functions can be used to | |
594 | ;; de/activate sets of functions depending on certain advice naming | |
595 | ;; conventions. | |
596 | ||
597 | ;; Finally, `ad-activate-all' and `ad-deactivate-all' can be used to | |
598 | ;; de/activate all currently advised functions. These are useful to | |
599 | ;; (temporarily) return to an un/advised state. | |
600 | ||
601 | ;; @@@ Reasons for the separation of advice definition and activation: | |
602 | ;; =================================================================== | |
603 | ;; As already mentioned, advising happens in two stages: | |
604 | ||
605 | ;; 1) definition of various pieces of advice | |
606 | ;; 2) activation of all advice currently defined and enabled | |
607 | ||
608 | ;; The advantage of this is that various pieces of advice can be defined | |
609 | ;; before they get combined into an advised definition which avoids | |
610 | ;; unnecessary constructions of intermediate advised definitions. The more | |
611 | ;; important advantage is that it allows the implementation of forward advice. | |
612 | ;; Advice information for a certain function accumulates as the value of the | |
613 | ;; `advice-info' property of the function symbol. This accumulation is | |
614 | ;; completely independent of the fact that that function might not yet be | |
615 | ;; defined. The special forms `defun' and `defmacro' have been advised to | |
616 | ;; check whether the function/macro they defined had advice information | |
617 | ;; associated with it. If so and forward advice is enabled, the original | |
618 | ;; definition will be saved, and then the advice will be activated. When a | |
619 | ;; file is loaded in a v18 Emacs the functions/macros it defines are also | |
620 | ;; defined with calls to `defun/defmacro'. Hence, we can forward advise | |
621 | ;; functions/macros which will be defined later during a load/autoload of some | |
622 | ;; file (for compiled files generated by jwz's byte-compiler in a v19 Emacs | |
623 | ;; this is slightly more complicated but the basic idea is the same). | |
624 | ||
625 | ;; @@ Enabling/disabling pieces or sets of advice: | |
626 | ;; =============================================== | |
627 | ;; A major motivation for the development of this advice package was to bring | |
628 | ;; a little bit more structure into the function overloading chaos in Emacs | |
629 | ;; Lisp. Many packages achieve some of their functionality by adding a little | |
630 | ;; bit (or a lot) to the standard functionality of some Emacs Lisp function. | |
631 | ;; ange-ftp is a very popular package that achieves its magic by overloading | |
632 | ;; most Emacs Lisp functions that deal with files. A popular function that's | |
633 | ;; overloaded by many packages is `expand-file-name'. The situation that one | |
634 | ;; function is multiply overloaded can arise easily. | |
635 | ||
636 | ;; Once in a while it would be desirable to be able to disable some/all | |
637 | ;; overloads of a particular package while keeping all the rest. Ideally - | |
638 | ;; at least in my opinion - these overloads would all be done with advice, | |
639 | ;; I know I am dreaming right now... In that ideal case the enable/disable | |
640 | ;; mechanism of advice could be used to achieve just that. | |
641 | ||
642 | ;; Every piece of advice is associated with an enablement flag. When the | |
643 | ;; advised definition of a particular function gets constructed (e.g., during | |
644 | ;; activation) only the currently enabled pieces of advice will be considered. | |
645 | ;; This mechanism allows one to have different "views" of an advised function | |
646 | ;; dependent on what pieces of advice are currently enabled. | |
647 | ||
648 | ;; Another motivation for this mechanism is that it allows one to define a | |
649 | ;; piece of advice for some function yet keep it dormant until a certain | |
650 | ;; condition is met. Until then activation of the function will not make use | |
651 | ;; of that piece of advice. Once the condition is met the advice can be | |
652 | ;; enabled and a reactivation of the function will add its functionality as | |
653 | ;; part of the new advised definition. For example, the advices of `defun' | |
654 | ;; etc. used by advice itself will stay disabled until `ad-start-advice' is | |
655 | ;; called and some variables have the proper values. Hence, if somebody | |
656 | ;; else advised these functions too and activates them the advices defined | |
657 | ;; by advice will get used only if they are intended to be used. | |
658 | ||
659 | ;; The main interface to this mechanism are the interactive functions | |
660 | ;; `ad-enable-advice' and `ad-disable-advice'. For example, the following | |
661 | ;; would disable a particular advice of the function `foo': | |
662 | ;; | |
663 | ;; (ad-disable-advice 'foo 'before 'my-advice) | |
664 | ;; | |
665 | ;; This call by itself only changes the flag, to get the proper effect in | |
666 | ;; the advised definition too one has to activate `foo' with | |
667 | ;; | |
668 | ;; (ad-activate 'foo) | |
669 | ;; | |
670 | ;; or interactively. To disable whole sets of advices one can use a regular | |
671 | ;; expression mechanism. For example, let us assume that ange-ftp actually | |
672 | ;; used advice to overload all its functions, and that it used the | |
673 | ;; "ange-ftp-" prefix for all its advice names, then we could temporarily | |
674 | ;; disable all its advices with | |
675 | ;; | |
676 | ;; (ad-disable-regexp "^ange-ftp-") | |
677 | ;; | |
678 | ;; and the following call would put that actually into effect: | |
679 | ;; | |
680 | ;; (ad-activate-regexp "^ange-ftp-") | |
681 | ;; | |
682 | ;; A saver way would have been to use | |
683 | ;; | |
684 | ;; (ad-update-regexp "^ange-ftp-") | |
685 | ;; | |
686 | ;; instead which would have only reactivated currently actively advised | |
687 | ;; functions, but not functions that were currently deactivated. All these | |
688 | ;; functions can also be called interactively. | |
689 | ||
690 | ;; A certain piece of advice is considered a match if its name contains a | |
691 | ;; match for the regular expression. To enable ange-ftp again we would use | |
692 | ;; `ad-enable-regexp' and then activate or update again. | |
693 | ||
694 | ;; @@ Forward advice, function definition hooks: | |
695 | ;; ============================================= | |
696 | ;; Because most Emacs Lisp packages are loaded on demand via an autoload | |
697 | ;; mechanism it is essential to be able to "forward advise" functions. | |
698 | ;; Otherwise, proper advice definition and activation would make it necessary | |
699 | ;; to preload every file that defines a certain function before it can be | |
700 | ;; advised, which would partly defeat the purpose of the advice mechanism. | |
701 | ||
702 | ;; In the following, "forward advice" always implies its automatic activation | |
703 | ;; once a function gets defined, and not just the accumulation of advice | |
704 | ;; information for a possibly undefined function. | |
705 | ||
706 | ;; Advice implements forward advice mainly via the following: 1) Separation | |
707 | ;; of advice definition and activation that makes it possible to accumulate | |
708 | ;; advice information without having the original function already defined, | |
709 | ;; 2) special versions of the function defining functions `defun', `defmacro' | |
710 | ;; and `fset' that check for advice information whenever they define a | |
711 | ;; function. If advice information was found and forward advice is enabled | |
712 | ;; then the advice will immediately get activated when the function gets | |
713 | ;; defined. | |
714 | ||
715 | ;; @@@ Enabling forward advice: | |
716 | ;; ============================ | |
717 | ;; Forward advice is enabled by setting `ad-activate-on-definition' to t | |
718 | ;; and then calling `ad-start-advice' which can either be done interactively, | |
719 | ;; directly with `(ad-start-advice)' in your .emacs, or by setting | |
720 | ;; `ad-start-advice-on-load' to t before advice gets loaded. For example, | |
721 | ;; putting the following into your .emacs will enable forward advice: | |
722 | ;; | |
723 | ;; (setq ad-start-advice-on-load t) | |
724 | ;; (setq ad-activate-on-definition t) | |
725 | ;; | |
726 | ;; "Activation on definition" means, that whenever a function gets defined | |
727 | ;; with either `defun', `defmacro', `fset' or by loading a byte-compiled | |
728 | ;; file, and the function has some advice-info stored with it then that | |
729 | ;; advice will get activated right away. | |
730 | ||
731 | ;; If jwz's byte-compiler is used then `ad-use-jwz-byte-compiler' should | |
732 | ;; be t in order to make forward advice work with functions defined in | |
733 | ;; compiled files generated by that compiler. In v19s which use this | |
734 | ;; compiler the value of this variable will be correct automatically. | |
735 | ;; If you use a v18 Emacs in conjunction with jwz's compiler and you want | |
736 | ;; to use forward advice then you should check its value after loading | |
737 | ;; advice. If it is nil set it explicitly with | |
738 | ;; | |
739 | ;; (setq ad-use-jwz-byte-compiler t) | |
740 | ;; | |
741 | ;; along with `ad-activate-on-definition' before you start advice (see above). | |
742 | ||
743 | ;; IMPORTANT: A v18 Emacs + jwz's compiler + forward advice means performance | |
744 | ;; tradeoffs which are described below. | |
745 | ||
746 | ;; @@@ Forward advice with compiled files generated by jwz's byte-compiler: | |
747 | ;; ======================================================================== | |
748 | ;; The v18 byte-compiler only uses `defun/defmacro' to define compiled | |
749 | ;; functions, hence, providing advised versions of these functions was | |
750 | ;; sufficient to achieve forward advice. With the advent of Jamie Zawinski's | |
6e2f6f45 | 751 | ;; optimizing byte-compiler which is now standardly used in Emacs-19 and |
ee7bf2ad RM |
752 | ;; Lemacs things became more complicated. jwz's compiler defines functions |
753 | ;; in hunks of byte-code without explicit usage of `defun/defmacro'. To | |
754 | ;; still provide forward advice even in this scenario, advice defines an | |
755 | ;; advised version of the `byte-code' subr that scans its arguments for | |
756 | ;; function definitions during the loading of compiled files. While this is | |
757 | ;; no problem in a v19 Emacs, because it uses a new datatype for compiled | |
758 | ;; code objects and the `byte-code' subr is only rarely used at all, it | |
759 | ;; presents a major problem in a v18 Emacs because there calls to | |
760 | ;; `byte-code' are the only means of executing compiled code (every body of | |
761 | ;; a compiled function contains a call to `byte-code'). Because the advised | |
762 | ;; `byte-code' has to perform some extra checks every call to a compiled | |
763 | ;; function becomes more expensive. | |
764 | ||
765 | ;; Enabling forward advice leads to performance degradation in the following | |
766 | ;; situations: | |
767 | ;; - A v18 Emacs is used and the value of `ad-use-jwz-byte-compiler' is t | |
768 | ;; (either because jwz's byte-compiler is used instead of the standard v18 | |
769 | ;; compiler, or some compiled files generated by jwz's compiler are used). | |
770 | ;; - A v19 Emacs is used with some old-style v18 compiled files. | |
771 | ;; Some performance experiments I conducted showed that function call intensive | |
772 | ;; code (such as the highly recursive byte-compiler itself) slows down by a | |
773 | ;; factor of 1.8. Function call intensive code that runs while a file gets | |
774 | ;; loaded can slow down by a factor of 6! For the v19 scenario this performance | |
775 | ;; lossage would only apply to code that was loaded from old v18 compiled | |
776 | ;; files. | |
777 | ||
778 | ;; MORAL: If you use a v18 Emacs in conjunction with jwz's byte-compiler you | |
779 | ;; should think twice whether you really need forward advice. There are some | |
780 | ;; alternatives to forward advice described below that might give you what | |
781 | ;; you need without the loss of performance (that performance loss probably | |
782 | ;; outweighs by far any performance gain due to the optimizing nature of jwz's | |
783 | ;; compiler). | |
784 | ||
785 | ;; @@@ Alternatives to automatic activation of forward advice: | |
786 | ;; =========================================================== | |
787 | ;; If you use a v18 Emacs in conjunction with jwz's compiler, or you simply | |
788 | ;; don't trust the automatic activation mechanism of forward advice, then | |
789 | ;; you can use some of the following alternatives to get around that: | |
790 | ;; - Preload the file that contains the definition of the function that you | |
791 | ;; want to advice. Inelegant and wasteful, but it works. | |
792 | ;; - If the package that contains the definition of the function you want to | |
793 | ;; advise has any mode hooks, and the advised function is only used once such | |
794 | ;; a mode has been entered, then you can activate the advice in the mode | |
795 | ;; hook. Just put a form like `(ad-activate 'my-advised-fn t)' into the | |
796 | ;; hook definition. The caching mechanism will reuse advised definitions, | |
797 | ;; so calling that mode hook over and over again will not construct | |
798 | ;; advised definitions over and over again, so you won't loose any | |
799 | ;; performance. | |
800 | ;; - If your Emacs comes with file load hooks (such as v19's | |
801 | ;; `after-load-alist' mechanism), then you can put the activation form | |
802 | ;; into that, for example, add `("myfile" (ad-activate 'my-advised-fn t))' | |
803 | ;; to it to activate the advice right ater "myfile" got loaded. | |
804 | ||
805 | ;; @@@ Function definition hooks: | |
806 | ;; ============================== | |
807 | ;; Automatic activation of forward advice is implemented as an application | |
808 | ;; of a more general function definition hook mechanism. After a function | |
809 | ;; gets re/defined with `defun/defmacro/fset' or via a hunk of byte-code | |
810 | ;; during the loading of a byte-compiled file, and function definition hooks | |
811 | ;; are enabled, then all hook functions stored in `ad-definition-hooks' are | |
812 | ;; run with the variable `ad-defined-function' bound to the name of the | |
813 | ;; currently defined function. | |
814 | ||
815 | ;; Function definition hooks can be enabled with | |
816 | ;; | |
817 | ;; (setq ad-enable-definition-hooks t) | |
818 | ;; | |
819 | ;; before advice gets started with `ad-start-advice'. Setting | |
820 | ;; `ad-activate-on-definition' to t automatically enables definition hooks | |
821 | ;; regardless of the value of `ad-enable-definition-hooks'. | |
822 | ||
823 | ;; @@@ Wish list: | |
824 | ;; ============== | |
825 | ;; - The implementation of definition hooks for v19 compiled files would be | |
826 | ;; safer if jwz's byte-compiler used something like `byte-code-tl' instead | |
827 | ;; of `byte-code' to execute hunks of function defining byte-code at the | |
828 | ;; top level of compiled files. | |
829 | ;; - Definition hooks should be implemented directly as part of the C-code | |
6e2f6f45 | 830 | ;; that implements `fset', because then Advice wouldn't have to use all |
ee7bf2ad RM |
831 | ;; these dirty hacks to achieve this functionality. |
832 | ||
833 | ;; @@ Caching of advised definitions: | |
834 | ;; ================================== | |
835 | ;; After an advised definition got constructed it gets cached as part of the | |
836 | ;; advised function's advice-info so it can be reused, for example, after an | |
837 | ;; intermediate deactivation. Because the advice-info of a function might | |
838 | ;; change between the time of caching and reuse a cached definition gets | |
839 | ;; a cache-id associated with it so it can be verified whether the cached | |
840 | ;; definition is still valid (the main application of this is preactivation | |
841 | ;; - see below). | |
842 | ||
843 | ;; When an advised function gets activated and a verifiable cached definition | |
844 | ;; is available, then that definition will be used instead of creating a new | |
845 | ;; advised definition from scratch. If you want to make sure that a new | |
846 | ;; definition gets constructed then you should use `ad-clear-cache' before you | |
847 | ;; activate the advised function. | |
848 | ||
849 | ;; @@ Preactivation: | |
850 | ;; ================= | |
851 | ;; Constructing an advised definition is moderately expensive. In a situation | |
852 | ;; where one package defines a lot of advised functions it might be | |
853 | ;; prohibitively expensive to do all the advised definition construction at | |
854 | ;; runtime. Preactivation is a mechanism that allows compile-time construction | |
855 | ;; of compiled advised definitions that can be activated cheaply during | |
856 | ;; runtime. Preactivation uses the caching mechanism to do that. Here's how it | |
857 | ;; works: | |
858 | ||
859 | ;; When the byte-compiler compiles a `defadvice' that has the `preactivate' | |
860 | ;; flag specified, it uses the current original definition of the advised | |
861 | ;; function plus the advice specified in this `defadvice' (even if it is | |
862 | ;; specified as disabled) and all other currently enabled pieces of advice to | |
863 | ;; construct an advised definition and an identifying cache-id and makes them | |
864 | ;; part of the `defadvice' expansion which will then be compiled by the | |
865 | ;; byte-compiler (to ensure that in a v18 emacs you have to put the | |
866 | ;; `defadvice' inside a `defun' to get it compiled and then you have to call | |
867 | ;; that compiled `defun' in order to actually execute the `defadvice'). When | |
868 | ;; the file with the compiled, preactivating `defadvice' gets loaded the | |
869 | ;; precompiled advised definition will be cached on the advised function's | |
870 | ;; advice-info. When it gets activated (can be immediately on execution of the | |
871 | ;; `defadvice' or any time later) the cache-id gets checked against the | |
872 | ;; current state of advice and if it is verified the precompiled definition | |
873 | ;; will be used directly (the verification is pretty cheap). If it couldn't get | |
874 | ;; verified a new advised definition for that function will be built from | |
875 | ;; scratch, hence, the efficiency added by the preactivation mechanism does | |
876 | ;; not at all impair the flexibility of the advice mechanism. | |
877 | ||
878 | ;; MORAL: In order get all the efficiency out of preactivation the advice | |
879 | ;; state of an advised function at the time the file with the | |
880 | ;; preactivating `defadvice' gets byte-compiled should be exactly | |
881 | ;; the same as it will be when the advice of that function gets | |
882 | ;; actually activated. If it is not there is a high chance that the | |
883 | ;; cache-id will not match and hence a new advised definition will | |
884 | ;; have to be constructed at runtime. | |
885 | ||
886 | ;; Preactivation and forward advice do not contradict each other. It is | |
887 | ;; perfectly ok to load a file with a preactivating `defadvice' before the | |
888 | ;; original definition of the advised function is available. The constructed | |
889 | ;; advised definition will be used once the original function gets defined and | |
890 | ;; its advice gets activated. The only constraint is that at the time the | |
891 | ;; file with the preactivating `defadvice' got compiled the original function | |
892 | ;; definition was available. | |
893 | ||
894 | ;; TIPS: Here are some indications that a preactivation did not work the way | |
895 | ;; you intended it to work: | |
896 | ;; - Activation of the advised function takes longer than usual/expected | |
897 | ;; - The byte-compiler gets loaded while an advised function gets | |
898 | ;; activated | |
899 | ;; - `byte-compile' is part of the `features' variable even though you | |
900 | ;; did not use the byte-compiler | |
901 | ;; Right now advice does not provide an elegant way to find out whether | |
902 | ;; and why a preactivation failed. What you can do is to trace the | |
903 | ;; function `ad-cache-id-verification-code' (with the function | |
904 | ;; `trace-function-background' defined in my trace.el package) before | |
905 | ;; any of your advised functions get activated. After they got | |
906 | ;; activated check whether all calls to `ad-cache-id-verification-code' | |
907 | ;; returned `verified' as a result. Other values indicate why the | |
908 | ;; verification failed which should give you enough information to | |
909 | ;; fix your preactivation/compile/load/activation sequence. | |
910 | ||
911 | ;; IMPORTANT: There is one case (that I am aware of) that can make | |
912 | ;; preactivation fail, i.e., a preconstructed advised definition that does | |
913 | ;; NOT match the current state of advice gets used nevertheless. That case | |
914 | ;; arises if one package defines a certain piece of advice which gets used | |
915 | ;; during preactivation, and another package incompatibly redefines that | |
916 | ;; very advice (i.e., same function/class/name), and it is the second advice | |
917 | ;; that is available when the preconstructed definition gets activated, and | |
918 | ;; that was the only definition of that advice so far (`ad-add-advice' | |
919 | ;; catches advice redefinitions and clears the cache in such a case). | |
920 | ;; Catching that would make the cache verification too expensive. | |
921 | ||
922 | ;; MORAL-II: Redefining somebody else's advice is BAAAAD (to speak with | |
923 | ;; George Walker Bush), and why would you redefine your own advice anyway? | |
924 | ;; Advice is a mechanism to facilitate function redefinition, not advice | |
6e2f6f45 | 925 | ;; redefinition (wait until I write Meta-Advice :-). If you really have |
ee7bf2ad RM |
926 | ;; to undo somebody else's advice try to write a "neutralizing" advice. |
927 | ||
928 | ;; @@ Advising macros and special forms and other dangerous things: | |
929 | ;; ================================================================ | |
930 | ;; Look at the corresponding tutorial sections for more information on | |
931 | ;; these topics. Here it suffices to point out that the special treatment | |
932 | ;; of macros and special forms by the byte-compiler can lead to problems | |
933 | ;; when they get advised. Macros can create problems because they get | |
934 | ;; expanded at compile time, hence, they might not have all the necessary | |
935 | ;; runtime support and such advice cannot be de/activated or changed as | |
936 | ;; it is possible for functions. Special forms create problems because they | |
937 | ;; have to be advised "into" macros, i.e., an advised special form is a | |
938 | ;; implemented as a macro, hence, in most cases the byte-compiler will | |
939 | ;; not recognize it as a special form anymore which can lead to very strange | |
940 | ;; results. | |
941 | ;; | |
942 | ;; MORAL: - Only advise macros or special forms when you are absolutely sure | |
943 | ;; what you are doing. | |
944 | ;; - As a safety measure, always do `ad-deactivate-all' before you | |
945 | ;; byte-compile a file to make sure that even if some inconsiderate | |
946 | ;; person advised some special forms you'll get proper compilation | |
947 | ;; results. After compilation do `ad-activate-all' to get back to | |
948 | ;; the previous state. | |
949 | ||
950 | ;; @@ Adding a piece of advice with `ad-add-advice': | |
951 | ;; ================================================= | |
952 | ;; The non-interactive function `ad-add-advice' can be used to add a piece of | |
953 | ;; advice to some function without using `defadvice'. This is useful if advice | |
954 | ;; has to be added somewhere by a function (also look at `ad-make-advice'). | |
955 | ||
956 | ;; @@ Activation/deactivation advices, file load hooks: | |
957 | ;; ==================================================== | |
958 | ;; There are two special classes of advice called `activation' and | |
959 | ;; `deactivation'. The body forms of these advices are not included into the | |
960 | ;; advised definition of a function, rather they are assembled into a hook | |
961 | ;; form which will be evaluated whenever the advice-info of the advised | |
962 | ;; function gets activated or deactivated. One application of this mechanism | |
963 | ;; is to define file load hooks for files that do not provide such hooks | |
964 | ;; (v19s already come with a general file-load-hook mechanism, v18s don't). | |
965 | ;; For example, suppose you want to print a message whenever `file-x' gets | |
966 | ;; loaded, and suppose the last function defined in `file-x' is | |
967 | ;; `file-x-last-fn'. Then we can define the following advice: | |
968 | ;; | |
969 | ;; (defadvice file-x-last-fn (activation file-x-load-hook) | |
970 | ;; "Executed whenever file-x is loaded" | |
971 | ;; (if load-in-progress (message "Loaded file-x"))) | |
972 | ;; | |
973 | ;; This will constitute a forward advice for function `file-x-last-fn' which | |
974 | ;; will get activated when `file-x' is loaded (only if forward advice is | |
975 | ;; enabled of course). Because there are no "real" pieces of advice | |
976 | ;; available for it, its definition will not be changed, but the activation | |
977 | ;; advice will be run during its activation which is equivalent to having a | |
978 | ;; file load hook for `file-x'. | |
979 | ||
980 | ;; @@ Summary of main advice concepts: | |
981 | ;; =================================== | |
982 | ;; - Definition: | |
983 | ;; A piece of advice gets defined with `defadvice' and added to the | |
984 | ;; `advice-info' property of a function. | |
985 | ;; - Enablement: | |
986 | ;; Every piece of advice has an enablement flag associated with it. Only | |
987 | ;; enabled advices are considered during construction of an advised | |
988 | ;; definition. | |
989 | ;; - Activation: | |
990 | ;; Redefine an advised function with its advised definition. Constructs | |
991 | ;; an advised definition from scratch if no verifiable cached advised | |
992 | ;; definition is available and caches it. | |
993 | ;; - Deactivation: | |
994 | ;; Back-define an advised function to its original definition. | |
995 | ;; - Update: | |
996 | ;; Reactivate an advised function but only if its advice is currently | |
997 | ;; active. This can be used to bring all currently advised function up | |
998 | ;; to date with the current state of advice without also activating | |
999 | ;; currently deactivated functions. | |
1000 | ;; - Caching: | |
1001 | ;; Is the saving of an advised definition and an identifying cache-id so | |
1002 | ;; it can be reused, for example, for activation after deactivation. | |
1003 | ;; - Preactivation: | |
1004 | ;; Is the construction of an advised definition according to the current | |
1005 | ;; state of advice during byte-compilation of a file with a preactivating | |
1006 | ;; `defadvice'. That advised definition can then rather cheaply be used | |
1007 | ;; during activation without having to construct an advised definition | |
1008 | ;; from scratch at runtime. | |
1009 | ||
1010 | ;; @@ Summary of interactive advice manipulation functions: | |
1011 | ;; ======================================================== | |
1012 | ;; The following interactive functions can be used to manipulate the state | |
1013 | ;; of advised functions (all of them support completion on function names, | |
1014 | ;; advice classes and advice names): | |
1015 | ||
1016 | ;; - ad-activate to activate the advice of a FUNCTION | |
1017 | ;; - ad-deactivate to deactivate the advice of a FUNCTION | |
1018 | ;; - ad-update to activate the advice of a FUNCTION unless it was not | |
1019 | ;; yet activated or is currently deactivated. | |
1020 | ;; - ad-unadvise deactivates a FUNCTION and removes all of its advice | |
1021 | ;; information, hence, it cannot be activated again | |
1022 | ;; - ad-recover tries to redefine a FUNCTION to its original definition and | |
1023 | ;; discards all advice information (a low-level `ad-unadvise'). | |
1024 | ;; Use only in emergencies. | |
1025 | ||
1026 | ;; - ad-remove-advice removes a particular piece of advice of a FUNCTION. | |
1027 | ;; You still have to do call `ad-activate' or `ad-update' to | |
1028 | ;; activate the new state of advice. | |
1029 | ;; - ad-enable-advice enables a particular piece of advice of a FUNCTION. | |
1030 | ;; - ad-disable-advice disables a particular piece of advice of a FUNCTION. | |
1031 | ;; - ad-enable-regexp maps over all currently advised functions and enables | |
1032 | ;; every advice whose name contains a match for a regular | |
1033 | ;; expression. | |
1034 | ;; - ad-disable-regexp disables matching advices. | |
1035 | ||
1036 | ;; - ad-activate-regexp activates all advised function with a matching advice | |
1037 | ;; - ad-deactivate-regexp deactivates all advised function with matching advice | |
1038 | ;; - ad-update-regexp updates all advised function with a matching advice | |
1039 | ;; - ad-activate-all activates all advised functions | |
1040 | ;; - ad-deactivate-all deactivates all advised functions | |
1041 | ;; - ad-update-all updates all advised functions | |
1042 | ;; - ad-unadvise-all unadvises all advised functions | |
1043 | ;; - ad-recover-all recovers all advised functions | |
1044 | ||
1045 | ;; - ad-compile byte-compiles a function/macro if it is compilable. | |
1046 | ||
1047 | ;; @@ Summary of forms with special meanings when used within an advice: | |
1048 | ;; ===================================================================== | |
1049 | ;; ad-return-value name of the return value variable (get/settable) | |
1050 | ;; ad-subr-args name of &rest argument variable used for advised | |
1051 | ;; subrs whose actual argument list cannot be | |
1052 | ;; determined (get/settable) | |
1053 | ;; (ad-get-arg <pos>), (ad-get-args <pos>), | |
1054 | ;; (ad-set-arg <pos> <value>), (ad-set-args <pos> <value-list>) | |
1055 | ;; argument access text macros to get/set the values of | |
1056 | ;; actual arguments at a certain position | |
1057 | ;; ad-arg-bindings text macro that returns the actual names, values | |
1058 | ;; and types of the arguments as a list of bindings. The | |
1059 | ;; order of the bindings corresponds to the order of the | |
1060 | ;; arguments. The individual fields of every binding (name, | |
1061 | ;; value and type) can be accessed with the function | |
1062 | ;; `ad-arg-binding-field' (see example above). | |
1063 | ;; ad-do-it text macro that identifies the place where the original | |
1064 | ;; or wrapped definition should go in an around advice | |
1065 | ||
1066 | ||
1067 | ;; @ Foo games: An advice tutorial | |
1068 | ;; =============================== | |
6e2f6f45 | 1069 | ;; The following tutorial was created in Emacs 18.59. Left-justified |
ee7bf2ad RM |
1070 | ;; s-expressions are input forms followed by one or more result forms. |
1071 | ;; First we have to start the advice magic: | |
1072 | ;; | |
1073 | ;; (ad-start-advice) | |
1074 | ;; nil | |
1075 | ;; | |
1076 | ;; We start by defining an innocent looking function `foo' that simply | |
1077 | ;; adds 1 to its argument X: | |
1078 | ;; | |
1079 | ;; (defun foo (x) | |
1080 | ;; "Add 1 to X." | |
1081 | ;; (1+ x)) | |
1082 | ;; foo | |
1083 | ;; | |
1084 | ;; (foo 3) | |
1085 | ;; 4 | |
1086 | ;; | |
1087 | ;; @@ Defining a simple piece of advice: | |
1088 | ;; ===================================== | |
1089 | ;; Now let's define the first piece of advice for `foo'. To do that we | |
1090 | ;; use the macro `defadvice' which takes a function name, a list of advice | |
1091 | ;; specifiers and a list of body forms as arguments. The first element of | |
1092 | ;; the advice specifiers is the class of the advice, the second is its name, | |
1093 | ;; the third its position and the rest are some flags. The class of our | |
1094 | ;; first advice is `before', its name is `fg-add2', its position among the | |
1095 | ;; currently defined before advices (none so far) is `first', and the advice | |
1096 | ;; will be `activate'ed immediately. Advice names are global symbols, hence, | |
1097 | ;; the name space conventions used for function names should be applied. All | |
1098 | ;; advice names in this tutorial will be prefixed with `fg' for `Foo Games' | |
1099 | ;; (because everybody has the right to be inconsistent all the function names | |
1100 | ;; used in this tutorial do NOT follow this convention). | |
1101 | ;; | |
1102 | ;; In the body of an advice we can refer to the argument variables of the | |
1103 | ;; original function by name. Here we add 1 to X so the effect of calling | |
1104 | ;; `foo' will be to actually add 2. All of the advice definitions below only | |
1105 | ;; have one body form for simplicity, but there is no restriction to that | |
1106 | ;; extent. Every piece of advice can have a documentation string which will | |
1107 | ;; be combined with the documentation of the original function. | |
1108 | ;; | |
1109 | ;; (defadvice foo (before fg-add2 first activate) | |
1110 | ;; "Add 2 to X." | |
1111 | ;; (setq x (1+ x))) | |
1112 | ;; foo | |
1113 | ;; | |
1114 | ;; (foo 3) | |
1115 | ;; 5 | |
1116 | ;; | |
1117 | ;; @@ Specifying the position of an advice: | |
1118 | ;; ======================================== | |
1119 | ;; Now we define the second before advice which will cancel the effect of | |
1120 | ;; the previous advice. This time we specify the position as 0 which is | |
1121 | ;; equivalent to `first'. A number can be used to specify the zero-based | |
1122 | ;; position of an advice among the list of advices in the same class. This | |
1123 | ;; time we already have one before advice hence the position specification | |
1124 | ;; actually has an effect. So, after the following definition the position | |
1125 | ;; of the previous advice will be 1 even though we specified it with `first' | |
1126 | ;; above, the reason for this is that the position argument is relative to | |
1127 | ;; the currently defined pieces of advice which by now has changed. | |
1128 | ;; | |
1129 | ;; (defadvice foo (before fg-cancel-add2 0 activate) | |
1130 | ;; "Again only add 1 to X." | |
1131 | ;; (setq x (1- x))) | |
1132 | ;; foo | |
1133 | ;; | |
1134 | ;; (foo 3) | |
1135 | ;; 4 | |
1136 | ;; | |
1137 | ;; @@ Redefining a piece of advice: | |
1138 | ;; ================================ | |
1139 | ;; Now we define an advice with the same class and same name but with a | |
1140 | ;; different position. Defining an advice in a class in which an advice with | |
1141 | ;; that name already exists is interpreted as a redefinition of that | |
1142 | ;; particular advice, in which case the position argument will be ignored | |
1143 | ;; and the previous position of the redefined piece of advice is used. | |
1144 | ;; Advice flags can be specified with non-ambiguous initial substrings, hence, | |
1145 | ;; from now on we'll use `act' instead of the verbose `activate'. | |
1146 | ;; | |
1147 | ;; (defadvice foo (before fg-cancel-add2 last act) | |
1148 | ;; "Again only add 1 to X." | |
1149 | ;; (setq x (1- x))) | |
1150 | ;; foo | |
1151 | ;; | |
1152 | ;; @@ Assembly of advised documentation: | |
1153 | ;; ===================================== | |
1154 | ;; The documentation strings of the various pieces of advice are assembled | |
1155 | ;; in order which shows that advice `fg-cancel-add2' is still the first | |
1156 | ;; `before' advice even though we specified position `last' above: | |
1157 | ;; | |
1158 | ;; (documentation 'foo) | |
1159 | ;; "Add 1 to X. | |
1160 | ;; | |
1161 | ;; This function is advised with the following advice(s): | |
1162 | ;; | |
1163 | ;; fg-cancel-add2 (before): | |
1164 | ;; Again only add 1 to X. | |
1165 | ;; | |
1166 | ;; fg-add2 (before): | |
1167 | ;; Add 2 to X." | |
1168 | ;; | |
1169 | ;; @@ Advising interactive behavior: | |
1170 | ;; ================================= | |
1171 | ;; We can make a function interactive (or change its interactive behavior) | |
1172 | ;; by specifying an interactive form in one of the before or around | |
1173 | ;; advices (there could also be body forms in this advice). The particular | |
1174 | ;; definition always assigns 5 as an argument to X which gives us 6 as a | |
1175 | ;; result when we call foo interactively: | |
1176 | ;; | |
1177 | ;; (defadvice foo (before fg-inter last act) | |
1178 | ;; "Use 5 as argument when called interactively." | |
1179 | ;; (interactive (list 5))) | |
1180 | ;; foo | |
1181 | ;; | |
1182 | ;; (call-interactively 'foo) | |
1183 | ;; 6 | |
1184 | ;; | |
1185 | ;; If more than one advice have an interactive declaration, then the one of | |
1186 | ;; the advice with the smallest position will be used (before advices go | |
1187 | ;; before around and after advices), hence, the declaration below does | |
1188 | ;; not have any effect: | |
1189 | ;; | |
1190 | ;; (defadvice foo (before fg-inter2 last act) | |
1191 | ;; (interactive (list 6))) | |
1192 | ;; foo | |
1193 | ;; | |
1194 | ;; (call-interactively 'foo) | |
1195 | ;; 6 | |
1196 | ;; | |
1197 | ;; Let's have a look at what the definition of `foo' looks like now | |
1198 | ;; (indentation added by hand for legibility): | |
1199 | ;; | |
1200 | ;; (symbol-function 'foo) | |
1201 | ;; (lambda (x) | |
1202 | ;; "$ad-doc: foo$" | |
1203 | ;; (interactive (list 5)) | |
1204 | ;; (let (ad-return-value) | |
1205 | ;; (setq x (1- x)) | |
1206 | ;; (setq x (1+ x)) | |
1207 | ;; (setq ad-return-value (ad-Orig-foo x)) | |
1208 | ;; ad-return-value)) | |
1209 | ;; | |
1210 | ;; @@ Around advices: | |
1211 | ;; ================== | |
1212 | ;; Now we'll try some `around' advices. An around advice is a wrapper around | |
1213 | ;; the original definition. It can shadow or establish bindings for the | |
1214 | ;; original definition, and it can look at and manipulate the value returned | |
1215 | ;; by the original function. The position of the special keyword `ad-do-it' | |
1216 | ;; specifies where the code of the original function will be executed. The | |
1217 | ;; keyword can appear multiple times which will result in multiple calls of | |
1218 | ;; the original function in the resulting advised code. Note, that if we don't | |
1219 | ;; specify a position argument (i.e., `first', `last' or a number), then | |
1220 | ;; `first' (or 0) is the default): | |
1221 | ;; | |
1222 | ;; (defadvice foo (around fg-times-2 act) | |
1223 | ;; "First double X." | |
1224 | ;; (let ((x (* x 2))) | |
1225 | ;; ad-do-it)) | |
1226 | ;; foo | |
1227 | ;; | |
1228 | ;; (foo 3) | |
1229 | ;; 7 | |
1230 | ;; | |
1231 | ;; Around advices are assembled like onion skins where the around advice | |
1232 | ;; with position 0 is the outermost skin and the advice at the last position | |
1233 | ;; is the innermost skin which is directly wrapped around the call of the | |
1234 | ;; original definition of the function. Hence, after the next `defadvice' we | |
1235 | ;; will first multiply X by 2 then add 1 and then call the original | |
1236 | ;; definition (i.e., add 1 again): | |
1237 | ;; | |
1238 | ;; (defadvice foo (around fg-add-1 last act) | |
1239 | ;; "Add 1 to X." | |
1240 | ;; (let ((x (1+ x))) | |
1241 | ;; ad-do-it)) | |
1242 | ;; foo | |
1243 | ;; | |
1244 | ;; (foo 3) | |
1245 | ;; 8 | |
1246 | ;; | |
1247 | ;; Again, let's see what the definition of `foo' looks like so far: | |
1248 | ;; | |
1249 | ;; (symbol-function 'foo) | |
1250 | ;; (lambda (x) | |
1251 | ;; "$ad-doc: foo$" | |
1252 | ;; (interactive (list 5)) | |
1253 | ;; (let (ad-return-value) | |
1254 | ;; (setq x (1- x)) | |
1255 | ;; (setq x (1+ x)) | |
1256 | ;; (let ((x (* x 2))) | |
1257 | ;; (let ((x (1+ x))) | |
1258 | ;; (setq ad-return-value (ad-Orig-foo x)))) | |
1259 | ;; ad-return-value)) | |
1260 | ;; | |
1261 | ;; @@ Controlling advice activation: | |
1262 | ;; ================================= | |
1263 | ;; In every `defadvice' so far we have used the flag `activate' to activate | |
1264 | ;; the advice immediately after its definition, and that's what we want in | |
1265 | ;; most cases. However, if we define multiple pieces of advice for a single | |
1266 | ;; function then activating every advice immediately is inefficient. A | |
1267 | ;; better way to do this is to only activate the last defined advice. | |
1268 | ;; For example: | |
1269 | ;; | |
1270 | ;; (defadvice foo (after fg-times-x) | |
1271 | ;; "Multiply the result with X." | |
1272 | ;; (setq ad-return-value (* ad-return-value x))) | |
1273 | ;; foo | |
1274 | ;; | |
1275 | ;; This still yields the same result as before: | |
1276 | ;; (foo 3) | |
1277 | ;; 8 | |
1278 | ;; | |
1279 | ;; Now we define another advice and activate which will also activate the | |
1280 | ;; previous advice `fg-times-x'. Note the use of the special variable | |
1281 | ;; `ad-return-value' in the body of the advice which is set to the result of | |
1282 | ;; the original function. If we change its value then the value returned by | |
1283 | ;; the advised function will be changed accordingly: | |
1284 | ;; | |
1285 | ;; (defadvice foo (after fg-times-x-again act) | |
1286 | ;; "Again multiply the result with X." | |
1287 | ;; (setq ad-return-value (* ad-return-value x))) | |
1288 | ;; foo | |
1289 | ;; | |
1290 | ;; Now the advices have an effect: | |
1291 | ;; | |
1292 | ;; (foo 3) | |
1293 | ;; 72 | |
1294 | ;; | |
1295 | ;; @@ Protecting advice execution: | |
1296 | ;; =============================== | |
1297 | ;; Once in a while we define an advice to perform some cleanup action, | |
1298 | ;; for example: | |
1299 | ;; | |
1300 | ;; (defadvice foo (after fg-cleanup last act) | |
1301 | ;; "Do some cleanup." | |
1302 | ;; (print "Let's clean up now!")) | |
1303 | ;; foo | |
1304 | ;; | |
1305 | ;; However, in case of an error the cleanup won't be performed: | |
1306 | ;; | |
1307 | ;; (condition-case error | |
1308 | ;; (foo t) | |
1309 | ;; (error 'error-in-foo)) | |
1310 | ;; error-in-foo | |
1311 | ;; | |
1312 | ;; To make sure a certain piece of advice gets executed even if some error or | |
1313 | ;; non-local exit occurred in any preceding code, we can protect it by using | |
1314 | ;; the `protect' keyword. (if any of the around advices is protected then the | |
1315 | ;; whole around advice onion will be protected): | |
1316 | ;; | |
1317 | ;; (defadvice foo (after fg-cleanup prot act) | |
1318 | ;; "Do some protected cleanup." | |
1319 | ;; (print "Let's clean up now!")) | |
1320 | ;; foo | |
1321 | ;; | |
1322 | ;; Now the cleanup form will be executed even in case of an error: | |
1323 | ;; | |
1324 | ;; (condition-case error | |
1325 | ;; (foo t) | |
1326 | ;; (error 'error-in-foo)) | |
1327 | ;; "Let's clean up now!" | |
1328 | ;; error-in-foo | |
1329 | ;; | |
1330 | ;; Again, let's see what `foo' looks like: | |
1331 | ;; | |
1332 | ;; (symbol-function 'foo) | |
1333 | ;; (lambda (x) | |
1334 | ;; "$ad-doc: foo$" | |
1335 | ;; (interactive (list 5)) | |
1336 | ;; (let (ad-return-value) | |
1337 | ;; (unwind-protect | |
1338 | ;; (progn (setq x (1- x)) | |
1339 | ;; (setq x (1+ x)) | |
1340 | ;; (let ((x (* x 2))) | |
1341 | ;; (let ((x (1+ x))) | |
1342 | ;; (setq ad-return-value (ad-Orig-foo x)))) | |
1343 | ;; (setq ad-return-value (* ad-return-value x)) | |
1344 | ;; (setq ad-return-value (* ad-return-value x))) | |
1345 | ;; (print "Let's clean up now!")) | |
1346 | ;; ad-return-value)) | |
1347 | ;; | |
1348 | ;; @@ Compilation of advised definitions: | |
1349 | ;; ====================================== | |
1350 | ;; Finally, we can specify the `compile' keyword in a `defadvice' to say | |
1351 | ;; that we want the resulting advised function to be byte-compiled | |
1352 | ;; (`compile' will be ignored unless we also specified `activate'): | |
1353 | ;; | |
1354 | ;; (defadvice foo (after fg-cleanup prot act comp) | |
1355 | ;; "Do some protected cleanup." | |
1356 | ;; (print "Let's clean up now!")) | |
1357 | ;; foo | |
1358 | ;; | |
1359 | ;; Now `foo' is byte-compiled: | |
1360 | ;; | |
1361 | ;; (symbol-function 'foo) | |
1362 | ;; (lambda (x) | |
1363 | ;; "$ad-doc: foo$" | |
1364 | ;; (interactive (byte-code "....." [5] 1)) | |
1365 | ;; (byte-code "....." [ad-return-value x nil ((byte-code "....." [print "Let's clean up now!"] 2)) * 2 ad-Orig-foo] 6)) | |
1366 | ;; | |
1367 | ;; (foo 3) | |
1368 | ;; "Let's clean up now!" | |
1369 | ;; 72 | |
1370 | ;; | |
1371 | ;; @@ Enabling and disabling pieces of advice: | |
1372 | ;; =========================================== | |
1373 | ;; Once in a while it is desirable to temporarily disable a piece of advice | |
1374 | ;; so that it won't be considered during activation, for example, if two | |
1375 | ;; different packages advise the same function and one wants to temporarily | |
1376 | ;; neutralize the effect of the advice of one of the packages. | |
1377 | ;; | |
1378 | ;; The following disables the after advice `fg-times-x' in the function `foo'. | |
1379 | ;; All that does is to change a flag for this particular advice. All the | |
1380 | ;; other information defining it will be left unchanged (e.g., its relative | |
1381 | ;; position in this advice class, etc.). | |
1382 | ;; | |
1383 | ;; (ad-disable-advice 'foo 'after 'fg-times-x) | |
1384 | ;; nil | |
1385 | ;; | |
1386 | ;; For this to have an effect we have to activate `foo': | |
1387 | ;; | |
1388 | ;; (ad-activate 'foo) | |
1389 | ;; foo | |
1390 | ;; | |
1391 | ;; (foo 3) | |
1392 | ;; "Let's clean up now!" | |
1393 | ;; 24 | |
1394 | ;; | |
1395 | ;; If we want to disable all multiplication advices in `foo' we can use a | |
1396 | ;; regular expression that matches the names of such advices. Actually, any | |
1397 | ;; advice name that contains a match for the regular expression will be | |
1398 | ;; called a match. A special advice class `any' can be used to consider | |
1399 | ;; all advice classes: | |
1400 | ;; | |
1401 | ;; (ad-disable-advice 'foo 'any "^fg-.*times") | |
1402 | ;; nil | |
1403 | ;; | |
1404 | ;; (ad-activate 'foo) | |
1405 | ;; foo | |
1406 | ;; | |
1407 | ;; (foo 3) | |
1408 | ;; "Let's clean up now!" | |
1409 | ;; 5 | |
1410 | ;; | |
1411 | ;; To enable the disabled advice we could use either `ad-enable-advice' | |
1412 | ;; similar to `ad-disable-advice', or as an alternative `ad-enable-regexp' | |
1413 | ;; which will enable matching advices in ALL currently advised functions. | |
1414 | ;; Hence, this can be used to dis/enable advices made by a particular | |
1415 | ;; package to a set of functions as long as that package obeys standard | |
1416 | ;; advice name conventions. We prefixed all advice names with `fg-', hence | |
1417 | ;; the following will do the trick (`ad-enable-regexp' returns the number | |
1418 | ;; of matched advices): | |
1419 | ;; | |
1420 | ;; (ad-enable-regexp "^fg-") | |
1421 | ;; 9 | |
1422 | ;; | |
1423 | ;; The following will activate all currently active advised functions that | |
1424 | ;; contain some advice matched by the regular expression. This is a save | |
1425 | ;; way to update the activation of advised functions whose advice changed | |
1426 | ;; in some way or other without accidentally also activating currently | |
1427 | ;; deactivated functions: | |
1428 | ;; | |
1429 | ;; (ad-update-regexp "^fg-") | |
1430 | ;; nil | |
1431 | ;; | |
1432 | ;; (foo 3) | |
1433 | ;; "Let's clean up now!" | |
1434 | ;; 72 | |
1435 | ;; | |
1436 | ;; Another use for the dis/enablement mechanism is to define a piece of advice | |
1437 | ;; and keep it "dormant" until a particular condition is satisfied, i.e., until | |
1438 | ;; then the advice will not be used during activation. The `disable' flag lets | |
1439 | ;; one do that with `defadvice': | |
1440 | ;; | |
1441 | ;; (defadvice foo (before fg-1-more dis) | |
1442 | ;; "Add yet 1 more." | |
1443 | ;; (setq x (1+ x))) | |
1444 | ;; foo | |
1445 | ;; | |
1446 | ;; (ad-activate 'foo) | |
1447 | ;; foo | |
1448 | ;; | |
1449 | ;; (foo 3) | |
1450 | ;; "Let's clean up now!" | |
1451 | ;; 72 | |
1452 | ;; | |
1453 | ;; (ad-enable-advice 'foo 'before 'fg-1-more) | |
1454 | ;; nil | |
1455 | ;; | |
1456 | ;; (ad-activate 'foo) | |
1457 | ;; foo | |
1458 | ;; | |
1459 | ;; (foo 3) | |
1460 | ;; "Let's clean up now!" | |
1461 | ;; 160 | |
1462 | ;; | |
1463 | ;; @@ Caching: | |
1464 | ;; =========== | |
1465 | ;; Advised definitions get cached to allow efficient activation/deactivation | |
1466 | ;; without having to reconstruct them if nothing in the advice-info of a | |
1467 | ;; function has changed. The following idiom can be used to temporarily | |
1468 | ;; deactivate functions that have a piece of advice defined by a certain | |
1469 | ;; package (we save the old definition to check out caching): | |
1470 | ;; | |
1471 | ;; (setq old-definition (symbol-function 'foo)) | |
1472 | ;; (lambda (x) ....) | |
1473 | ;; | |
1474 | ;; (ad-deactivate-regexp "^fg-") | |
1475 | ;; nil | |
1476 | ;; | |
1477 | ;; (foo 3) | |
1478 | ;; 4 | |
1479 | ;; | |
1480 | ;; (ad-activate-regexp "^fg-") | |
1481 | ;; nil | |
1482 | ;; | |
1483 | ;; (eq old-definition (symbol-function 'foo)) | |
1484 | ;; t | |
1485 | ;; | |
1486 | ;; (foo 3) | |
1487 | ;; "Let's clean up now!" | |
1488 | ;; 160 | |
1489 | ;; | |
1490 | ;; @@ Forward advice: | |
1491 | ;; ================== | |
1492 | ;; To enable automatic activation of forward advice we first have to set | |
1493 | ;; `ad-activate-on-definition' to t and restart advice: | |
1494 | ;; | |
1495 | ;; (setq ad-activate-on-definition t) | |
1496 | ;; t | |
1497 | ;; | |
1498 | ;; (ad-start-advice) | |
1499 | ;; (ad-activate-defined-function) | |
1500 | ;; | |
1501 | ;; Let's define a piece of advice for an undefined function: | |
1502 | ;; | |
1503 | ;; (defadvice bar (before fg-sub-1-more act) | |
1504 | ;; "Subtract one more from X." | |
1505 | ;; (setq x (1- x))) | |
1506 | ;; bar | |
1507 | ;; | |
1508 | ;; `bar' is not yet defined: | |
1509 | ;; (fboundp 'bar) | |
1510 | ;; nil | |
1511 | ;; | |
1512 | ;; Now we define it and the forward advice will get activated (only because | |
1513 | ;; `ad-activate-on-definition' was t when we started advice above with | |
1514 | ;; `ad-start-advice'): | |
1515 | ;; | |
1516 | ;; (defun bar (x) | |
1517 | ;; "Subtract 1 from X." | |
1518 | ;; (1- x)) | |
1519 | ;; bar | |
1520 | ;; | |
1521 | ;; (bar 4) | |
1522 | ;; 2 | |
1523 | ;; | |
1524 | ;; Redefinition will activate any available advice if the value of | |
1525 | ;; `ad-redefinition-action' is either `warn', `accept' or `discard': | |
1526 | ;; | |
1527 | ;; (defun bar (x) | |
1528 | ;; "Subtract 2 from X." | |
1529 | ;; (- x 2)) | |
1530 | ;; bar | |
1531 | ;; | |
1532 | ;; (bar 4) | |
1533 | ;; 1 | |
1534 | ;; | |
1535 | ;; @@ Preactivation: | |
1536 | ;; ================= | |
1537 | ;; Constructing advised definitions is moderately expensive, hence, it is | |
1538 | ;; desirable to have a way to construct them at byte-compile time. | |
1539 | ;; Preactivation is a mechanism that allows one to do that. | |
1540 | ;; | |
1541 | ;; (defun fie (x) | |
1542 | ;; "Multiply X by 2." | |
1543 | ;; (* x 2)) | |
1544 | ;; fie | |
1545 | ;; | |
1546 | ;; (defadvice fie (before fg-times-4 preact) | |
1547 | ;; "Multiply X by 4." | |
1548 | ;; (setq x (* x 2))) | |
1549 | ;; fie | |
1550 | ;; | |
1551 | ;; This advice did not affect `fie'... | |
1552 | ;; | |
1553 | ;; (fie 2) | |
1554 | ;; 4 | |
1555 | ;; | |
1556 | ;; ...but it constructed a cached definition that will be used once `fie' gets | |
1557 | ;; activated as long as its current advice state is the same as it was during | |
1558 | ;; preactivation: | |
1559 | ;; | |
1560 | ;; (setq cached-definition (ad-get-cache-definition 'fie)) | |
1561 | ;; (lambda (x) ....) | |
1562 | ;; | |
1563 | ;; (ad-activate 'fie) | |
1564 | ;; fie | |
1565 | ;; | |
1566 | ;; (eq cached-definition (symbol-function 'fie)) | |
1567 | ;; t | |
1568 | ;; | |
1569 | ;; (fie 2) | |
1570 | ;; 8 | |
1571 | ;; | |
1572 | ;; If you put a preactivating `defadvice' into an elisp file that gets byte- | |
1573 | ;; compiled then the constructed advised definition will get compiled by | |
1574 | ;; the byte-compiler. For that to occur in a v18 emacs you have to put the | |
1575 | ;; `defadvice' inside a `defun' because the v18 compiler does not compile | |
1576 | ;; top-level forms other than `defun' or `defmacro', for example, | |
1577 | ;; | |
1578 | ;; (defun fg-defadvice-fum () | |
1579 | ;; (defadvice fum (before fg-times-4 preact act) | |
1580 | ;; "Multiply X by 4." | |
1581 | ;; (setq x (* x 2)))) | |
1582 | ;; fg-defadvice-fum | |
1583 | ;; | |
1584 | ;; So far, no `defadvice' for `fum' got executed, but when we compile | |
1585 | ;; `fg-defadvice-fum' the `defadvice' will be expanded by the byte compiler. | |
1586 | ;; In order for preactivation to be effective we have to have a proper | |
1587 | ;; definition of `fum' around at preactivation time, hence, we define it now: | |
1588 | ;; | |
1589 | ;; (defun fum (x) | |
1590 | ;; "Multiply X by 2." | |
1591 | ;; (* x 2)) | |
1592 | ;; fum | |
1593 | ;; | |
1594 | ;; Now we compile the defining function which will construct an advised | |
1595 | ;; definition during expansion of the `defadvice', compile it and store it | |
1596 | ;; as part of the compiled `fg-defadvice-fum': | |
1597 | ;; | |
1598 | ;; (ad-compile-function 'fg-defadvice-fum) | |
1599 | ;; (lambda nil (byte-code ...)) | |
1600 | ;; | |
1601 | ;; `fum' is still completely unaffected: | |
1602 | ;; | |
1603 | ;; (fum 2) | |
1604 | ;; 4 | |
1605 | ;; | |
1606 | ;; (ad-get-advice-info 'fum) | |
1607 | ;; nil | |
1608 | ;; | |
1609 | ;; (fg-defadvice-fum) | |
1610 | ;; fum | |
1611 | ;; | |
1612 | ;; Now the advised version of `fum' is compiled because the compiled definition | |
1613 | ;; constructed during preactivation was used, even though we did not specify | |
1614 | ;; the `compile' flag: | |
1615 | ;; | |
1616 | ;; (symbol-function 'fum) | |
1617 | ;; (lambda (x) | |
1618 | ;; "$ad-doc: fum$" | |
1619 | ;; (byte-code "....." [ad-return-value x nil * 2 ad-Orig-fum] 4)) | |
1620 | ;; | |
1621 | ;; (fum 2) | |
1622 | ;; 8 | |
1623 | ;; | |
1624 | ;; A preactivated definition will only be used if it matches the current | |
1625 | ;; function definition and advice information. If it does not match it | |
1626 | ;; will simply be discarded and a new advised definition will be constructed | |
1627 | ;; from scratch. For example, let's first remove all advice-info for `fum': | |
1628 | ;; | |
1629 | ;; (ad-unadvise 'fum) | |
1630 | ;; (("fie") ("bar") ("foo") ...) | |
1631 | ;; | |
1632 | ;; And now define a new piece of advice: | |
1633 | ;; | |
1634 | ;; (defadvice fum (before fg-interactive act) | |
1635 | ;; "Make fum interactive." | |
1636 | ;; (interactive "nEnter x: ")) | |
1637 | ;; fum | |
1638 | ;; | |
1639 | ;; When we now try to use a preactivation it will not be used because the | |
1640 | ;; current advice state is different from the one at preactivation time. This | |
1641 | ;; is no tragedy, everything will work as expected just not as efficient, | |
1642 | ;; because a new advised definition has to be constructed from scratch: | |
1643 | ;; | |
1644 | ;; (fg-defadvice-fum) | |
1645 | ;; fum | |
1646 | ;; | |
1647 | ;; A new uncompiled advised definition got constructed: | |
1648 | ;; | |
1649 | ;; (ad-compiled-p (symbol-function 'fum)) | |
1650 | ;; nil | |
1651 | ;; | |
1652 | ;; (fum 2) | |
1653 | ;; 8 | |
1654 | ;; | |
1655 | ;; MORAL: To get all the efficiency out of preactivation the function | |
1656 | ;; definition and advice state at preactivation time must be the same as the | |
1657 | ;; state at activation time. Preactivation does work with forward advice, all | |
1658 | ;; that's necessary is that the definition of the forward advised function is | |
1659 | ;; available when the `defadvice' with the preactivation gets compiled. | |
1660 | ;; | |
1661 | ;; @@ Portable argument access: | |
1662 | ;; ============================ | |
1663 | ;; So far, we always used the actual argument variable names to access an | |
1664 | ;; argument in a piece of advice. For many advice applications this is | |
1665 | ;; perfectly ok and keeps advices simple. However, it decreases portability | |
1666 | ;; of advices because it assumes specific argument variable names. For example, | |
1667 | ;; if one advises a subr such as `eval-region' which then gets redefined by | |
1668 | ;; some package (e.g., edebug) into a function with different argument names, | |
1669 | ;; then a piece of advice written for `eval-region' that was written with | |
1670 | ;; the subr arguments in mind will break. Similar situations arise when one | |
1671 | ;; switches between major Emacs versions, e.g., certain subrs in v18 are | |
1672 | ;; functions in v19 and vice versa. Also, in v19s subr argument lists | |
1673 | ;; are available and will be used, while they are not available in v18. | |
1674 | ;; | |
1675 | ;; Argument access text macros allow one to access arguments of an advised | |
1676 | ;; function in a portable way without having to worry about all these | |
1677 | ;; possibilities. These macros will be translated into the proper access forms | |
1678 | ;; at activation time, hence, argument access will be as efficient as if | |
1679 | ;; the arguments had been used directly in the definition of the advice. | |
1680 | ;; | |
1681 | ;; (defun fuu (x y z) | |
1682 | ;; "Add 3 numbers." | |
1683 | ;; (+ x y z)) | |
1684 | ;; fuu | |
1685 | ;; | |
1686 | ;; (fuu 1 1 1) | |
1687 | ;; 3 | |
1688 | ;; | |
1689 | ;; Argument access macros specify actual arguments at a certain position. | |
1690 | ;; Position 0 access the first actual argument, position 1 the second etc. | |
1691 | ;; For example, the following advice adds 1 to each of the 3 arguments: | |
1692 | ;; | |
1693 | ;; (defadvice fuu (before fg-add-1-to-all act) | |
1694 | ;; "Adds 1 to all arguments." | |
1695 | ;; (ad-set-arg 0 (1+ (ad-get-arg 0))) | |
1696 | ;; (ad-set-arg 1 (1+ (ad-get-arg 1))) | |
1697 | ;; (ad-set-arg 2 (1+ (ad-get-arg 2)))) | |
1698 | ;; fuu | |
1699 | ;; | |
1700 | ;; (fuu 1 1 1) | |
1701 | ;; 6 | |
1702 | ;; | |
1703 | ;; Now suppose somebody redefines `fuu' with a rest argument. Our advice | |
1704 | ;; will still work because we used access macros (note, that automatic | |
1705 | ;; advice activation is still in effect, hence, the redefinition of `fuu' | |
1706 | ;; will automatically activate all its advice): | |
1707 | ;; | |
1708 | ;; (defun fuu (&rest numbers) | |
1709 | ;; "Add NUMBERS." | |
1710 | ;; (apply '+ numbers)) | |
1711 | ;; fuu | |
1712 | ;; | |
1713 | ;; (fuu 1 1 1) | |
1714 | ;; 6 | |
1715 | ;; | |
1716 | ;; (fuu 1 1 1 1 1 1) | |
1717 | ;; 9 | |
1718 | ;; | |
1719 | ;; What's important to notice is that argument access macros access actual | |
1720 | ;; arguments regardless of how they got distributed onto argument variables. | |
1721 | ;; In Emacs Lisp the semantics of an actual argument is determined purely | |
1722 | ;; by position, hence, as long as nobody changes the semantics of what a | |
1723 | ;; certain actual argument at a certain position means the access macros | |
1724 | ;; will do the right thing. | |
1725 | ;; | |
1726 | ;; Because of &rest arguments we need a second kind of access macro that | |
1727 | ;; can access all actual arguments starting from a certain position: | |
1728 | ;; | |
1729 | ;; (defadvice fuu (before fg-print-args act) | |
1730 | ;; "Print all arguments." | |
1731 | ;; (print (ad-get-args 0))) | |
1732 | ;; fuu | |
1733 | ;; | |
1734 | ;; (fuu 1 2 3 4 5) | |
1735 | ;; (1 2 3 4 5) | |
1736 | ;; 18 | |
1737 | ;; | |
1738 | ;; (defadvice fuu (before fg-set-args act) | |
1739 | ;; "Swaps 2nd and 3rd arg and discards all the rest." | |
1740 | ;; (ad-set-args 1 (list (ad-get-arg 2) (ad-get-arg 1)))) | |
1741 | ;; fuu | |
1742 | ;; | |
1743 | ;; (fuu 1 2 3 4 4 4 4 4 4) | |
1744 | ;; (1 3 2) | |
1745 | ;; 9 | |
1746 | ;; | |
1747 | ;; (defun fuu (x y z) | |
1748 | ;; "Add 3 numbers." | |
1749 | ;; (+ x y z)) | |
1750 | ;; | |
1751 | ;; (fuu 1 2 3) | |
1752 | ;; (1 3 2) | |
1753 | ;; 9 | |
1754 | ;; | |
1755 | ;; @@ Defining the argument list of an advised function: | |
1756 | ;; ===================================================== | |
1757 | ;; Once in a while it might be desirable to advise a function and additionally | |
1758 | ;; give it an extra argument that controls the advised code, for example, one | |
1759 | ;; might want to make an interactive function sensitive to a prefix argument. | |
1760 | ;; For such cases `defadvice' allows the specification of an argument list | |
1761 | ;; for the advised function. Similar to the redefinition of interactive | |
1762 | ;; behavior, the first argument list specification found in the list of before/ | |
1763 | ;; around/after advices will be used. Of course, the specified argument list | |
1764 | ;; should be downward compatible with the original argument list, otherwise | |
1765 | ;; functions that call the advised function with the original argument list | |
1766 | ;; in mind will break. | |
1767 | ;; | |
1768 | ;; (defun fii (x) | |
1769 | ;; "Add 1 to X." | |
1770 | ;; (1+ x)) | |
1771 | ;; fii | |
1772 | ;; | |
1773 | ;; Now we advise `fii' to use an optional second argument that controls the | |
1774 | ;; amount of incrementation. A list following the (optional) position | |
1775 | ;; argument of the advice will be interpreted as an argument list | |
1776 | ;; specification. This means you cannot specify an empty argument list, and | |
1777 | ;; why would you want to anyway? | |
1778 | ;; | |
1779 | ;; (defadvice fii (before fg-inc-x (x &optional incr) act) | |
1780 | ;; "Increment X by INCR (default is 1)." | |
1781 | ;; (setq x (+ x (1- (or incr 1))))) | |
1782 | ;; fii | |
1783 | ;; | |
1784 | ;; (fii 3) | |
1785 | ;; 4 | |
1786 | ;; | |
1787 | ;; (fii 3 2) | |
1788 | ;; 5 | |
1789 | ;; | |
1790 | ;; @@ Specifying argument lists of subrs: | |
1791 | ;; ====================================== | |
1792 | ;; The argument lists of subrs cannot be determined directly from Lisp. | |
6e2f6f45 | 1793 | ;; This means that Advice has to use `(&rest ad-subr-args)' as the |
ee7bf2ad RM |
1794 | ;; argument list of the advised subr which is not very efficient. In Lemacs |
1795 | ;; subr argument lists can be determined from their documentation string, in | |
6e2f6f45 | 1796 | ;; Emacs-19 this is the case for some but not all subrs. To accommodate |
ee7bf2ad | 1797 | ;; for the cases where the argument lists cannot be determined (e.g., in a |
6e2f6f45 | 1798 | ;; v18 Emacs) Advice comes with a specification mechanism that allows the |
ee7bf2ad RM |
1799 | ;; advice programmer to tell advice what the argument list of a certain subr |
1800 | ;; really is. | |
1801 | ;; | |
1802 | ;; In a v18 Emacs the following will return the &rest idiom: | |
1803 | ;; | |
1804 | ;; (ad-arglist (symbol-function 'car)) | |
1805 | ;; (&rest ad-subr-args) | |
1806 | ;; | |
1807 | ;; To tell advice what the argument list of `car' really is we | |
1808 | ;; can do the following: | |
1809 | ;; | |
1810 | ;; (ad-define-subr-args 'car '(list)) | |
1811 | ;; ((list)) | |
1812 | ;; | |
1813 | ;; Now `ad-arglist' will return the proper argument list (this method is | |
1814 | ;; actually used by advice itself for the advised definition of `fset'): | |
1815 | ;; | |
1816 | ;; (ad-arglist (symbol-function 'car)) | |
1817 | ;; (list) | |
1818 | ;; | |
1819 | ;; The defined argument list will be stored on the property list of the | |
1820 | ;; subr name symbol. When advice looks for a subr argument list it first | |
1821 | ;; checks for a definition on the property list, if that fails it tries | |
1822 | ;; to infer it from the documentation string and caches it on the property | |
1823 | ;; list if it was successful, otherwise `(&rest ad-subr-args)' will be used. | |
1824 | ;; | |
1825 | ;; @@ Advising interactive subrs: | |
1826 | ;; ============================== | |
1827 | ;; For the most part there is no difference between advising functions and | |
1828 | ;; advising subrs. There is one situation though where one might have to write | |
1829 | ;; slightly different advice code for subrs than for functions. This case | |
1830 | ;; arises when one wants to access subr arguments in a before/around advice | |
1831 | ;; when the arguments were determined by an interactive call to the subr. | |
1832 | ;; Advice cannot determine what `interactive' form determines the interactive | |
1833 | ;; behavior of the subr, hence, when it calls the original definition in an | |
1834 | ;; interactive subr invocation it has to use `call-interactively' to generate | |
1835 | ;; the proper interactive behavior. Thus up to that call the arguments of the | |
1836 | ;; interactive subr will be nil. For example, the following advice for | |
1837 | ;; `kill-buffer' will not work in an interactive invocation... | |
1838 | ;; | |
1839 | ;; (defadvice kill-buffer (before fg-kill-buffer-hook first act preact comp) | |
1840 | ;; (my-before-kill-buffer-hook (ad-get-arg 0))) | |
1841 | ;; kill-buffer | |
1842 | ;; | |
1843 | ;; ...because the buffer argument will be nil in that case. The way out of | |
1844 | ;; this dilemma is to provide an `interactive' specification that mirrors | |
1845 | ;; the interactive behavior of the unadvised subr, for example, the following | |
1846 | ;; will do the right thing even when `kill-buffer' is called interactively: | |
1847 | ;; | |
1848 | ;; (defadvice kill-buffer (before fg-kill-buffer-hook first act preact comp) | |
1849 | ;; (interactive "bKill buffer: ") | |
1850 | ;; (my-before-kill-buffer-hook (ad-get-arg 0))) | |
1851 | ;; kill-buffer | |
1852 | ;; | |
1853 | ;; @@ Advising macros: | |
1854 | ;; =================== | |
1855 | ;; Advising macros is slightly different because there are two significant | |
1856 | ;; time points in the invocation of a macro: Expansion and evaluation time. | |
1857 | ;; For an advised macro instead of evaluating the original definition we | |
1858 | ;; use `macroexpand', that is, changing argument values and binding | |
1859 | ;; environments by pieces of advice has an affect during macro expansion | |
1860 | ;; but not necessarily during evaluation. In particular, any side effects | |
1861 | ;; of pieces of advice will occur during macro expansion. To also affect | |
1862 | ;; the behavior during evaluation time one has to change the value of | |
1863 | ;; `ad-return-value' in a piece of after advice. For example: | |
1864 | ;; | |
1865 | ;; (defmacro foom (x) | |
1866 | ;; (` (list (, x)))) | |
1867 | ;; foom | |
1868 | ;; | |
1869 | ;; (foom '(a)) | |
1870 | ;; ((a)) | |
1871 | ;; | |
1872 | ;; (defadvice foom (before fg-print-x act) | |
1873 | ;; "Print the value of X." | |
1874 | ;; (print x)) | |
1875 | ;; foom | |
1876 | ;; | |
1877 | ;; The following works as expected because evaluation immediately follows | |
1878 | ;; macro expansion: | |
1879 | ;; | |
1880 | ;; (foom '(a)) | |
1881 | ;; (quote (a)) | |
1882 | ;; ((a)) | |
1883 | ;; | |
1884 | ;; However, the printing happens during expansion (or byte-compile) time: | |
1885 | ;; | |
1886 | ;; (macroexpand '(foom '(a))) | |
1887 | ;; (quote (a)) | |
1888 | ;; (list (quote (a))) | |
1889 | ;; | |
1890 | ;; If we want it to happen during evaluation time we have to do the | |
1891 | ;; following (first remove the old advice): | |
1892 | ;; | |
1893 | ;; (ad-remove-advice 'foom 'before 'fg-print-x) | |
1894 | ;; nil | |
1895 | ;; | |
1896 | ;; (defadvice foom (after fg-print-x act) | |
1897 | ;; "Print the value of X." | |
1898 | ;; (setq ad-return-value | |
1899 | ;; (` (progn (print (, x)) | |
1900 | ;; (, ad-return-value))))) | |
1901 | ;; foom | |
1902 | ;; | |
1903 | ;; (macroexpand '(foom '(a))) | |
1904 | ;; (progn (print (quote (a))) (list (quote (a)))) | |
1905 | ;; | |
1906 | ;; (foom '(a)) | |
1907 | ;; (a) | |
1908 | ;; ((a)) | |
1909 | ;; | |
1910 | ;; While this method might seem somewhat cumbersome, it is very general | |
1911 | ;; because it allows one to influence macro expansion as well as evaluation. | |
1912 | ;; In general, advising macros should be a rather rare activity anyway, in | |
1913 | ;; particular, because compile-time macro expansion takes away a lot of the | |
1914 | ;; flexibility and effectiveness of the advice mechanism. Macros that were | |
1915 | ;; compile-time expanded before the advice was activated will of course never | |
1916 | ;; exhibit the advised behavior. | |
1917 | ;; | |
1918 | ;; @@ Advising special forms: | |
1919 | ;; ========================== | |
1920 | ;; Now for something that should be even more rare than advising macros: | |
1921 | ;; Advising special forms. Because special forms are irregular in their | |
1922 | ;; argument evaluation behavior (e.g., `setq' evaluates the second but not | |
1923 | ;; the first argument) they have to be advised into macros. A dangerous | |
1924 | ;; consequence of this is that the byte-compiler will not recognize them | |
1925 | ;; as special forms anymore (well, in most cases) and use their expansion | |
1926 | ;; rather than the proper byte-code. Also, because the original definition | |
1927 | ;; of a special form cannot be `funcall'ed, `eval' has to be used instead | |
1928 | ;; which is less efficient. | |
1929 | ;; | |
1930 | ;; MORAL: Do not advise special forms unless you are completely sure about | |
1931 | ;; what you are doing (some of the forward advice behavior is | |
1932 | ;; implemented via advice of the special forms `defun' and `defmacro'). | |
1933 | ;; As a safety measure one should always do `ad-deactivate-all' before | |
1934 | ;; one byte-compiles a file to avoid any interference of advised | |
1935 | ;; special forms. | |
1936 | ;; | |
1937 | ;; Apart from the safety concerns advising special forms is not any different | |
1938 | ;; from advising plain functions or subrs. | |
1939 | ||
1940 | ||
ee7bf2ad RM |
1941 | ;;; Code: |
1942 | ||
1943 | ;; @ Advice implementation: | |
1944 | ;; ======================== | |
1945 | ||
1946 | ;; @@ Compilation idiosyncrasies: | |
1947 | ;; ============================== | |
1948 | ||
1949 | ;; `defadvice' expansion needs quite a few advice functions and variables, | |
6e2f6f45 | 1950 | ;; hence, I need to preload the file before it can be compiled. To avoid |
ee7bf2ad RM |
1951 | ;; interference of bogus compiled files I always preload the source file: |
1952 | (provide 'advice-preload) | |
1953 | ;; During a normal load this is a noop: | |
1954 | (require 'advice-preload "advice.el") | |
1955 | ||
ee7bf2ad RM |
1956 | |
1957 | ;; @@ Variable definitions: | |
1958 | ;; ======================== | |
1959 | ||
f643a891 | 1960 | (defconst ad-version "2.11") |
ee7bf2ad | 1961 | |
f643a891 RS |
1962 | (defmacro ad-lemacs-p () |
1963 | ;;Expands into Non-nil constant if we run Lucid's version of Emacs-19. | |
1964 | ;;Unselected conditional code will be optimized away during compilation. | |
1965 | (string-match "Lucid" emacs-version)) | |
ee7bf2ad RM |
1966 | |
1967 | ;;;###autoload | |
de0748e0 | 1968 | (defvar ad-start-advice-on-load t |
6e2f6f45 | 1969 | "*Non-nil will start Advice magic when this file gets loaded. |
ee7bf2ad RM |
1970 | Also see function `ad-start-advice'.") |
1971 | ||
1972 | ;;;###autoload | |
1973 | (defvar ad-activate-on-definition nil | |
6e2f6f45 | 1974 | "*Non-nil means automatic advice activation at function definition. |
ee7bf2ad RM |
1975 | Set this variable to t if you want to enable forward advice (which is |
1976 | automatic advice activation of a previously undefined function at the | |
6e2f6f45 | 1977 | point the function gets defined/loaded/autoloaded). The value of this |
ee7bf2ad | 1978 | variable takes effect only during the execution of `ad-start-advice'. |
6e2f6f45 | 1979 | If non-nil it will enable definition hooks regardless of the value |
ee7bf2ad RM |
1980 | of `ad-enable-definition-hooks'.") |
1981 | ||
1982 | ;;;###autoload | |
1983 | (defvar ad-redefinition-action 'warn | |
1984 | "*Defines what to do with redefinitions during de/activation. | |
1985 | Redefinition occurs if a previously activated function that already has an | |
1986 | original definition associated with it gets redefined and then de/activated. | |
1987 | In such a case we can either accept the current definition as the new | |
1988 | original definition, discard the current definition and replace it with the | |
6e2f6f45 RS |
1989 | old original, or keep it and raise an error. The values `accept', `discard', |
1990 | `error' or `warn' govern what will be done. `warn' is just like `accept' but | |
1991 | it additionally prints a warning message. All other values will be | |
ee7bf2ad RM |
1992 | interpreted as `error'.") |
1993 | ||
1994 | ;;;###autoload | |
1995 | (defvar ad-definition-hooks nil | |
1996 | "*List of hooks to be run after a function definition. | |
1997 | The variable `ad-defined-function' will be bound to the name of | |
1998 | the currently defined function when the hook function is run.") | |
1999 | ||
2000 | ;;;###autoload | |
2001 | (defvar ad-enable-definition-hooks nil | |
6e2f6f45 | 2002 | "*Non-nil will enable hooks to be run on function definition. |
ee7bf2ad | 2003 | Setting this variable is a noop unless the value of |
6e2f6f45 | 2004 | `ad-activate-on-definition' (which see) is nil.") |
ee7bf2ad RM |
2005 | |
2006 | ||
2007 | ;; @@ Some utilities: | |
2008 | ;; ================== | |
2009 | ||
2010 | ;; We don't want the local arguments to interfere with anything | |
2011 | ;; referenced in the supplied functions => the cryptic casing: | |
2012 | (defun ad-substitute-tree (sUbTrEe-TeSt fUnCtIoN tReE) | |
2013 | ;;"Substitutes qualifying subTREEs with result of FUNCTION(subTREE). | |
2014 | ;;Only proper subtrees are considered, for example, if TREE is (1 (2 (3)) 4) | |
2015 | ;;then the subtrees will be 1 (2 (3)) 2 (3) 3 4, dotted structures are | |
6e2f6f45 RS |
2016 | ;;allowed too. Once a qualifying subtree has been found its subtrees will |
2017 | ;;not be considered anymore. (ad-substitute-tree 'atom 'identity tree) | |
ee7bf2ad RM |
2018 | ;;generates a copy of TREE." |
2019 | (cond ((consp tReE) | |
2020 | (cons (if (funcall sUbTrEe-TeSt (car tReE)) | |
2021 | (funcall fUnCtIoN (car tReE)) | |
2022 | (if (consp (car tReE)) | |
2023 | (ad-substitute-tree sUbTrEe-TeSt fUnCtIoN (car tReE)) | |
2024 | (car tReE))) | |
2025 | (ad-substitute-tree sUbTrEe-TeSt fUnCtIoN (cdr tReE)))) | |
2026 | ((funcall sUbTrEe-TeSt tReE) | |
2027 | (funcall fUnCtIoN tReE)) | |
2028 | (t tReE))) | |
2029 | ||
2030 | ;; this is just faster than `ad-substitute-tree': | |
2031 | (defun ad-copy-tree (tree) | |
2032 | ;;"Returns a copy of the list structure of TREE." | |
2033 | (cond ((consp tree) | |
2034 | (cons (ad-copy-tree (car tree)) | |
2035 | (ad-copy-tree (cdr tree)))) | |
2036 | (t tree))) | |
2037 | ||
2038 | (defmacro ad-dolist (varform &rest body) | |
2039 | "A Common-Lisp-style dolist iterator with the following syntax: | |
2040 | ||
6e2f6f45 RS |
2041 | (ad-dolist (VAR INIT-FORM [RESULT-FORM]) |
2042 | BODY-FORM...) | |
ee7bf2ad | 2043 | |
6e2f6f45 RS |
2044 | which will iterate over the list yielded by INIT-FORM binding VAR to the |
2045 | current head at every iteration. If RESULT-FORM is supplied its value will | |
2046 | be returned at the end of the iteration, nil otherwise. The iteration can be | |
2047 | exited prematurely with `(ad-do-return [VALUE])'." | |
ee7bf2ad RM |
2048 | (let ((expansion |
2049 | (` (let ((ad-dO-vAr (, (car (cdr varform)))) | |
2050 | (, (car varform))) | |
2051 | (while ad-dO-vAr | |
2052 | (setq (, (car varform)) (car ad-dO-vAr)) | |
2053 | (,@ body) | |
2054 | ;;work around a backquote bug: | |
2055 | ;;(` ((,@ '(foo)) (bar))) => (append '(foo) '(((bar)))) wrong | |
2056 | ;;(` ((,@ '(foo)) (, '(bar)))) => (append '(foo) (list '(bar))) | |
2057 | (, '(setq ad-dO-vAr (cdr ad-dO-vAr)))) | |
2058 | (, (car (cdr (cdr varform)))))))) | |
2059 | ;;ok, this wastes some cons cells but only during compilation: | |
2060 | (if (catch 'contains-return | |
2061 | (ad-substitute-tree | |
2062 | (function (lambda (subtree) | |
2063 | (cond ((eq (car-safe subtree) 'ad-dolist)) | |
2064 | ((eq (car-safe subtree) 'ad-do-return) | |
2065 | (throw 'contains-return t))))) | |
2066 | 'identity body) | |
2067 | nil) | |
2068 | (` (catch 'ad-dO-eXiT (, expansion))) | |
2069 | expansion))) | |
2070 | ||
2071 | (defmacro ad-do-return (value) | |
2072 | (` (throw 'ad-dO-eXiT (, value)))) | |
2073 | ||
2074 | (if (not (get 'ad-dolist 'lisp-indent-hook)) | |
2075 | (put 'ad-dolist 'lisp-indent-hook 1)) | |
2076 | ||
2077 | ||
6e2f6f45 RS |
2078 | ;; @@ Save real definitions of subrs used by Advice: |
2079 | ;; ================================================= | |
2080 | ;; Advice depends on the real, unmodified functionality of various subrs, | |
2081 | ;; we save them here so advised versions will not interfere (eventually, | |
2082 | ;; we will save all subrs used in code generated by Advice): | |
2083 | ||
2084 | (defmacro ad-save-real-definition (function) | |
2085 | (let ((saved-function (intern (format "ad-real-%s" function)))) | |
2086 | ;; Make sure the compiler is loaded during macro expansion: | |
2087 | (require 'byte-compile "bytecomp") | |
2088 | (` (if (not (fboundp '(, saved-function))) | |
2089 | (progn (fset '(, saved-function) (symbol-function '(, function))) | |
2090 | ;; Copy byte-compiler properties: | |
2091 | (,@ (if (get function 'byte-compile) | |
2092 | (` ((put '(, saved-function) 'byte-compile | |
2093 | '(, (get function 'byte-compile))))))) | |
2094 | (,@ (if (get function 'byte-opcode) | |
2095 | (` ((put '(, saved-function) 'byte-opcode | |
2096 | '(, (get function 'byte-opcode)))))))))))) | |
2097 | ||
2098 | (defun ad-save-real-definitions () | |
2099 | ;; Macro expansion will hardcode the values of the various byte-compiler | |
2100 | ;; properties into the compiled version of this function such that the | |
2101 | ;; proper values will be available at runtime without loading the compiler: | |
2102 | (ad-save-real-definition fset) | |
2103 | (ad-save-real-definition documentation) | |
2104 | (ad-save-real-definition byte-code) | |
2105 | (put 'ad-real-byte-code 'byte-compile nil)) | |
2106 | ||
2107 | (ad-save-real-definitions) | |
2108 | ||
2109 | ||
ee7bf2ad RM |
2110 | ;; @@ Advice info access fns: |
2111 | ;; ========================== | |
2112 | ||
2113 | ;; Advice information for a particular function is stored on the | |
6e2f6f45 | 2114 | ;; advice-info property of the function symbol. It is stored as an |
ee7bf2ad RM |
2115 | ;; alist of the following format: |
2116 | ;; | |
2117 | ;; ((active . t/nil) | |
2118 | ;; (before adv1 adv2 ...) | |
2119 | ;; (around adv1 adv2 ...) | |
2120 | ;; (after adv1 adv2 ...) | |
2121 | ;; (activation adv1 adv2 ...) | |
2122 | ;; (deactivation adv1 adv2 ...) | |
2123 | ;; (origname . <symbol fbound to origdef>) | |
2124 | ;; (cache . (<advised-definition> . <id>))) | |
2125 | ||
2126 | ;; List of currently advised though not necessarily activated functions | |
2127 | ;; (this list is maintained as a completion table): | |
2128 | (defvar ad-advised-functions nil) | |
2129 | ||
2130 | (defmacro ad-pushnew-advised-function (function) | |
2131 | ;;"Add FUNCTION to `ad-advised-functions' unless its already there." | |
2132 | (` (if (not (assoc (symbol-name (, function)) ad-advised-functions)) | |
2133 | (setq ad-advised-functions | |
2134 | (cons (list (symbol-name (, function))) | |
2135 | ad-advised-functions))))) | |
2136 | ||
2137 | (defmacro ad-pop-advised-function (function) | |
2138 | ;;"Remove FUNCTION from `ad-advised-functions'." | |
2139 | (` (setq ad-advised-functions | |
2140 | (delq (assoc (symbol-name (, function)) ad-advised-functions) | |
2141 | ad-advised-functions)))) | |
2142 | ||
2143 | (defmacro ad-do-advised-functions (varform &rest body) | |
2144 | ;;"`ad-dolist'-style iterator that maps over `ad-advised-functions'. | |
6e2f6f45 RS |
2145 | ;; (ad-do-advised-functions (VAR [RESULT-FORM]) |
2146 | ;; BODY-FORM...) | |
2147 | ;;Also see `ad-dolist'. On each iteration VAR will be bound to the | |
ee7bf2ad RM |
2148 | ;;name of an advised function (a symbol)." |
2149 | (` (ad-dolist ((, (car varform)) | |
2150 | ad-advised-functions | |
2151 | (, (car (cdr varform)))) | |
2152 | (setq (, (car varform)) (intern (car (, (car varform))))) | |
2153 | (,@ body)))) | |
2154 | ||
2155 | (if (not (get 'ad-do-advised-functions 'lisp-indent-hook)) | |
2156 | (put 'ad-do-advised-functions 'lisp-indent-hook 1)) | |
2157 | ||
2158 | (defmacro ad-get-advice-info (function) | |
2159 | (` (get (, function) 'ad-advice-info))) | |
2160 | ||
2161 | (defmacro ad-set-advice-info (function advice-info) | |
2162 | (` (put (, function) 'ad-advice-info (, advice-info)))) | |
2163 | ||
2164 | (defmacro ad-copy-advice-info (function) | |
2165 | (` (ad-copy-tree (get (, function) 'ad-advice-info)))) | |
2166 | ||
2167 | (defmacro ad-is-advised (function) | |
6e2f6f45 | 2168 | ;;"Returns non-nil if FUNCTION has any advice info associated with it. |
ee7bf2ad RM |
2169 | ;;This does not mean that the advice is also active." |
2170 | (list 'ad-get-advice-info function)) | |
2171 | ||
2172 | (defun ad-initialize-advice-info (function) | |
2173 | ;;"Initializes the advice info for FUNCTION. | |
2174 | ;;Assumes that FUNCTION has not yet been advised." | |
2175 | (ad-pushnew-advised-function function) | |
2176 | (ad-set-advice-info function (list (cons 'active nil)))) | |
2177 | ||
2178 | (defmacro ad-get-advice-info-field (function field) | |
2179 | ;;"Retrieves the value of the advice info FIELD of FUNCTION." | |
2180 | (` (cdr (assq (, field) (ad-get-advice-info (, function)))))) | |
2181 | ||
2182 | (defun ad-set-advice-info-field (function field value) | |
2183 | ;;"Destructively modifies VALUE of the advice info FIELD of FUNCTION." | |
2184 | (and (ad-is-advised function) | |
2185 | (cond ((assq field (ad-get-advice-info function)) | |
2186 | ;; A field with that name is already present: | |
2187 | (rplacd (assq field (ad-get-advice-info function)) value)) | |
2188 | (t;; otherwise, create a new field with that name: | |
2189 | (nconc (ad-get-advice-info function) | |
2190 | (list (cons field value))))))) | |
2191 | ||
2192 | ;; Don't make this a macro so we can use it as a predicate: | |
2193 | (defun ad-is-active (function) | |
6e2f6f45 | 2194 | ;;"non-nil if FUNCTION is advised and activated." |
ee7bf2ad RM |
2195 | (ad-get-advice-info-field function 'active)) |
2196 | ||
2197 | ||
2198 | ;; @@ Access fns for single pieces of advice and related predicates: | |
2199 | ;; ================================================================= | |
2200 | ||
2201 | (defun ad-make-advice (name protect enable definition) | |
2202 | "Constructs single piece of advice to be stored in some advice-info. | |
6e2f6f45 | 2203 | NAME should be a non-nil symbol, PROTECT and ENABLE should each be |
ee7bf2ad | 2204 | either t or nil, and DEFINITION should be a list of the form |
6e2f6f45 | 2205 | `(advice lambda ARGLIST [DOCSTRING] [INTERACTIVE-FORM] BODY...)'." |
ee7bf2ad RM |
2206 | (list name protect enable definition)) |
2207 | ||
2208 | ;; ad-find-advice uses the alist structure directly -> | |
2209 | ;; change if this data structure changes!! | |
2210 | (defmacro ad-advice-name (advice) | |
2211 | (list 'car advice)) | |
2212 | (defmacro ad-advice-protected (advice) | |
2213 | (list 'nth 1 advice)) | |
2214 | (defmacro ad-advice-enabled (advice) | |
2215 | (list 'nth 2 advice)) | |
2216 | (defmacro ad-advice-definition (advice) | |
2217 | (list 'nth 3 advice)) | |
2218 | ||
2219 | (defun ad-advice-set-enabled (advice flag) | |
2220 | (rplaca (cdr (cdr advice)) flag)) | |
2221 | ||
2222 | (defun ad-class-p (thing) | |
2223 | (memq thing ad-advice-classes)) | |
2224 | (defun ad-name-p (thing) | |
2225 | (and thing (symbolp thing))) | |
2226 | (defun ad-position-p (thing) | |
2227 | (or (natnump thing) | |
2228 | (memq thing '(first last)))) | |
2229 | ||
2230 | ||
2231 | ;; @@ Advice access functions: | |
2232 | ;; =========================== | |
2233 | ||
2234 | ;; List of defined advice classes: | |
2235 | (defvar ad-advice-classes '(before around after activation deactivation)) | |
2236 | ||
2237 | (defun ad-has-enabled-advice (function class) | |
2238 | ;;"True if at least one of FUNCTION's advices in CLASS is enabled." | |
2239 | (ad-dolist (advice (ad-get-advice-info-field function class)) | |
2240 | (if (ad-advice-enabled advice) (ad-do-return t)))) | |
2241 | ||
2242 | (defun ad-has-redefining-advice (function) | |
2243 | ;;"True if FUNCTION's advice info defines at least 1 redefining advice. | |
2244 | ;;Redefining advices affect the construction of an advised definition." | |
2245 | (and (ad-is-advised function) | |
2246 | (or (ad-has-enabled-advice function 'before) | |
2247 | (ad-has-enabled-advice function 'around) | |
2248 | (ad-has-enabled-advice function 'after)))) | |
2249 | ||
2250 | (defun ad-has-any-advice (function) | |
2251 | ;;"True if the advice info of FUNCTION defines at least one advice." | |
2252 | (and (ad-is-advised function) | |
2253 | (ad-dolist (class ad-advice-classes nil) | |
2254 | (if (ad-get-advice-info-field function class) | |
2255 | (ad-do-return t))))) | |
2256 | ||
2257 | (defun ad-get-enabled-advices (function class) | |
2258 | ;;"Returns the list of enabled advices of FUNCTION in CLASS." | |
2259 | (let (enabled-advices) | |
2260 | (ad-dolist (advice (ad-get-advice-info-field function class)) | |
2261 | (if (ad-advice-enabled advice) | |
2262 | (setq enabled-advices (cons advice enabled-advices)))) | |
2263 | (reverse enabled-advices))) | |
2264 | ||
2265 | ||
2266 | ;; @@ Access functions for original definitions: | |
2267 | ;; ============================================ | |
2268 | ;; The advice-info of an advised function contains its `origname' which is | |
2269 | ;; a symbol that is fbound to the original definition available at the first | |
6e2f6f45 | 2270 | ;; proper activation of the function after a legal re/definition. If the |
ee7bf2ad | 2271 | ;; original was defined via fcell indirection then `origname' will be defined |
6e2f6f45 | 2272 | ;; just so. Hence, to get hold of the actual original definition of a function |
ee7bf2ad RM |
2273 | ;; we need to use `ad-real-orig-definition'. |
2274 | ||
2275 | (defun ad-make-origname (function) | |
2276 | ;;"Makes name to be used to call the original FUNCTION." | |
2277 | (intern (format "ad-Orig-%s" function))) | |
2278 | ||
2279 | (defmacro ad-get-orig-definition (function) | |
2280 | (` (let ((origname (ad-get-advice-info-field (, function) 'origname))) | |
2281 | (if (fboundp origname) | |
2282 | (symbol-function origname))))) | |
2283 | ||
2284 | (defmacro ad-set-orig-definition (function definition) | |
2285 | (` (ad-real-fset | |
2286 | (ad-get-advice-info-field function 'origname) (, definition)))) | |
2287 | ||
2288 | (defmacro ad-clear-orig-definition (function) | |
2289 | (` (fmakunbound (ad-get-advice-info-field (, function) 'origname)))) | |
2290 | ||
2291 | ||
2292 | ;; @@ Interactive input functions: | |
2293 | ;; =============================== | |
2294 | ||
2295 | (defun ad-read-advised-function (&optional prompt predicate default) | |
2296 | ;;"Reads name of advised function with completion from the minibuffer. | |
6e2f6f45 RS |
2297 | ;;An optional PROMPT will be used to prompt for the function. PREDICATE |
2298 | ;;plays the same role as for `try-completion' (which see). DEFAULT will | |
ee7bf2ad | 2299 | ;;be returned on empty input (defaults to the first advised function for |
6e2f6f45 | 2300 | ;;which PREDICATE returns non-nil)." |
ee7bf2ad RM |
2301 | (if (null ad-advised-functions) |
2302 | (error "ad-read-advised-function: There are no advised functions")) | |
2303 | (setq default | |
2304 | (or default | |
2305 | (ad-do-advised-functions (function) | |
2306 | (if (or (null predicate) | |
2307 | (funcall predicate function)) | |
2308 | (ad-do-return function))) | |
2309 | (error "ad-read-advised-function: %s" | |
2310 | "There are no qualifying advised functions"))) | |
2311 | (let* ((ad-pReDiCaTe predicate) | |
2312 | (function | |
2313 | (completing-read | |
2314 | (format "%s(default %s) " (or prompt "Function: ") default) | |
2315 | ad-advised-functions | |
2316 | (if predicate | |
2317 | (function | |
2318 | (lambda (function) | |
2319 | ;; Oops, no closures - the joys of dynamic scoping: | |
2320 | ;; `predicate' clashed with the `predicate' argument | |
2321 | ;; of Lemacs' `completing-read'..... | |
2322 | (funcall ad-pReDiCaTe (intern (car function)))))) | |
2323 | t))) | |
2324 | (if (equal function "") | |
2325 | (if (ad-is-advised default) | |
2326 | default | |
2327 | (error "ad-read-advised-function: `%s' is not advised" default)) | |
2328 | (intern function)))) | |
2329 | ||
2330 | (defvar ad-advice-class-completion-table | |
2331 | (mapcar '(lambda (class) (list (symbol-name class))) | |
2332 | ad-advice-classes)) | |
2333 | ||
2334 | (defun ad-read-advice-class (function &optional prompt default) | |
2335 | ;;"Reads a legal advice class with completion from the minibuffer. | |
6e2f6f45 | 2336 | ;;An optional PROMPT will be used to prompt for the class. DEFAULT will |
ee7bf2ad RM |
2337 | ;;be returned on empty input (defaults to the first non-empty advice |
2338 | ;;class of FUNCTION)." | |
2339 | (setq default | |
2340 | (or default | |
2341 | (ad-dolist (class ad-advice-classes) | |
2342 | (if (ad-get-advice-info-field function class) | |
2343 | (ad-do-return class))) | |
2344 | (error "ad-read-advice-class: `%s' has no advices" function))) | |
2345 | (let ((class (completing-read | |
2346 | (format "%s(default %s) " (or prompt "Class: ") default) | |
2347 | ad-advice-class-completion-table nil t))) | |
2348 | (if (equal class "") | |
2349 | default | |
2350 | (intern class)))) | |
2351 | ||
2352 | (defun ad-read-advice-name (function class &optional prompt) | |
2353 | ;;"Reads name of existing advice of CLASS for FUNCTION with completion. | |
2354 | ;;An optional PROMPT is used to prompt for the name." | |
2355 | (let* ((name-completion-table | |
2356 | (mapcar (function (lambda (advice) | |
2357 | (list (symbol-name (ad-advice-name advice))))) | |
2358 | (ad-get-advice-info-field function class))) | |
2359 | (default | |
2360 | (if (null name-completion-table) | |
2361 | (error "ad-read-advice-name: `%s' has no %s advice" | |
2362 | function class) | |
2363 | (car (car name-completion-table)))) | |
2364 | (prompt (format "%s(default %s) " (or prompt "Name: ") default)) | |
2365 | (name (completing-read prompt name-completion-table nil t))) | |
2366 | (if (equal name "") | |
2367 | (intern default) | |
2368 | (intern name)))) | |
2369 | ||
2370 | (defun ad-read-advice-specification (&optional prompt) | |
2371 | ;;"Reads a complete function/class/name specification from minibuffer. | |
6e2f6f45 | 2372 | ;;The list of read symbols will be returned. The optional PROMPT will |
ee7bf2ad RM |
2373 | ;;be used to prompt for the function." |
2374 | (let* ((function (ad-read-advised-function prompt)) | |
2375 | (class (ad-read-advice-class function)) | |
2376 | (name (ad-read-advice-name function class))) | |
2377 | (list function class name))) | |
2378 | ||
2379 | ;; Use previous regexp as a default: | |
2380 | (defvar ad-last-regexp "") | |
2381 | ||
2382 | (defun ad-read-regexp (&optional prompt) | |
2383 | ;;"Reads a regular expression from the minibuffer." | |
2384 | (let ((regexp (read-from-minibuffer | |
2385 | (concat (or prompt "Regular expression: ") | |
2386 | (if (equal ad-last-regexp "") "" | |
2387 | (format "(default \"%s\") " ad-last-regexp)))))) | |
2388 | (setq ad-last-regexp | |
2389 | (if (equal regexp "") ad-last-regexp regexp)))) | |
2390 | ||
2391 | ||
2392 | ;; @@ Finding, enabling, adding and removing pieces of advice: | |
2393 | ;; =========================================================== | |
2394 | ||
2395 | (defmacro ad-find-advice (function class name) | |
2396 | ;;"Finds the first advice of FUNCTION in CLASS with NAME." | |
2397 | (` (assq (, name) (ad-get-advice-info-field (, function) (, class))))) | |
2398 | ||
2399 | (defun ad-advice-position (function class name) | |
2400 | ;;"Returns position of first advice of FUNCTION in CLASS with NAME." | |
2401 | (let* ((found-advice (ad-find-advice function class name)) | |
2402 | (advices (ad-get-advice-info-field function class))) | |
2403 | (if found-advice | |
2404 | (- (length advices) (length (memq found-advice advices)))))) | |
2405 | ||
2406 | (defun ad-find-some-advice (function class name) | |
2407 | "Finds the first of FUNCTION's advices in CLASS matching NAME. | |
2408 | NAME can be a symbol or a regular expression matching part of an advice name. | |
2409 | If CLASS is `any' all legal advice classes will be checked." | |
2410 | (if (ad-is-advised function) | |
2411 | (let (found-advice) | |
2412 | (ad-dolist (advice-class ad-advice-classes) | |
2413 | (if (or (eq class 'any) (eq advice-class class)) | |
2414 | (setq found-advice | |
2415 | (ad-dolist (advice (ad-get-advice-info-field | |
2416 | function advice-class)) | |
2417 | (if (or (and (stringp name) | |
2418 | (string-match | |
2419 | name (symbol-name | |
2420 | (ad-advice-name advice)))) | |
2421 | (eq name (ad-advice-name advice))) | |
2422 | (ad-do-return advice))))) | |
2423 | (if found-advice (ad-do-return found-advice)))))) | |
2424 | ||
2425 | (defun ad-enable-advice-internal (function class name flag) | |
2426 | ;;"Sets enable FLAG of FUNCTION's advices in CLASS matching NAME. | |
2427 | ;;If NAME is a string rather than a symbol then it's interpreted as a regular | |
2428 | ;;expression and all advices whose name contain a match for it will be | |
6e2f6f45 RS |
2429 | ;;affected. If CLASS is `any' advices in all legal advice classes will be |
2430 | ;;considered. The number of changed advices will be returned (or nil if | |
ee7bf2ad RM |
2431 | ;;FUNCTION was not advised)." |
2432 | (if (ad-is-advised function) | |
2433 | (let ((matched-advices 0)) | |
2434 | (ad-dolist (advice-class ad-advice-classes) | |
2435 | (if (or (eq class 'any) (eq advice-class class)) | |
2436 | (ad-dolist (advice (ad-get-advice-info-field | |
2437 | function advice-class)) | |
2438 | (cond ((or (and (stringp name) | |
2439 | (string-match | |
2440 | name (symbol-name (ad-advice-name advice)))) | |
2441 | (eq name (ad-advice-name advice))) | |
2442 | (setq matched-advices (1+ matched-advices)) | |
2443 | (ad-advice-set-enabled advice flag)))))) | |
2444 | matched-advices))) | |
2445 | ||
2446 | (defun ad-enable-advice (function class name) | |
2447 | "Enables the advice of FUNCTION with CLASS and NAME." | |
2448 | (interactive (ad-read-advice-specification "Enable advice of: ")) | |
2449 | (if (ad-is-advised function) | |
2450 | (if (eq (ad-enable-advice-internal function class name t) 0) | |
2451 | (error "ad-enable-advice: `%s' has no %s advice matching `%s'" | |
2452 | function class name)) | |
2453 | (error "ad-enable-advice: `%s' is not advised" function))) | |
2454 | ||
2455 | (defun ad-disable-advice (function class name) | |
2456 | "Disables the advice of FUNCTION with CLASS and NAME." | |
2457 | (interactive (ad-read-advice-specification "Disable advice of: ")) | |
2458 | (if (ad-is-advised function) | |
2459 | (if (eq (ad-enable-advice-internal function class name nil) 0) | |
2460 | (error "ad-disable-advice: `%s' has no %s advice matching `%s'" | |
2461 | function class name)) | |
2462 | (error "ad-disable-advice: `%s' is not advised" function))) | |
2463 | ||
2464 | (defun ad-enable-regexp-internal (regexp class flag) | |
2465 | ;;"Sets enable FLAGs of all CLASS advices whose name contains a REGEXP match. | |
6e2f6f45 | 2466 | ;;If CLASS is `any' all legal advice classes are considered. The number of |
ee7bf2ad RM |
2467 | ;;affected advices will be returned." |
2468 | (let ((matched-advices 0)) | |
2469 | (ad-do-advised-functions (advised-function) | |
2470 | (setq matched-advices | |
2471 | (+ matched-advices | |
2472 | (or (ad-enable-advice-internal | |
2473 | advised-function class regexp flag) | |
2474 | 0)))) | |
2475 | matched-advices)) | |
2476 | ||
2477 | (defun ad-enable-regexp (regexp) | |
2478 | "Enables all advices with names that contain a match for REGEXP. | |
2479 | All currently advised functions will be considered." | |
2480 | (interactive | |
2481 | (list (ad-read-regexp "Enable advices via regexp: "))) | |
2482 | (let ((matched-advices (ad-enable-regexp-internal regexp 'any t))) | |
2483 | (if (interactive-p) | |
2484 | (message "%d matching advices enabled" matched-advices)) | |
2485 | matched-advices)) | |
2486 | ||
2487 | (defun ad-disable-regexp (regexp) | |
2488 | "Disables all advices with names that contain a match for REGEXP. | |
2489 | All currently advised functions will be considered." | |
2490 | (interactive | |
2491 | (list (ad-read-regexp "Disable advices via regexp: "))) | |
2492 | (let ((matched-advices (ad-enable-regexp-internal regexp 'any nil))) | |
2493 | (if (interactive-p) | |
2494 | (message "%d matching advices disabled" matched-advices)) | |
2495 | matched-advices)) | |
2496 | ||
2497 | (defun ad-remove-advice (function class name) | |
2498 | "Removes FUNCTION's advice with NAME from its advices in CLASS. | |
2499 | If such an advice was found it will be removed from the list of advices | |
2500 | in that CLASS." | |
2501 | (interactive (ad-read-advice-specification "Remove advice of: ")) | |
2502 | (if (ad-is-advised function) | |
2503 | (let* ((advice-to-remove (ad-find-advice function class name))) | |
2504 | (if advice-to-remove | |
2505 | (ad-set-advice-info-field | |
2506 | function class | |
2507 | (delq advice-to-remove (ad-get-advice-info-field function class))) | |
2508 | (error "ad-remove-advice: `%s' has no %s advice `%s'" | |
2509 | function class name))) | |
2510 | (error "ad-remove-advice: `%s' is not advised" function))) | |
2511 | ||
2512 | ;;;###autoload | |
2513 | (defun ad-add-advice (function advice class position) | |
2514 | "Adds a piece of ADVICE to FUNCTION's list of advices in CLASS. | |
2515 | If FUNCTION already has one or more pieces of advice of the specified | |
6e2f6f45 | 2516 | CLASS then POSITION determines where the new piece will go. The value |
ee7bf2ad | 2517 | of POSITION can either be `first', `last' or a number where 0 corresponds |
6e2f6f45 RS |
2518 | to `first'. Numbers outside the range will be mapped to the closest |
2519 | extreme position. If there was already a piece of ADVICE with the same | |
ee7bf2ad RM |
2520 | name, then the position argument will be ignored and the old advice |
2521 | will be overwritten with the new one. | |
2522 | If the FUNCTION was not advised already, then its advice info will be | |
6e2f6f45 | 2523 | initialized. Redefining a piece of advice whose name is part of the cache-id |
ee7bf2ad RM |
2524 | will clear the cache." |
2525 | (cond ((not (ad-is-advised function)) | |
2526 | (ad-initialize-advice-info function) | |
2527 | (ad-set-advice-info-field | |
2528 | function 'origname (ad-make-origname function)))) | |
2529 | (let* ((previous-position | |
2530 | (ad-advice-position function class (ad-advice-name advice))) | |
2531 | (advices (ad-get-advice-info-field function class)) | |
2532 | ;; Determine a numerical position for the new advice: | |
2533 | (position (cond (previous-position) | |
2534 | ((eq position 'first) 0) | |
2535 | ((eq position 'last) (length advices)) | |
2536 | ((numberp position) | |
2537 | (max 0 (min position (length advices)))) | |
2538 | (t 0)))) | |
2539 | ;; Check whether we have to clear the cache: | |
2540 | (if (memq (ad-advice-name advice) (ad-get-cache-class-id function class)) | |
2541 | (ad-clear-cache function)) | |
2542 | (if previous-position | |
2543 | (setcar (nthcdr position advices) advice) | |
2544 | (if (= position 0) | |
2545 | (ad-set-advice-info-field function class (cons advice advices)) | |
2546 | (setcdr (nthcdr (1- position) advices) | |
2547 | (cons advice (nthcdr position advices))))))) | |
2548 | ||
2549 | ||
2550 | ;; @@ Accessing and manipulating function definitions: | |
2551 | ;; =================================================== | |
2552 | ||
2553 | (defmacro ad-macrofy (definition) | |
2554 | ;;"Takes a lambda function DEFINITION and makes a macro out of it." | |
2555 | (` (cons 'macro (, definition)))) | |
2556 | ||
2557 | (defmacro ad-lambdafy (definition) | |
2558 | ;;"Takes a macro function DEFINITION and makes a lambda out of it." | |
2559 | (` (cdr (, definition)))) | |
2560 | ||
2561 | ;; There is no way to determine whether some subr is a special form or not, | |
6e2f6f45 | 2562 | ;; hence we need this list (which is probably out of date): |
ee7bf2ad RM |
2563 | (defvar ad-special-forms |
2564 | (mapcar 'symbol-function | |
2565 | '(and catch cond condition-case defconst defmacro | |
2566 | defun defvar function if interactive let let* | |
2567 | or prog1 prog2 progn quote save-excursion | |
2568 | save-restriction save-window-excursion setq | |
2569 | setq-default unwind-protect while | |
2570 | with-output-to-temp-buffer))) | |
2571 | ||
2572 | (defmacro ad-special-form-p (definition) | |
6e2f6f45 | 2573 | ;;"non-nil if DEFINITION is a special form." |
ee7bf2ad RM |
2574 | (list 'memq definition 'ad-special-forms)) |
2575 | ||
2576 | (defmacro ad-interactive-p (definition) | |
6e2f6f45 | 2577 | ;;"non-nil if DEFINITION can be called interactively." |
ee7bf2ad RM |
2578 | (list 'commandp definition)) |
2579 | ||
2580 | (defmacro ad-subr-p (definition) | |
6e2f6f45 | 2581 | ;;"non-nil if DEFINITION is a subr." |
ee7bf2ad RM |
2582 | (list 'subrp definition)) |
2583 | ||
2584 | (defmacro ad-macro-p (definition) | |
6e2f6f45 | 2585 | ;;"non-nil if DEFINITION is a macro." |
ee7bf2ad RM |
2586 | (` (eq (car-safe (, definition)) 'macro))) |
2587 | ||
2588 | (defmacro ad-lambda-p (definition) | |
6e2f6f45 | 2589 | ;;"non-nil if DEFINITION is a lambda expression." |
ee7bf2ad RM |
2590 | (` (eq (car-safe (, definition)) 'lambda))) |
2591 | ||
2592 | ;; see ad-make-advice for the format of advice definitions: | |
2593 | (defmacro ad-advice-p (definition) | |
6e2f6f45 | 2594 | ;;"non-nil if DEFINITION is a piece of advice." |
ee7bf2ad RM |
2595 | (` (eq (car-safe (, definition)) 'advice))) |
2596 | ||
6e2f6f45 RS |
2597 | ;; Emacs/Lemacs cross-compatibility |
2598 | ;; (compiled-function-p is an obsolete function in Emacs): | |
ee7bf2ad RM |
2599 | (if (and (not (fboundp 'byte-code-function-p)) |
2600 | (fboundp 'compiled-function-p)) | |
2601 | (ad-real-fset 'byte-code-function-p 'compiled-function-p)) | |
2602 | ||
6e2f6f45 RS |
2603 | (defmacro ad-compiled-p (definition) |
2604 | ;;"non-nil if DEFINITION is a compiled byte-code object." | |
2605 | (` (or (byte-code-function-p (, definition)) | |
2606 | (and (ad-macro-p (, definition)) | |
2607 | (byte-code-function-p (ad-lambdafy (, definition))))))) | |
ee7bf2ad | 2608 | |
6e2f6f45 RS |
2609 | (defmacro ad-compiled-code (compiled-definition) |
2610 | ;;"Returns the byte-code object of a COMPILED-DEFINITION." | |
ee7bf2ad RM |
2611 | (` (if (ad-macro-p (, compiled-definition)) |
2612 | (ad-lambdafy (, compiled-definition)) | |
2613 | (, compiled-definition)))) | |
2614 | ||
2615 | (defun ad-lambda-expression (definition) | |
2616 | ;;"Returns the lambda expression of a function/macro/advice DEFINITION." | |
2617 | (cond ((ad-lambda-p definition) | |
2618 | definition) | |
2619 | ((ad-macro-p definition) | |
2620 | (ad-lambdafy definition)) | |
2621 | ((ad-advice-p definition) | |
2622 | (cdr definition)) | |
2623 | (t nil))) | |
2624 | ||
2625 | (defun ad-arglist (definition &optional name) | |
2626 | ;;"Returns the argument list of DEFINITION. | |
2627 | ;;If DEFINITION could be from a subr then its NAME should be | |
2628 | ;;supplied to make subr arglist lookup more efficient." | |
6e2f6f45 RS |
2629 | (cond ((ad-compiled-p definition) |
2630 | (aref (ad-compiled-code definition) 0)) | |
ee7bf2ad RM |
2631 | ((consp definition) |
2632 | (car (cdr (ad-lambda-expression definition)))) | |
2633 | ((ad-subr-p definition) | |
2634 | (if name | |
2635 | (ad-subr-arglist name) | |
2636 | ;; otherwise get it from its printed representation: | |
2637 | (setq name (format "%s" definition)) | |
2638 | (string-match "^#<subr \\([^>]+\\)>$" name) | |
2639 | (ad-subr-arglist | |
2640 | (intern (substring name (match-beginning 1) (match-end 1)))))))) | |
2641 | ||
2642 | ;; Store subr-args as `((arg1 arg2 ...))' so I can distinguish | |
2643 | ;; a defined empty arglist `(nil)' from an undefined arglist: | |
2644 | (defmacro ad-define-subr-args (subr arglist) | |
2645 | (` (put (, subr) 'ad-subr-arglist (list (, arglist))))) | |
2646 | (defmacro ad-undefine-subr-args (subr) | |
2647 | (` (put (, subr) 'ad-subr-arglist nil))) | |
2648 | (defmacro ad-subr-args-defined-p (subr) | |
2649 | (` (get (, subr) 'ad-subr-arglist))) | |
2650 | (defmacro ad-get-subr-args (subr) | |
2651 | (` (car (get (, subr) 'ad-subr-arglist)))) | |
2652 | ||
2653 | (defun ad-subr-arglist (subr-name) | |
2654 | ;;"Retrieve arglist of the subr with SUBR-NAME. | |
6e2f6f45 RS |
2655 | ;;Either use the one stored under the `ad-subr-arglist' property, |
2656 | ;;or try to retrieve it from the docstring and cache it under | |
ee7bf2ad | 2657 | ;;that property, or otherwise use `(&rest ad-subr-args)'." |
6e2f6f45 RS |
2658 | (cond ((ad-subr-args-defined-p subr-name) |
2659 | (ad-get-subr-args subr-name)) | |
2660 | ;; says jwz: Should use this for Lemacs 19.8 and above: | |
2661 | ;;((fboundp 'subr-min-args) | |
2662 | ;; ...) | |
2663 | ;; says hans: I guess what Jamie means is that I should use the values | |
2664 | ;; of `subr-min-args' and `subr-max-args' to construct the subr arglist | |
2665 | ;; without having to look it up via parsing the docstring, e.g., | |
2666 | ;; values 1 and 2 would suggest `(arg1 &optional arg2)' as an | |
2667 | ;; argument list. However, that won't work because there is no | |
2668 | ;; way to distinguish a subr with args `(a &optional b &rest c)' from | |
2669 | ;; one with args `(a &rest c)' using that mechanism. Also, the argument | |
2670 | ;; names from the docstring are more meaningful. Hence, I'll stick with | |
2671 | ;; the old way of doing things. | |
2672 | (t (let ((doc (ad-real-documentation subr-name t))) | |
2673 | (cond ((and doc | |
2674 | (string-match | |
2675 | "[\n\t ]*\narguments: ?\\((.*)\\)\n?\\'" doc)) | |
2676 | (ad-define-subr-args | |
2677 | subr-name | |
2678 | (car (read-from-string | |
2679 | doc (match-beginning 1) (match-end 1)))) | |
2680 | (ad-get-subr-args subr-name)) | |
2681 | (t '(&rest ad-subr-args))))))) | |
ee7bf2ad RM |
2682 | |
2683 | (defun ad-docstring (definition) | |
2684 | ;;"Returns the unexpanded docstring of DEFINITION." | |
2685 | (let ((docstring | |
6e2f6f45 RS |
2686 | (if (ad-compiled-p definition) |
2687 | (ad-real-documentation definition t) | |
ee7bf2ad RM |
2688 | (car (cdr (cdr (ad-lambda-expression definition))))))) |
2689 | (if (or (stringp docstring) | |
2690 | (natnump docstring)) | |
2691 | docstring))) | |
2692 | ||
2693 | (defun ad-interactive-form (definition) | |
2694 | ;;"Returns the interactive form of DEFINITION." | |
6e2f6f45 | 2695 | (cond ((ad-compiled-p definition) |
ee7bf2ad | 2696 | (and (commandp definition) |
6e2f6f45 | 2697 | (list 'interactive (aref (ad-compiled-code definition) 5)))) |
ee7bf2ad RM |
2698 | ((or (ad-advice-p definition) |
2699 | (ad-lambda-p definition)) | |
2700 | (commandp (ad-lambda-expression definition))))) | |
2701 | ||
2702 | (defun ad-body-forms (definition) | |
2703 | ;;"Returns the list of body forms of DEFINITION." | |
6e2f6f45 RS |
2704 | (cond ((ad-compiled-p definition) |
2705 | nil) | |
ee7bf2ad RM |
2706 | ((consp definition) |
2707 | (nthcdr (+ (if (ad-docstring definition) 1 0) | |
2708 | (if (ad-interactive-form definition) 1 0)) | |
2709 | (cdr (cdr (ad-lambda-expression definition))))))) | |
2710 | ||
ee7bf2ad RM |
2711 | ;; Matches the docstring of an advised definition. |
2712 | ;; The first group of the regexp matches the function name: | |
2713 | (defvar ad-advised-definition-docstring-regexp "^\\$ad-doc: \\(.+\\)\\$$") | |
2714 | ||
2715 | (defun ad-make-advised-definition-docstring (function) | |
2716 | ;; Makes an identifying docstring for the advised definition of FUNCTION. | |
2717 | ;; Put function name into the documentation string so we can infer | |
6e2f6f45 | 2718 | ;; the name of the advised function from the docstring. This is needed |
ee7bf2ad RM |
2719 | ;; to generate a proper advised docstring even if we are just given a |
2720 | ;; definition (also see the defadvice for `documentation'): | |
2721 | (format "$ad-doc: %s$" (prin1-to-string function))) | |
2722 | ||
2723 | (defun ad-advised-definition-p (definition) | |
6e2f6f45 | 2724 | ;;"non-nil if DEFINITION was generated from advice information." |
ee7bf2ad RM |
2725 | (if (or (ad-lambda-p definition) |
2726 | (ad-macro-p definition) | |
2727 | (ad-compiled-p definition)) | |
2728 | (let ((docstring (ad-docstring definition))) | |
2729 | (and (stringp docstring) | |
2730 | (string-match | |
2731 | ad-advised-definition-docstring-regexp docstring))))) | |
2732 | ||
2733 | (defun ad-definition-type (definition) | |
2734 | ;;"Returns symbol that describes the type of DEFINITION." | |
2735 | (if (ad-macro-p definition) | |
2736 | 'macro | |
2737 | (if (ad-subr-p definition) | |
2738 | (if (ad-special-form-p definition) | |
2739 | 'special-form | |
2740 | 'subr) | |
2741 | (if (or (ad-lambda-p definition) | |
2742 | (ad-compiled-p definition)) | |
2743 | 'function | |
2744 | (if (ad-advice-p definition) | |
2745 | 'advice))))) | |
2746 | ||
2747 | (defun ad-has-proper-definition (function) | |
2748 | ;;"True if FUNCTION is a symbol with a proper definition. | |
2749 | ;;For that it has to be fbound with a non-autoload definition." | |
2750 | (and (symbolp function) | |
2751 | (fboundp function) | |
2752 | (not (eq (car-safe (symbol-function function)) 'autoload)))) | |
2753 | ||
2754 | ;; The following two are necessary for the sake of packages such as | |
2755 | ;; ange-ftp which redefine functions via fcell indirection: | |
2756 | (defun ad-real-definition (function) | |
2757 | ;;"Finds FUNCTION's definition at the end of function cell indirection." | |
2758 | (if (ad-has-proper-definition function) | |
2759 | (let ((definition (symbol-function function))) | |
2760 | (if (symbolp definition) | |
2761 | (ad-real-definition definition) | |
2762 | definition)))) | |
2763 | ||
2764 | (defun ad-real-orig-definition (function) | |
2765 | ;;"Finds FUNCTION's real original definition starting from its `origname'." | |
2766 | (if (ad-is-advised function) | |
2767 | (ad-real-definition (ad-get-advice-info-field function 'origname)))) | |
2768 | ||
2769 | (defun ad-is-compilable (function) | |
2770 | ;;"True if FUNCTION has an interpreted definition that can be compiled." | |
2771 | (and (ad-has-proper-definition function) | |
2772 | (or (ad-lambda-p (symbol-function function)) | |
2773 | (ad-macro-p (symbol-function function))) | |
2774 | (not (ad-compiled-p (symbol-function function))))) | |
2775 | ||
ee7bf2ad RM |
2776 | (defun ad-compile-function (function) |
2777 | "Byte-compiles FUNCTION (or macro) if it is not yet compiled." | |
2778 | (interactive "aByte-compile function: ") | |
2779 | (if (ad-is-compilable function) | |
6e2f6f45 | 2780 | (byte-compile function))) |
ee7bf2ad RM |
2781 | |
2782 | ||
2783 | ;; @@ Constructing advised definitions: | |
2784 | ;; ==================================== | |
2785 | ;; | |
2786 | ;; Main design decisions about the form of advised definitions: | |
2787 | ;; | |
2788 | ;; A) How will original definitions be called? | |
2789 | ;; B) What will argument lists of advised functions look like? | |
2790 | ;; | |
2791 | ;; Ad A) | |
2792 | ;; I chose to use function indirection for all four types of original | |
2793 | ;; definitions (functions, macros, subrs and special forms), i.e., create | |
2794 | ;; a unique symbol `ad-Orig-<name>' which is fbound to the original | |
6e2f6f45 | 2795 | ;; definition and call it according to type and arguments. Functions and |
ee7bf2ad | 2796 | ;; subrs that don't have any &rest arguments can be called directly in a |
6e2f6f45 RS |
2797 | ;; `(ad-Orig-<name> ....)' form. If they have a &rest argument we have to |
2798 | ;; use `apply'. Macros will be called with | |
ee7bf2ad RM |
2799 | ;; `(macroexpand '(ad-Orig-<name> ....))', and special forms also need a |
2800 | ;; form like that with `eval' instead of `macroexpand'. | |
2801 | ;; | |
2802 | ;; Ad B) | |
2803 | ;; Use original arguments where possible and `(&rest ad-subr-args)' | |
2804 | ;; otherwise, even though this seems to be more complicated and less | |
2805 | ;; uniform than a general `(&rest args)' approach. My reason to still | |
2806 | ;; do it that way is that in most cases my approach leads to the more | |
2807 | ;; efficient form for the advised function, and portability (e.g., to | |
2808 | ;; make the same advice work regardless of whether something is a | |
2809 | ;; function or a subr) can still be achieved with argument access macros. | |
2810 | ||
2811 | ||
2812 | (defun ad-prognify (forms) | |
2813 | (cond ((<= (length forms) 1) | |
2814 | (car forms)) | |
2815 | (t (cons 'progn forms)))) | |
2816 | ||
2817 | ;; @@@ Accessing argument lists: | |
2818 | ;; ============================= | |
2819 | ||
2820 | (defun ad-parse-arglist (arglist) | |
2821 | ;;"Parses ARGLIST into its required, optional and rest parameters. | |
2822 | ;;A three-element list is returned, where the 1st element is the list of | |
2823 | ;;required arguments, the 2nd is the list of optional arguments, and the 3rd | |
6e2f6f45 | 2824 | ;;is the name of an optional rest parameter (or nil)." |
ee7bf2ad RM |
2825 | (let* (required optional rest) |
2826 | (setq rest (car (cdr (memq '&rest arglist)))) | |
2827 | (if rest (setq arglist (reverse (cdr (memq '&rest (reverse arglist)))))) | |
2828 | (setq optional (cdr (memq '&optional arglist))) | |
2829 | (if optional | |
2830 | (setq required (reverse (cdr (memq '&optional (reverse arglist))))) | |
2831 | (setq required arglist)) | |
2832 | (list required optional rest))) | |
2833 | ||
2834 | (defun ad-retrieve-args-form (arglist) | |
2835 | ;;"Generates a form which evaluates into names/values/types of ARGLIST. | |
2836 | ;;When the form gets evaluated within a function with that argument list | |
2837 | ;;it will result in a list with one entry for each argument, where the | |
2838 | ;;first element of each entry is the name of the argument, the second | |
2839 | ;;element is its actual current value, and the third element is either | |
2840 | ;;`required', `optional' or `rest' depending on the type of the argument." | |
2841 | (let* ((parsed-arglist (ad-parse-arglist arglist)) | |
2842 | (rest (nth 2 parsed-arglist))) | |
2843 | (` (list | |
2844 | (,@ (mapcar (function | |
2845 | (lambda (req) | |
2846 | (` (list '(, req) (, req) 'required)))) | |
2847 | (nth 0 parsed-arglist))) | |
2848 | (,@ (mapcar (function | |
2849 | (lambda (opt) | |
2850 | (` (list '(, opt) (, opt) 'optional)))) | |
2851 | (nth 1 parsed-arglist))) | |
2852 | (,@ (if rest (list (` (list '(, rest) (, rest) 'rest))))) | |
2853 | )))) | |
2854 | ||
2855 | (defun ad-arg-binding-field (binding field) | |
2856 | (cond ((eq field 'name) (car binding)) | |
2857 | ((eq field 'value) (car (cdr binding))) | |
2858 | ((eq field 'type) (car (cdr (cdr binding)))))) | |
2859 | ||
2860 | (defun ad-list-access (position list) | |
2861 | (cond ((= position 0) list) | |
2862 | ((= position 1) (list 'cdr list)) | |
2863 | (t (list 'nthcdr position list)))) | |
2864 | ||
2865 | (defun ad-element-access (position list) | |
2866 | (cond ((= position 0) (list 'car list)) | |
2867 | ((= position 1) (` (car (cdr (, list))))) | |
2868 | (t (list 'nth position list)))) | |
2869 | ||
2870 | (defun ad-access-argument (arglist index) | |
2871 | ;;"Tells how to access ARGLIST's actual argument at position INDEX. | |
2872 | ;;For a required/optional arg it simply returns it, if a rest argument has | |
2873 | ;;to be accessed, it returns a list with the index and name." | |
2874 | (let* ((parsed-arglist (ad-parse-arglist arglist)) | |
2875 | (reqopt-args (append (nth 0 parsed-arglist) | |
2876 | (nth 1 parsed-arglist))) | |
2877 | (rest-arg (nth 2 parsed-arglist))) | |
2878 | (cond ((< index (length reqopt-args)) | |
2879 | (nth index reqopt-args)) | |
2880 | (rest-arg | |
2881 | (list (- index (length reqopt-args)) rest-arg))))) | |
2882 | ||
2883 | (defun ad-get-argument (arglist index) | |
2884 | ;;"Returns form to access ARGLIST's actual argument at position INDEX." | |
2885 | (let ((argument-access (ad-access-argument arglist index))) | |
2886 | (cond ((consp argument-access) | |
2887 | (ad-element-access | |
2888 | (car argument-access) (car (cdr argument-access)))) | |
2889 | (argument-access)))) | |
2890 | ||
2891 | (defun ad-set-argument (arglist index value-form) | |
2892 | ;;"Returns form to set ARGLIST's actual arg at INDEX to VALUE-FORM." | |
2893 | (let ((argument-access (ad-access-argument arglist index))) | |
2894 | (cond ((consp argument-access) | |
2895 | ;; should this check whether there actually is something to set? | |
2896 | (` (setcar (, (ad-list-access | |
2897 | (car argument-access) (car (cdr argument-access)))) | |
2898 | (, value-form)))) | |
2899 | (argument-access | |
2900 | (` (setq (, argument-access) (, value-form)))) | |
2901 | (t (error "ad-set-argument: No argument at position %d of `%s'" | |
2902 | index arglist))))) | |
2903 | ||
2904 | (defun ad-get-arguments (arglist index) | |
2905 | ;;"Returns form to access all actual arguments starting at position INDEX." | |
2906 | (let* ((parsed-arglist (ad-parse-arglist arglist)) | |
2907 | (reqopt-args (append (nth 0 parsed-arglist) | |
2908 | (nth 1 parsed-arglist))) | |
2909 | (rest-arg (nth 2 parsed-arglist)) | |
2910 | args-form) | |
2911 | (if (< index (length reqopt-args)) | |
2912 | (setq args-form (` (list (,@ (nthcdr index reqopt-args)))))) | |
2913 | (if rest-arg | |
2914 | (if args-form | |
2915 | (setq args-form (` (nconc (, args-form) (, rest-arg)))) | |
2916 | (setq args-form (ad-list-access (- index (length reqopt-args)) | |
2917 | rest-arg)))) | |
2918 | args-form)) | |
2919 | ||
2920 | (defun ad-set-arguments (arglist index values-form) | |
2921 | ;;"Makes form to assign elements of VALUES-FORM as actual ARGLIST args. | |
2922 | ;;The assignment starts at position INDEX." | |
2923 | (let ((values-index 0) | |
2924 | argument-access set-forms) | |
2925 | (while (setq argument-access (ad-access-argument arglist index)) | |
2926 | (if (symbolp argument-access) | |
2927 | (setq set-forms | |
2928 | (cons (ad-set-argument | |
2929 | arglist index | |
2930 | (ad-element-access values-index 'ad-vAlUeS)) | |
2931 | set-forms)) | |
2932 | (setq set-forms | |
2933 | (cons (if (= (car argument-access) 0) | |
2934 | (list 'setq | |
2935 | (car (cdr argument-access)) | |
2936 | (ad-list-access values-index 'ad-vAlUeS)) | |
2937 | (list 'setcdr | |
2938 | (ad-list-access (1- (car argument-access)) | |
2939 | (car (cdr argument-access))) | |
2940 | (ad-list-access values-index 'ad-vAlUeS))) | |
2941 | set-forms)) | |
2942 | ;; terminate loop | |
2943 | (setq arglist nil)) | |
2944 | (setq index (1+ index)) | |
2945 | (setq values-index (1+ values-index))) | |
2946 | (if (null set-forms) | |
2947 | (error "ad-set-arguments: No argument at position %d of `%s'" | |
2948 | index arglist) | |
2949 | (if (= (length set-forms) 1) | |
2950 | ;; For exactly one set-form we can use values-form directly,... | |
2951 | (ad-substitute-tree | |
2952 | (function (lambda (form) (eq form 'ad-vAlUeS))) | |
2953 | (function (lambda (form) values-form)) | |
2954 | (car set-forms)) | |
2955 | ;; ...if we have more we have to bind it to a variable: | |
2956 | (` (let ((ad-vAlUeS (, values-form))) | |
2957 | (,@ (reverse set-forms)) | |
2958 | ;; work around the old backquote bug: | |
2959 | (, 'ad-vAlUeS))))))) | |
2960 | ||
2961 | (defun ad-insert-argument-access-forms (definition arglist) | |
2962 | ;;"Expands arg-access text macros in DEFINITION according to ARGLIST." | |
2963 | (ad-substitute-tree | |
2964 | (function | |
2965 | (lambda (form) | |
2966 | (or (eq form 'ad-arg-bindings) | |
2967 | (and (memq (car-safe form) | |
2968 | '(ad-get-arg ad-get-args ad-set-arg ad-set-args)) | |
2969 | (integerp (car-safe (cdr form))))))) | |
2970 | (function | |
2971 | (lambda (form) | |
2972 | (if (eq form 'ad-arg-bindings) | |
2973 | (ad-retrieve-args-form arglist) | |
2974 | (let ((accessor (car form)) | |
2975 | (index (car (cdr form))) | |
2976 | (val (car (cdr (ad-insert-argument-access-forms | |
2977 | (cdr form) arglist))))) | |
2978 | (cond ((eq accessor 'ad-get-arg) | |
2979 | (ad-get-argument arglist index)) | |
2980 | ((eq accessor 'ad-set-arg) | |
2981 | (ad-set-argument arglist index val)) | |
2982 | ((eq accessor 'ad-get-args) | |
2983 | (ad-get-arguments arglist index)) | |
2984 | ((eq accessor 'ad-set-args) | |
2985 | (ad-set-arguments arglist index val))))))) | |
2986 | definition)) | |
2987 | ||
2988 | ;; @@@ Mapping argument lists: | |
2989 | ;; =========================== | |
2990 | ;; Here is the problem: | |
2991 | ;; Suppose function foo was called with (foo 1 2 3 4 5), and foo has the | |
2992 | ;; argument list (x y &rest z), and we want to call the function bar which | |
2993 | ;; has argument list (a &rest b) with a combination of x, y and z so that | |
2994 | ;; the effect is just as if we had called (bar 1 2 3 4 5) directly. | |
2995 | ;; The mapping should work for any two argument lists. | |
2996 | ||
2997 | (defun ad-map-arglists (source-arglist target-arglist) | |
6e2f6f45 | 2998 | "Makes `funcall/apply' form to map SOURCE-ARGLIST to TARGET-ARGLIST. |
ee7bf2ad RM |
2999 | The arguments supplied to TARGET-ARGLIST will be taken from SOURCE-ARGLIST just |
3000 | as if they had been supplied to a function with TARGET-ARGLIST directly. | |
3001 | Excess source arguments will be neglected, missing source arguments will be | |
6e2f6f45 RS |
3002 | supplied as nil. Returns a `funcall' or `apply' form with the second element |
3003 | being `function' which has to be replaced by an actual function argument. | |
3004 | Example: `(ad-map-arglists '(a &rest args) '(w x y z))' will return | |
3005 | `(funcall function a (car args) (car (cdr args)) (nth 2 args))'." | |
ee7bf2ad RM |
3006 | (let* ((parsed-source-arglist (ad-parse-arglist source-arglist)) |
3007 | (source-reqopt-args (append (nth 0 parsed-source-arglist) | |
3008 | (nth 1 parsed-source-arglist))) | |
3009 | (source-rest-arg (nth 2 parsed-source-arglist)) | |
3010 | (parsed-target-arglist (ad-parse-arglist target-arglist)) | |
3011 | (target-reqopt-args (append (nth 0 parsed-target-arglist) | |
3012 | (nth 1 parsed-target-arglist))) | |
3013 | (target-rest-arg (nth 2 parsed-target-arglist)) | |
3014 | (need-apply (and source-rest-arg target-rest-arg)) | |
3015 | (target-arg-index -1)) | |
3016 | ;; This produces ``error-proof'' target function calls with the exception | |
3017 | ;; of a case like (&rest a) mapped onto (x &rest y) where the actual args | |
3018 | ;; supplied to A might not be enough to supply the required target arg X | |
3019 | (append (list (if need-apply 'apply 'funcall) 'function) | |
3020 | (cond (need-apply | |
3021 | ;; `apply' can take care of that directly: | |
3022 | (append source-reqopt-args (list source-rest-arg))) | |
3023 | (t (mapcar (function | |
3024 | (lambda (arg) | |
3025 | (setq target-arg-index (1+ target-arg-index)) | |
3026 | (ad-get-argument | |
3027 | source-arglist target-arg-index))) | |
3028 | (append target-reqopt-args | |
3029 | (and target-rest-arg | |
3030 | ;; If we have a rest arg gobble up | |
3031 | ;; remaining source args: | |
3032 | (nthcdr (length target-reqopt-args) | |
3033 | source-reqopt-args))))))))) | |
3034 | ||
3035 | (defun ad-make-mapped-call (source-arglist target-arglist target-function) | |
3036 | ;;"Makes form to call TARGET-FUNCTION with args from SOURCE-ARGLIST." | |
3037 | (let* ((mapped-form (ad-map-arglists source-arglist target-arglist))) | |
3038 | (if (eq (car mapped-form) 'funcall) | |
3039 | (cons target-function (cdr (cdr mapped-form))) | |
3040 | (prog1 mapped-form | |
3041 | (setcar (cdr mapped-form) (list 'quote target-function)))))) | |
3042 | ||
3043 | ;; @@@ Making an advised documentation string: | |
3044 | ;; =========================================== | |
3045 | ;; New policy: The documentation string for an advised function will be built | |
6e2f6f45 | 3046 | ;; at the time the advised `documentation' function is called. This has the |
ee7bf2ad RM |
3047 | ;; following advantages: |
3048 | ;; 1) command-key substitutions will automatically be correct | |
3049 | ;; 2) No wasted string space due to big advised docstrings in caches or | |
3050 | ;; compiled files that contain preactivations | |
3051 | ;; The overall overhead for this should be negligible because people normally | |
3052 | ;; don't lookup documentation for the same function over and over again. | |
3053 | ||
6e2f6f45 | 3054 | (defun ad-make-single-advice-docstring (advice class &optional style) |
ee7bf2ad | 3055 | (let ((advice-docstring (ad-docstring (ad-advice-definition advice)))) |
6e2f6f45 RS |
3056 | (cond ((eq style 'plain) |
3057 | advice-docstring) | |
3058 | ((eq style 'freeze) | |
3059 | (format "Permanent %s-advice `%s':%s%s" | |
3060 | class (ad-advice-name advice) | |
3061 | (if advice-docstring "\n" "") | |
3062 | (or advice-docstring ""))) | |
3063 | (t (format "%s-advice `%s':%s%s" | |
3064 | (capitalize (symbol-name class)) (ad-advice-name advice) | |
3065 | (if advice-docstring "\n" "") | |
3066 | (or advice-docstring "")))))) | |
3067 | ||
3068 | (defun ad-make-advised-docstring (function &optional style) | |
ee7bf2ad RM |
3069 | ;;"Constructs a documentation string for the advised FUNCTION. |
3070 | ;;It concatenates the original documentation with the documentation | |
6e2f6f45 RS |
3071 | ;;strings of the individual pieces of advice which will be formatted |
3072 | ;;according to STYLE. STYLE can be `plain' or `freeze', everything else | |
3073 | ;;will be interpreted as `default'. The order of the advice documentation | |
ee7bf2ad RM |
3074 | ;;strings corresponds to before/around/after and the individual ordering |
3075 | ;;in any of these classes." | |
3076 | (let* ((origdef (ad-real-orig-definition function)) | |
6e2f6f45 | 3077 | (origtype (symbol-name (ad-definition-type origdef))) |
ee7bf2ad | 3078 | (origdoc |
6e2f6f45 RS |
3079 | ;; Retrieve raw doc, key substitution will be taken care of later: |
3080 | (ad-real-documentation origdef t)) | |
3081 | paragraphs advice-docstring) | |
3082 | (if origdoc (setq paragraphs (list origdoc))) | |
3083 | (if (not (eq style 'plain)) | |
3084 | (setq paragraphs (cons (concat "This " origtype " is advised.") | |
3085 | paragraphs))) | |
3086 | (ad-dolist (class ad-advice-classes) | |
3087 | (ad-dolist (advice (ad-get-enabled-advices function class)) | |
3088 | (setq advice-docstring | |
3089 | (ad-make-single-advice-docstring advice class style)) | |
3090 | (if advice-docstring | |
3091 | (setq paragraphs (cons advice-docstring paragraphs))))) | |
3092 | (if paragraphs | |
3093 | ;; separate paragraphs with blank lines: | |
3094 | (mapconcat 'identity (nreverse paragraphs) "\n\n")))) | |
3095 | ||
3096 | (defun ad-make-plain-docstring (function) | |
3097 | (ad-make-advised-docstring function 'plain)) | |
3098 | (defun ad-make-freeze-docstring (function) | |
3099 | (ad-make-advised-docstring function 'freeze)) | |
ee7bf2ad RM |
3100 | |
3101 | ;; @@@ Accessing overriding arglists and interactive forms: | |
3102 | ;; ======================================================== | |
3103 | ||
3104 | (defun ad-advised-arglist (function) | |
3105 | ;;"Finds first defined arglist in FUNCTION's redefining advices." | |
3106 | (ad-dolist (advice (append (ad-get-enabled-advices function 'before) | |
3107 | (ad-get-enabled-advices function 'around) | |
3108 | (ad-get-enabled-advices function 'after))) | |
3109 | (let ((arglist (ad-arglist (ad-advice-definition advice)))) | |
3110 | (if arglist | |
3111 | ;; We found the first one, use it: | |
3112 | (ad-do-return arglist))))) | |
3113 | ||
3114 | (defun ad-advised-interactive-form (function) | |
3115 | ;;"Finds first interactive form in FUNCTION's redefining advices." | |
3116 | (ad-dolist (advice (append (ad-get-enabled-advices function 'before) | |
3117 | (ad-get-enabled-advices function 'around) | |
3118 | (ad-get-enabled-advices function 'after))) | |
3119 | (let ((interactive-form | |
3120 | (ad-interactive-form (ad-advice-definition advice)))) | |
3121 | (if interactive-form | |
3122 | ;; We found the first one, use it: | |
3123 | (ad-do-return interactive-form))))) | |
3124 | ||
3125 | ;; @@@ Putting it all together: | |
3126 | ;; ============================ | |
3127 | ||
3128 | (defun ad-make-advised-definition (function) | |
3129 | ;;"Generates an advised definition of FUNCTION from its advice info." | |
3130 | (if (and (ad-is-advised function) | |
3131 | (ad-has-redefining-advice function)) | |
3132 | (let* ((origdef (ad-real-orig-definition function)) | |
3133 | (origname (ad-get-advice-info-field function 'origname)) | |
3134 | (orig-interactive-p (ad-interactive-p origdef)) | |
3135 | (orig-subr-p (ad-subr-p origdef)) | |
3136 | (orig-special-form-p (ad-special-form-p origdef)) | |
3137 | (orig-macro-p (ad-macro-p origdef)) | |
3138 | ;; Construct the individual pieces that we need for assembly: | |
3139 | (orig-arglist (ad-arglist origdef function)) | |
3140 | (advised-arglist (or (ad-advised-arglist function) | |
3141 | orig-arglist)) | |
3142 | (advised-interactive-form (ad-advised-interactive-form function)) | |
3143 | (interactive-form | |
3144 | (cond (orig-macro-p nil) | |
3145 | (advised-interactive-form) | |
3146 | ((ad-interactive-form origdef)) | |
3147 | ;; Otherwise we must have a subr: make it interactive if | |
3148 | ;; we have to and initialize required arguments in case | |
3149 | ;; it is called interactively: | |
3150 | (orig-interactive-p | |
3151 | (let ((reqargs (car (ad-parse-arglist advised-arglist)))) | |
3152 | (if reqargs | |
3153 | (` (interactive | |
3154 | '(, (make-list (length reqargs) nil)))) | |
3155 | '(interactive)))))) | |
3156 | (orig-form | |
3157 | (cond ((or orig-special-form-p orig-macro-p) | |
3158 | ;; Special forms and macros will be advised into macros. | |
3159 | ;; The trick is to construct an expansion for the advised | |
3160 | ;; macro that does the correct thing when it gets eval'ed. | |
3161 | ;; For macros we'll just use the expansion of the original | |
3162 | ;; macro and return that. This way compiled advised macros | |
3163 | ;; will be expanded into something useful. Note that after | |
3164 | ;; advices have full control over whether they want to | |
3165 | ;; evaluate the expansion (the value of `ad-return-value') | |
3166 | ;; at macro expansion time or not. For special forms there | |
3167 | ;; is no solution that interacts reasonably with the | |
3168 | ;; compiler, hence we just evaluate the original at macro | |
3169 | ;; expansion time and return the result. The moral of that | |
3170 | ;; is that one should always deactivate advised special | |
3171 | ;; forms before one byte-compiles a file. | |
3172 | (` ((, (if orig-macro-p | |
3173 | 'macroexpand | |
3174 | 'eval)) | |
3175 | (cons '(, origname) | |
3176 | (, (ad-get-arguments advised-arglist 0)))))) | |
3177 | ((and orig-subr-p | |
3178 | orig-interactive-p | |
3179 | (not advised-interactive-form)) | |
3180 | ;; Check whether we were called interactively | |
3181 | ;; in order to do proper prompting: | |
3182 | (` (if (interactive-p) | |
3183 | (call-interactively '(, origname)) | |
3184 | (, (ad-make-mapped-call | |
3185 | orig-arglist advised-arglist origname))))) | |
3186 | ;; And now for normal functions and non-interactive subrs | |
3187 | ;; (or subrs whose interactive behavior was advised): | |
3188 | (t (ad-make-mapped-call | |
3189 | advised-arglist orig-arglist origname))))) | |
3190 | ||
3191 | ;; Finally, build the sucker: | |
3192 | (ad-assemble-advised-definition | |
3193 | (cond (orig-macro-p 'macro) | |
3194 | (orig-special-form-p 'special-form) | |
3195 | (t 'function)) | |
3196 | advised-arglist | |
3197 | (ad-make-advised-definition-docstring function) | |
3198 | interactive-form | |
3199 | orig-form | |
3200 | (ad-get-enabled-advices function 'before) | |
3201 | (ad-get-enabled-advices function 'around) | |
3202 | (ad-get-enabled-advices function 'after))))) | |
3203 | ||
3204 | (defun ad-assemble-advised-definition | |
3205 | (type args docstring interactive orig &optional befores arounds afters) | |
3206 | ||
3207 | ;;"Assembles an original and its advices into an advised function. | |
3208 | ;;It constructs a function or macro definition according to TYPE which has to | |
6e2f6f45 RS |
3209 | ;;be either `macro', `function' or `special-form'. ARGS is the argument list |
3210 | ;;that has to be used, DOCSTRING if non-nil defines the documentation of the | |
3211 | ;;definition, INTERACTIVE if non-nil is the interactive form to be used, | |
ee7bf2ad RM |
3212 | ;;ORIG is a form that calls the body of the original unadvised function, |
3213 | ;;and BEFORES, AROUNDS and AFTERS are the lists of advices with which ORIG | |
6e2f6f45 | 3214 | ;;should be modified. The assembled function will be returned." |
ee7bf2ad RM |
3215 | |
3216 | (let (before-forms around-form around-form-protected after-forms definition) | |
3217 | (ad-dolist (advice befores) | |
3218 | (cond ((and (ad-advice-protected advice) | |
3219 | before-forms) | |
3220 | (setq before-forms | |
3221 | (` ((unwind-protect | |
3222 | (, (ad-prognify before-forms)) | |
3223 | (,@ (ad-body-forms | |
3224 | (ad-advice-definition advice)))))))) | |
3225 | (t (setq before-forms | |
3226 | (append before-forms | |
3227 | (ad-body-forms (ad-advice-definition advice))))))) | |
3228 | ||
3229 | (setq around-form (` (setq ad-return-value (, orig)))) | |
3230 | (ad-dolist (advice (reverse arounds)) | |
3231 | ;; If any of the around advices is protected then we | |
3232 | ;; protect the complete around advice onion: | |
3233 | (if (ad-advice-protected advice) | |
3234 | (setq around-form-protected t)) | |
3235 | (setq around-form | |
3236 | (ad-substitute-tree | |
3237 | (function (lambda (form) (eq form 'ad-do-it))) | |
3238 | (function (lambda (form) around-form)) | |
3239 | (ad-prognify (ad-body-forms (ad-advice-definition advice)))))) | |
3240 | ||
3241 | (setq after-forms | |
3242 | (if (and around-form-protected before-forms) | |
3243 | (` ((unwind-protect | |
3244 | (, (ad-prognify before-forms)) | |
3245 | (, around-form)))) | |
3246 | (append before-forms (list around-form)))) | |
3247 | (ad-dolist (advice afters) | |
3248 | (cond ((and (ad-advice-protected advice) | |
3249 | after-forms) | |
3250 | (setq after-forms | |
3251 | (` ((unwind-protect | |
3252 | (, (ad-prognify after-forms)) | |
3253 | (,@ (ad-body-forms | |
3254 | (ad-advice-definition advice)))))))) | |
3255 | (t (setq after-forms | |
3256 | (append after-forms | |
3257 | (ad-body-forms (ad-advice-definition advice))))))) | |
3258 | ||
3259 | (setq definition | |
3260 | (` ((,@ (if (memq type '(macro special-form)) '(macro))) | |
3261 | lambda | |
3262 | (, args) | |
3263 | (,@ (if docstring (list docstring))) | |
3264 | (,@ (if interactive (list interactive))) | |
3265 | (let (ad-return-value) | |
3266 | (,@ after-forms) | |
3267 | (, (if (eq type 'special-form) | |
3268 | '(list 'quote ad-return-value) | |
3269 | 'ad-return-value)))))) | |
3270 | ||
3271 | (ad-insert-argument-access-forms definition args))) | |
3272 | ||
3273 | ;; This is needed for activation/deactivation hooks: | |
3274 | (defun ad-make-hook-form (function hook-name) | |
3275 | ;;"Makes hook-form from FUNCTION's advice bodies in class HOOK-NAME." | |
3276 | (let ((hook-forms | |
3277 | (mapcar (function (lambda (advice) | |
3278 | (ad-body-forms (ad-advice-definition advice)))) | |
3279 | (ad-get-enabled-advices function hook-name)))) | |
3280 | (if hook-forms | |
3281 | (ad-prognify (apply 'append hook-forms))))) | |
3282 | ||
3283 | ||
3284 | ;; @@ Caching: | |
3285 | ;; =========== | |
3286 | ;; Generating an advised definition of a function is moderately expensive, | |
3287 | ;; hence, it makes sense to cache it so we can reuse it in appropriate | |
3288 | ;; circumstances. Of course, it only makes sense to reuse a cached | |
3289 | ;; definition if the current advice and function definition state is the | |
3290 | ;; same as it was at the time when the cached definition was generated. | |
3291 | ;; For that purpose we associate every cache with an id so we can verify | |
6e2f6f45 | 3292 | ;; if it is still valid at a certain point in time. This id mechanism |
ee7bf2ad RM |
3293 | ;; makes it possible to preactivate advised functions, write the compiled |
3294 | ;; advised definitions to a file and reuse them during the actual | |
3295 | ;; activation without having to risk that the resulting definition will be | |
3296 | ;; incorrect, well, almost. | |
3297 | ;; | |
3298 | ;; A cache id is a list with six elements: | |
3299 | ;; 1) the list of names of enabled before advices | |
3300 | ;; 2) the list of names of enabled around advices | |
3301 | ;; 3) the list of names of enabled after advices | |
3302 | ;; 4) the type of the original function (macro, subr, etc.) | |
3303 | ;; 5) the arglist of the original definition (or t if it was equal to the | |
3304 | ;; arglist of the cached definition) | |
3305 | ;; 6) t if the interactive form of the original definition was equal to the | |
3306 | ;; interactive form of the cached definition | |
3307 | ;; | |
3308 | ;; Here's how a cache can get invalidated or be incorrect: | |
3309 | ;; A) a piece of advice used in the cache gets redefined | |
3310 | ;; B) the current list of enabled advices is different from the ones used | |
3311 | ;; for the cache | |
3312 | ;; C) the type of the original function changed, e.g., a function became a | |
3313 | ;; macro, or a subr became a function | |
3314 | ;; D) the arglist of the original function changed | |
3315 | ;; E) the interactive form of the original function changed | |
3316 | ;; F) a piece of advice used in the cache got redefined before the | |
3317 | ;; defadvice with the cached definition got loaded: This is a PROBLEM! | |
3318 | ;; | |
6e2f6f45 | 3319 | ;; Cases A and B are the normal ones. A is taken care of by `ad-add-advice' |
ee7bf2ad RM |
3320 | ;; which clears the cache in such a case, B is easily checked during |
3321 | ;; verification at activation time. | |
3322 | ;; | |
3323 | ;; Cases C, D and E have to be considered if one is slightly paranoid, i.e., | |
3324 | ;; if one considers the case that the original function could be different | |
3325 | ;; from the one available at caching time (e.g., for forward advice of | |
3326 | ;; functions that get redefined by some packages - such as `eval-region' gets | |
6e2f6f45 RS |
3327 | ;; redefined by edebug). All these cases can be easily checked during |
3328 | ;; verification. Element 4 of the id lets one check case C, element 5 takes | |
ee7bf2ad RM |
3329 | ;; care of case D (using t in the equality case saves some space, because the |
3330 | ;; arglist can be recovered at validation time from the cached definition), | |
3331 | ;; and element 6 takes care of case E which is only a problem if the original | |
3332 | ;; was actually a function whose interactive form was not overridden by a | |
3333 | ;; piece of advice. | |
3334 | ;; | |
3335 | ;; Case F is the only one which will lead to an incorrect advised function. | |
3336 | ;; There is no way to avoid this without storing the complete advice definition | |
3337 | ;; in the cache-id which is not feasible. | |
3338 | ;; | |
3339 | ;; The cache-id of a typical advised function with one piece of advice and | |
3340 | ;; no arglist redefinition takes 7 conses which is a small price to pay for | |
6e2f6f45 | 3341 | ;; the added efficiency. The validation itself is also pretty cheap, certainly |
ee7bf2ad RM |
3342 | ;; a lot cheaper than reconstructing an advised definition. |
3343 | ||
3344 | (defmacro ad-get-cache-definition (function) | |
3345 | (` (car (ad-get-advice-info-field (, function) 'cache)))) | |
3346 | ||
3347 | (defmacro ad-get-cache-id (function) | |
3348 | (` (cdr (ad-get-advice-info-field (, function) 'cache)))) | |
3349 | ||
3350 | (defmacro ad-set-cache (function definition id) | |
3351 | (` (ad-set-advice-info-field | |
3352 | (, function) 'cache (cons (, definition) (, id))))) | |
3353 | ||
3354 | (defun ad-clear-cache (function) | |
3355 | "Clears a previously cached advised definition of FUNCTION. | |
3356 | Clear the cache if you want to force `ad-activate' to construct a new | |
3357 | advised definition from scratch." | |
3358 | (interactive | |
3359 | (list (ad-read-advised-function "Clear cached definition of: "))) | |
3360 | (ad-set-advice-info-field function 'cache nil)) | |
3361 | ||
3362 | (defun ad-make-cache-id (function) | |
3363 | ;;"Generates an identifying image of the current advices of FUNCTION." | |
3364 | (let ((original-definition (ad-real-orig-definition function)) | |
3365 | (cached-definition (ad-get-cache-definition function))) | |
3366 | (list (mapcar (function (lambda (advice) (ad-advice-name advice))) | |
3367 | (ad-get-enabled-advices function 'before)) | |
3368 | (mapcar (function (lambda (advice) (ad-advice-name advice))) | |
3369 | (ad-get-enabled-advices function 'around)) | |
3370 | (mapcar (function (lambda (advice) (ad-advice-name advice))) | |
3371 | (ad-get-enabled-advices function 'after)) | |
3372 | (ad-definition-type original-definition) | |
3373 | (if (equal (ad-arglist original-definition function) | |
3374 | (ad-arglist cached-definition)) | |
3375 | t | |
3376 | (ad-arglist original-definition function)) | |
3377 | (if (eq (ad-definition-type original-definition) 'function) | |
3378 | (equal (ad-interactive-form original-definition) | |
3379 | (ad-interactive-form cached-definition)))))) | |
3380 | ||
3381 | (defun ad-get-cache-class-id (function class) | |
3382 | ;;"Returns the part of FUNCTION's cache id that identifies CLASS." | |
3383 | (let ((cache-id (ad-get-cache-id function))) | |
3384 | (if (eq class 'before) | |
3385 | (car cache-id) | |
3386 | (if (eq class 'around) | |
3387 | (nth 1 cache-id) | |
3388 | (nth 2 cache-id))))) | |
3389 | ||
3390 | (defun ad-verify-cache-class-id (cache-class-id advices) | |
3391 | (ad-dolist (advice advices (null cache-class-id)) | |
3392 | (if (ad-advice-enabled advice) | |
3393 | (if (eq (car cache-class-id) (ad-advice-name advice)) | |
3394 | (setq cache-class-id (cdr cache-class-id)) | |
3395 | (ad-do-return nil))))) | |
3396 | ||
3397 | ;; There should be a way to monitor if and why a cache verification failed | |
3398 | ;; in order to determine whether a certain preactivation could be used or | |
6e2f6f45 RS |
3399 | ;; not. Right now the only way to find out is to trace |
3400 | ;; `ad-cache-id-verification-code'. The code it returns indicates where the | |
3401 | ;; verification failed. Tracing `ad-verify-cache-class-id' might provide | |
ee7bf2ad RM |
3402 | ;; some additional useful information. |
3403 | ||
3404 | (defun ad-cache-id-verification-code (function) | |
3405 | (let ((cache-id (ad-get-cache-id function)) | |
3406 | (code 'before-advice-mismatch)) | |
3407 | (and (ad-verify-cache-class-id | |
3408 | (car cache-id) (ad-get-advice-info-field function 'before)) | |
3409 | (setq code 'around-advice-mismatch) | |
3410 | (ad-verify-cache-class-id | |
3411 | (nth 1 cache-id) (ad-get-advice-info-field function 'around)) | |
3412 | (setq code 'after-advice-mismatch) | |
3413 | (ad-verify-cache-class-id | |
3414 | (nth 2 cache-id) (ad-get-advice-info-field function 'after)) | |
3415 | (setq code 'definition-type-mismatch) | |
3416 | (let ((original-definition (ad-real-orig-definition function)) | |
3417 | (cached-definition (ad-get-cache-definition function))) | |
3418 | (and (eq (nth 3 cache-id) (ad-definition-type original-definition)) | |
3419 | (setq code 'arglist-mismatch) | |
3420 | (equal (if (eq (nth 4 cache-id) t) | |
3421 | (ad-arglist original-definition function) | |
3422 | (nth 4 cache-id) ) | |
3423 | (ad-arglist cached-definition)) | |
3424 | (setq code 'interactive-form-mismatch) | |
3425 | (or (null (nth 5 cache-id)) | |
3426 | (equal (ad-interactive-form original-definition) | |
3427 | (ad-interactive-form cached-definition))) | |
3428 | (setq code 'verified)))) | |
3429 | code)) | |
3430 | ||
3431 | (defun ad-verify-cache-id (function) | |
3432 | ;;"True if FUNCTION's cache-id is compatible with its current advices." | |
3433 | (eq (ad-cache-id-verification-code function) 'verified)) | |
3434 | ||
3435 | ||
3436 | ;; @@ Preactivation: | |
3437 | ;; ================= | |
3438 | ;; Preactivation can be used to generate compiled advised definitions | |
3439 | ;; at compile time without having to give up the dynamic runtime flexibility | |
6e2f6f45 | 3440 | ;; of the advice mechanism. Preactivation is a special feature of `defadvice', |
ee7bf2ad RM |
3441 | ;; it involves the following steps: |
3442 | ;; - remembering the function's current state (definition and advice-info) | |
3443 | ;; - advising it with the defined piece of advice | |
3444 | ;; - clearing its cache | |
3445 | ;; - generating an interpreted advised definition by activating it, this will | |
3446 | ;; make use of all its current active advice and its current definition | |
3447 | ;; - saving the so generated cached definition and id | |
3448 | ;; - resetting the function's advice and definition state to what it was | |
3449 | ;; before the preactivation | |
3450 | ;; - Returning the saved definition and its id to be used in the expansion of | |
3451 | ;; `defadvice' to assign it as an initial cache, hence it will be compiled | |
6e2f6f45 | 3452 | ;; at time the `defadvice' gets compiled. |
ee7bf2ad RM |
3453 | ;; Naturally, for preactivation to be effective it has to be applied/compiled |
3454 | ;; at the right time, i.e., when the current state of advices and function | |
6e2f6f45 | 3455 | ;; definition exactly reflects the state at activation time. Should that not |
ee7bf2ad RM |
3456 | ;; be the case, the precompiled definition will just be discarded and a new |
3457 | ;; advised definition will be generated. | |
3458 | ||
3459 | (defun ad-preactivate-advice (function advice class position) | |
3460 | ;;"Preactivates FUNCTION and returns the constructed cache." | |
3461 | (let* ((function-defined-p (fboundp function)) | |
3462 | (old-definition | |
3463 | (if function-defined-p | |
3464 | (symbol-function function))) | |
3465 | (old-advice-info (ad-copy-advice-info function)) | |
3466 | (ad-advised-functions ad-advised-functions)) | |
3467 | (unwind-protect | |
3468 | (progn | |
3469 | (ad-add-advice function advice class position) | |
3470 | (ad-enable-advice function class (ad-advice-name advice)) | |
3471 | (ad-clear-cache function) | |
3472 | (ad-activate function nil) | |
3473 | (if (and (ad-is-active function) | |
3474 | (ad-get-cache-definition function)) | |
3475 | (list (ad-get-cache-definition function) | |
3476 | (ad-get-cache-id function)))) | |
3477 | (ad-set-advice-info function old-advice-info) | |
3478 | ;; Don't `fset' function to nil if it was previously unbound: | |
3479 | (if function-defined-p | |
3480 | (ad-real-fset function old-definition) | |
3481 | (fmakunbound function))))) | |
3482 | ||
3483 | (defun ad-activate-advised-definition (function compile) | |
3484 | ;;"Redefines FUNCTION with its advised definition from cache or scratch. | |
6e2f6f45 | 3485 | ;;If COMPILE is true the resulting FUNCTION will be compiled. The current |
ee7bf2ad RM |
3486 | ;;definition and its cache-id will be put into the cache." |
3487 | (let ((verified-cached-definition | |
3488 | (if (ad-verify-cache-id function) | |
3489 | (ad-get-cache-definition function)))) | |
3490 | (ad-real-fset function | |
3491 | (or verified-cached-definition | |
3492 | (ad-make-advised-definition function))) | |
3493 | (if compile (ad-compile-function function)) | |
3494 | (if verified-cached-definition | |
3495 | (if (not (eq verified-cached-definition (symbol-function function))) | |
3496 | ;; we must have compiled, cache the compiled definition: | |
3497 | (ad-set-cache | |
3498 | function (symbol-function function) (ad-get-cache-id function))) | |
3499 | ;; We created a new advised definition, cache it with a proper id: | |
3500 | (ad-clear-cache function) | |
3501 | ;; ad-make-cache-id needs the new cached definition: | |
3502 | (ad-set-cache function (symbol-function function) nil) | |
3503 | (ad-set-cache | |
3504 | function (symbol-function function) (ad-make-cache-id function))))) | |
3505 | ||
3506 | (defun ad-handle-definition (function) | |
3507 | "Handles re/definition of an advised FUNCTION during de/activation. | |
3508 | If FUNCTION does not have an original definition associated with it and | |
3509 | the current definition is usable, then it will be stored as FUNCTION's | |
6e2f6f45 RS |
3510 | original definition. If no current definition is available (even in the |
3511 | case of undefinition) nothing will be done. In the case of redefinition | |
ee7bf2ad | 3512 | the action taken depends on the value of `ad-redefinition-action' (which |
6e2f6f45 | 3513 | see). Redefinition occurs when FUNCTION already has an original definition |
ee7bf2ad | 3514 | associated with it but got redefined with a new definition and then |
6e2f6f45 | 3515 | de/activated. If you do not like the current redefinition action change |
ee7bf2ad RM |
3516 | the value of `ad-redefinition-action' and de/activate again." |
3517 | (let ((original-definition (ad-get-orig-definition function)) | |
3518 | (current-definition (if (ad-real-definition function) | |
3519 | (symbol-function function)))) | |
3520 | (if original-definition | |
3521 | (if current-definition | |
3522 | (if (and (not (eq current-definition original-definition)) | |
3523 | ;; Redefinition with an advised definition from a | |
3524 | ;; different function won't count as such: | |
3525 | (not (ad-advised-definition-p current-definition))) | |
3526 | ;; we have a redefinition: | |
3527 | (if (not (memq ad-redefinition-action '(accept discard warn))) | |
3528 | (error "ad-handle-definition (see its doc): `%s' %s" | |
3529 | function "illegally redefined") | |
3530 | (if (eq ad-redefinition-action 'discard) | |
3531 | (ad-real-fset function original-definition) | |
3532 | (ad-set-orig-definition function current-definition) | |
3533 | (if (eq ad-redefinition-action 'warn) | |
3534 | (message "ad-handle-definition: `%s' got redefined" | |
3535 | function)))) | |
3536 | ;; either advised def or correct original is in place: | |
3537 | nil) | |
3538 | ;; we have an undefinition, ignore it: | |
3539 | nil) | |
3540 | (if current-definition | |
3541 | ;; we have a first definition, save it as original: | |
3542 | (ad-set-orig-definition function current-definition) | |
3543 | ;; we don't have anything noteworthy: | |
3544 | nil)))) | |
3545 | ||
3546 | ||
3547 | ;; @@ The top-level advice interface: | |
3548 | ;; ================================== | |
3549 | ||
3550 | (defun ad-activate (function &optional compile) | |
3551 | "Activates all the advice information of an advised FUNCTION. | |
3552 | If FUNCTION has a proper original definition then an advised | |
3553 | definition will be generated from FUNCTION's advice info and the | |
6e2f6f45 RS |
3554 | definition of FUNCTION will be replaced with it. If a previously |
3555 | cached advised definition was available, it will be used. With an | |
3556 | argument (COMPILE is non-nil) the resulting function (or a compilable | |
3557 | cached definition) will also be compiled. Activation of an advised | |
ee7bf2ad RM |
3558 | function that has an advice info but no actual pieces of advice is |
3559 | equivalent to a call to `ad-unadvise'. Activation of an advised | |
3560 | function that has actual pieces of advice but none of them are enabled | |
6e2f6f45 | 3561 | is equivalent to a call to `ad-deactivate'. The current advised |
ee7bf2ad RM |
3562 | definition will always be cached for later usage." |
3563 | (interactive | |
3564 | (list (ad-read-advised-function "Activate advice of: ") | |
3565 | current-prefix-arg)) | |
3566 | (if (not (ad-is-advised function)) | |
3567 | (error "ad-activate: `%s' is not advised" function) | |
3568 | (ad-handle-definition function) | |
3569 | ;; Just return for forward advised and not yet defined functions: | |
3570 | (if (ad-get-orig-definition function) | |
3571 | (if (not (ad-has-any-advice function)) | |
3572 | (ad-unadvise function) | |
3573 | ;; Otherwise activate the advice: | |
3574 | (cond ((ad-has-redefining-advice function) | |
3575 | (ad-activate-advised-definition function compile) | |
3576 | (ad-set-advice-info-field function 'active t) | |
3577 | (eval (ad-make-hook-form function 'activation)) | |
3578 | function) | |
3579 | ;; Here we are if we have all disabled advices: | |
3580 | (t (ad-deactivate function))))))) | |
3581 | ||
3582 | (defun ad-deactivate (function) | |
3583 | "Deactivates the advice of an actively advised FUNCTION. | |
3584 | If FUNCTION has a proper original definition, then the current | |
6e2f6f45 | 3585 | definition of FUNCTION will be replaced with it. All the advice |
ee7bf2ad RM |
3586 | information will still be available so it can be activated again with |
3587 | a call to `ad-activate'." | |
3588 | (interactive | |
3589 | (list (ad-read-advised-function "Deactivate advice of: " 'ad-is-active))) | |
3590 | (if (not (ad-is-advised function)) | |
3591 | (error "ad-deactivate: `%s' is not advised" function) | |
3592 | (cond ((ad-is-active function) | |
3593 | (ad-handle-definition function) | |
3594 | (if (not (ad-get-orig-definition function)) | |
3595 | (error "ad-deactivate: `%s' has no original definition" | |
3596 | function) | |
3597 | (ad-real-fset function (ad-get-orig-definition function)) | |
3598 | (ad-set-advice-info-field function 'active nil) | |
3599 | (eval (ad-make-hook-form function 'deactivation)) | |
3600 | function))))) | |
3601 | ||
3602 | (defun ad-update (function &optional compile) | |
3603 | "Update the advised definition of FUNCTION if its advice is active. | |
3604 | With a prefix argument or if the current definition is compiled compile the | |
3605 | resulting advised definition." | |
3606 | (interactive | |
3607 | (list (ad-read-advised-function | |
3608 | "Update advised definition of: " 'ad-is-active))) | |
3609 | (if (ad-is-active function) | |
3610 | (ad-activate | |
3611 | function (or compile (ad-compiled-p (symbol-function function)))))) | |
3612 | ||
3613 | (defun ad-unadvise (function) | |
3614 | "Deactivates FUNCTION and then removes all its advice information. | |
3615 | If FUNCTION was not advised this will be a noop." | |
3616 | (interactive | |
3617 | (list (ad-read-advised-function "Unadvise function: "))) | |
3618 | (cond ((ad-is-advised function) | |
3619 | (if (ad-is-active function) | |
3620 | (ad-deactivate function)) | |
3621 | (ad-clear-orig-definition function) | |
3622 | (ad-set-advice-info function nil) | |
3623 | (ad-pop-advised-function function)))) | |
3624 | ||
3625 | (defun ad-recover (function) | |
3626 | "Tries to recover FUNCTION's original definition and unadvises it. | |
3627 | This is more low-level than `ad-unadvise' because it does not do any | |
3628 | deactivation which might run hooks and get into other trouble. | |
3629 | Use in emergencies." | |
3630 | ;; Use more primitive interactive behavior here: Accept any symbol that's | |
3631 | ;; currently defined in obarray, not necessarily with a function definition: | |
3632 | (interactive | |
3633 | (list (intern | |
3634 | (completing-read "Recover advised function: " obarray nil t)))) | |
3635 | (cond ((ad-is-advised function) | |
3636 | (cond ((ad-get-orig-definition function) | |
3637 | (ad-real-fset function (ad-get-orig-definition function)) | |
3638 | (ad-clear-orig-definition function))) | |
3639 | (ad-set-advice-info function nil) | |
3640 | (ad-pop-advised-function function)))) | |
3641 | ||
3642 | (defun ad-activate-regexp (regexp &optional compile) | |
3643 | "Activates functions with an advice name containing a REGEXP match. | |
3644 | With prefix argument compiles resulting advised definitions." | |
3645 | (interactive | |
3646 | (list (ad-read-regexp "Activate via advice regexp: ") | |
3647 | current-prefix-arg)) | |
3648 | (ad-do-advised-functions (function) | |
3649 | (if (ad-find-some-advice function 'any regexp) | |
3650 | (ad-activate function compile)))) | |
3651 | ||
3652 | (defun ad-deactivate-regexp (regexp) | |
3653 | "Deactivates functions with an advice name containing REGEXP match." | |
3654 | (interactive | |
3655 | (list (ad-read-regexp "Deactivate via advice regexp: "))) | |
3656 | (ad-do-advised-functions (function) | |
3657 | (if (ad-find-some-advice function 'any regexp) | |
3658 | (ad-deactivate function)))) | |
3659 | ||
3660 | (defun ad-update-regexp (regexp &optional compile) | |
3661 | "Updates functions with an advice name containing a REGEXP match. | |
3662 | With prefix argument compiles resulting advised definitions." | |
3663 | (interactive | |
3664 | (list (ad-read-regexp "Update via advice regexp: ") | |
3665 | current-prefix-arg)) | |
3666 | (ad-do-advised-functions (function) | |
3667 | (if (ad-find-some-advice function 'any regexp) | |
3668 | (ad-update function compile)))) | |
3669 | ||
3670 | (defun ad-activate-all (&optional compile) | |
3671 | "Activates all currently advised functions. | |
3672 | With prefix argument compiles resulting advised definitions." | |
3673 | (interactive "P") | |
3674 | (ad-do-advised-functions (function) | |
3675 | (ad-activate function))) | |
3676 | ||
3677 | (defun ad-deactivate-all () | |
3678 | "Deactivates all currently advised functions." | |
3679 | (interactive) | |
3680 | (ad-do-advised-functions (function) | |
3681 | (ad-deactivate function))) | |
3682 | ||
3683 | (defun ad-update-all (&optional compile) | |
3684 | "Updates all currently advised functions. | |
3685 | With prefix argument compiles resulting advised definitions." | |
3686 | (interactive "P") | |
3687 | (ad-do-advised-functions (function) | |
3688 | (ad-update function compile))) | |
3689 | ||
3690 | (defun ad-unadvise-all () | |
3691 | "Unadvises all currently advised functions." | |
3692 | (interactive) | |
3693 | (ad-do-advised-functions (function) | |
3694 | (ad-unadvise function))) | |
3695 | ||
3696 | (defun ad-recover-all () | |
6e2f6f45 | 3697 | "Recovers all currently advised functions. Use in emergencies." |
ee7bf2ad RM |
3698 | (interactive) |
3699 | (ad-do-advised-functions (function) | |
6e2f6f45 | 3700 | (condition-case nil |
ee7bf2ad RM |
3701 | (ad-recover function) |
3702 | (error nil)))) | |
3703 | ||
3704 | ||
3705 | ;; Completion alist of legal `defadvice' flags | |
3706 | (defvar ad-defadvice-flags | |
6e2f6f45 RS |
3707 | '(("protect") ("disable") ("activate") |
3708 | ("compile") ("preactivate") ("freeze"))) | |
ee7bf2ad RM |
3709 | |
3710 | ;;;###autoload | |
3711 | (defmacro defadvice (function args &rest body) | |
3712 | "Defines a piece of advice for FUNCTION (a symbol). | |
6e2f6f45 RS |
3713 | The syntax of `defadvice' is as follows: |
3714 | ||
3715 | (defadvice FUNCTION (CLASS NAME [POSITION] [ARGLIST] FLAG...) | |
3716 | [DOCSTRING] [INTERACTIVE-FORM] | |
3717 | BODY... ) | |
3718 | ||
3719 | FUNCTION ::= Name of the function to be advised. | |
3720 | CLASS ::= `before' | `around' | `after' | `activation' | `deactivation'. | |
3721 | NAME ::= Non-nil symbol that names this piece of advice. | |
3722 | POSITION ::= `first' | `last' | NUMBER. Optional, defaults to `first', | |
3723 | see also `ad-add-advice'. | |
3724 | ARGLIST ::= An optional argument list to be used for the advised function | |
3725 | instead of the argument list of the original. The first one found in | |
3726 | before/around/after-advices will be used. | |
3727 | FLAG ::= `protect'|`disable'|`activate'|`compile'|`preactivate'|`freeze'. | |
ee7bf2ad | 3728 | All flags can be specified with unambiguous initial substrings. |
6e2f6f45 RS |
3729 | DOCSTRING ::= Optional documentation for this piece of advice. |
3730 | INTERACTIVE-FORM ::= Optional interactive form to be used for the advised | |
3731 | function. The first one found in before/around/after-advices will be used. | |
3732 | BODY ::= Any s-expression. | |
ee7bf2ad RM |
3733 | |
3734 | Semantics of the various flags: | |
3735 | `protect': The piece of advice will be protected against non-local exits in | |
6e2f6f45 RS |
3736 | any code that precedes it. If any around-advice of a function is protected |
3737 | then automatically all around-advices will be protected (the complete onion). | |
ee7bf2ad RM |
3738 | |
3739 | `activate': All advice of FUNCTION will be activated immediately if | |
6e2f6f45 | 3740 | FUNCTION has been properly defined prior to this application of `defadvice'. |
ee7bf2ad RM |
3741 | |
3742 | `compile': In conjunction with `activate' specifies that the resulting | |
3743 | advised function should be compiled. | |
3744 | ||
6e2f6f45 | 3745 | `disable': The defined advice will be disabled, hence, it will not be used |
ee7bf2ad RM |
3746 | during activation until somebody enables it. |
3747 | ||
6e2f6f45 RS |
3748 | `preactivate': Preactivates the advised FUNCTION at macro-expansion/compile |
3749 | time. This generates a compiled advised definition according to the current | |
3750 | advice state that will be used during activation if appropriate. Only use | |
3751 | this if the `defadvice' gets actually compiled. | |
ee7bf2ad | 3752 | |
6e2f6f45 RS |
3753 | `freeze': Expands the `defadvice' into a redefining `defun/defmacro' according |
3754 | to the current advice state. No other advice information will be saved. | |
3755 | Frozen advices cannot be undone, they behave like a hard redefinition of | |
3756 | the advised function. `freeze' implies `activate' and `preactivate'. The | |
3757 | documentation of the advised function can be dumped onto the `DOC' file | |
3758 | during preloading. | |
3759 | ||
3760 | Look at the file `advice.el' for comprehensive documentation." | |
ee7bf2ad RM |
3761 | (if (not (ad-name-p function)) |
3762 | (error "defadvice: Illegal function name: %s" function)) | |
3763 | (let* ((class (car args)) | |
3764 | (name (if (not (ad-class-p class)) | |
3765 | (error "defadvice: Illegal advice class: %s" class) | |
3766 | (nth 1 args))) | |
3767 | (position (if (not (ad-name-p name)) | |
3768 | (error "defadvice: Illegal advice name: %s" name) | |
3769 | (setq args (nthcdr 2 args)) | |
3770 | (if (ad-position-p (car args)) | |
3771 | (prog1 (car args) | |
3772 | (setq args (cdr args)))))) | |
3773 | (arglist (if (listp (car args)) | |
3774 | (prog1 (car args) | |
3775 | (setq args (cdr args))))) | |
3776 | (flags | |
3777 | (mapcar | |
3778 | (function | |
3779 | (lambda (flag) | |
3780 | (let ((completion | |
3781 | (try-completion (symbol-name flag) ad-defadvice-flags))) | |
3782 | (cond ((eq completion t) flag) | |
3783 | ((assoc completion ad-defadvice-flags) | |
3784 | (intern completion)) | |
3785 | (t (error "defadvice: Illegal or ambiguous flag: %s" | |
3786 | flag)))))) | |
3787 | args)) | |
3788 | (advice (ad-make-advice | |
3789 | name (memq 'protect flags) | |
3790 | (not (memq 'disable flags)) | |
3791 | (` (advice lambda (, arglist) (,@ body))))) | |
3792 | (preactivation (if (memq 'preactivate flags) | |
3793 | (ad-preactivate-advice | |
6e2f6f45 RS |
3794 | function advice class position))) |
3795 | unique-origname | |
3796 | (redefinition | |
3797 | (if (memq 'freeze flags) | |
3798 | (ad-with-originals (ad-make-advised-definition-docstring | |
3799 | ad-make-origname) | |
3800 | ;; Make sure we construct the actual docstring: | |
3801 | (fset 'ad-make-advised-definition-docstring | |
3802 | 'ad-make-freeze-docstring) | |
3803 | ;; With a unique origname we can have multiple freeze advices | |
3804 | ;; for the same function, each overloading the previous one: | |
3805 | (setq unique-origname | |
3806 | (intern (format "%s-%s-%s" | |
3807 | (ad-make-origname function) class name))) | |
3808 | (fset 'ad-make-origname '(lambda (x) unique-origname)) | |
3809 | (if (not (ad-has-proper-definition function)) | |
3810 | (error | |
3811 | "defadvice: `freeze' needs proper definition of `%s'" | |
3812 | function)) | |
3813 | (ad-preactivate-advice function advice class position))))) | |
ee7bf2ad | 3814 | ;; Now for the things to be done at evaluation time: |
6e2f6f45 RS |
3815 | (if redefinition |
3816 | ;; jwz's idea: Freeze the advised definition into a dumpable | |
3817 | ;; defun/defmacro whose docs can be written to the DOC file: | |
3818 | (let* ((macro-p (ad-macro-p (car redefinition))) | |
3819 | (body (cdr (if macro-p | |
3820 | (ad-lambdafy (car redefinition)) | |
3821 | (car redefinition))))) | |
3822 | (` (progn | |
3823 | (if (not (fboundp '(, unique-origname))) | |
3824 | (fset '(, unique-origname) (symbol-function '(, function)))) | |
3825 | ((, (if macro-p 'defmacro 'defun)) | |
3826 | (, function) | |
3827 | (,@ body))))) | |
3828 | ;; the normal case: | |
3829 | (` (progn | |
3830 | (ad-add-advice '(, function) '(, advice) '(, class) '(, position)) | |
3831 | (,@ (if preactivation | |
3832 | (` ((ad-set-cache | |
3833 | '(, function) | |
3834 | ;; the function will get compiled: | |
3835 | (, (cond ((ad-macro-p (car preactivation)) | |
3836 | (` (ad-macrofy | |
3837 | (function | |
3838 | (, (ad-lambdafy | |
3839 | (car preactivation))))))) | |
3840 | (t (` (function | |
3841 | (, (car preactivation))))))) | |
3842 | '(, (car (cdr preactivation)))))))) | |
3843 | (,@ (if (memq 'activate flags) | |
3844 | (` ((ad-activate '(, function) | |
3845 | (, (if (memq 'compile flags) t))))))) | |
3846 | '(, function)))))) | |
ee7bf2ad RM |
3847 | |
3848 | ||
3849 | ;; @@ Tools: | |
3850 | ;; ========= | |
3851 | ||
3852 | (defmacro ad-with-originals (functions &rest body) | |
3853 | "Binds FUNCTIONS to their original definitions and executes BODY. | |
3854 | For any members of FUNCTIONS that are not currently advised the rebinding will | |
6e2f6f45 | 3855 | be a noop. Any modifications done to the definitions of FUNCTIONS will be |
ee7bf2ad RM |
3856 | undone on exit of this macro." |
3857 | (let* ((index -1) | |
3858 | ;; Make let-variables to store current definitions: | |
3859 | (current-bindings | |
3860 | (mapcar (function | |
3861 | (lambda (function) | |
3862 | (setq index (1+ index)) | |
3863 | (list (intern (format "ad-oRiGdEf-%d" index)) | |
3864 | (` (symbol-function '(, function)))))) | |
3865 | functions))) | |
3866 | (` (let (, current-bindings) | |
3867 | (unwind-protect | |
3868 | (progn | |
3869 | (,@ (progn | |
3870 | ;; Make forms to redefine functions to their | |
3871 | ;; original definitions if they are advised: | |
3872 | (setq index -1) | |
3873 | (mapcar | |
3874 | (function | |
3875 | (lambda (function) | |
3876 | (setq index (1+ index)) | |
3877 | (` (ad-real-fset | |
3878 | '(, function) | |
3879 | (or (ad-get-orig-definition '(, function)) | |
3880 | (, (car (nth index current-bindings)))))))) | |
3881 | functions))) | |
3882 | (,@ body)) | |
3883 | (,@ (progn | |
3884 | ;; Make forms to back-define functions to the definitions | |
3885 | ;; they had outside this macro call: | |
3886 | (setq index -1) | |
3887 | (mapcar | |
3888 | (function | |
3889 | (lambda (function) | |
3890 | (setq index (1+ index)) | |
3891 | (` (ad-real-fset | |
3892 | '(, function) | |
3893 | (, (car (nth index current-bindings))))))) | |
3894 | functions)))))))) | |
3895 | ||
3896 | (if (not (get 'ad-with-originals 'lisp-indent-hook)) | |
3897 | (put 'ad-with-originals 'lisp-indent-hook 1)) | |
3898 | ||
3899 | ||
3900 | ;; @@ Advising `defun', `defmacro', `fset' and `documentation' | |
3901 | ;; =========================================================== | |
3902 | ;; Use the advice mechanism to advise defun/defmacro/fset so we can forward | |
3903 | ;; advise functions that might be defined later during load/autoload. | |
3904 | ;; Enabling forward advice was the original motivation for doing this, it | |
3905 | ;; has now been generalized to running definition hooks so other packages | |
3906 | ;; can make use of this sort of functionality too. | |
3907 | ||
3908 | (defvar ad-defined-function nil) | |
3909 | ||
3910 | (defun ad-activate-defined-function (&optional function) | |
3911 | "Activates the advice of an advised and defined FUNCTION. | |
3912 | If the current definition of FUNCTION is byte-compiled then the advised | |
6e2f6f45 | 3913 | definition will be compiled too. FUNCTION defaults to the value of |
ee7bf2ad RM |
3914 | `ad-defined-function'." |
3915 | (if (and (null function) | |
3916 | ad-defined-function) | |
3917 | (setq function ad-defined-function)) | |
3918 | (if (and (ad-is-advised function) | |
3919 | (ad-real-definition function)) | |
3920 | (ad-activate function (ad-compiled-p (symbol-function function))))) | |
3921 | ||
6e2f6f45 RS |
3922 | (defvar ad-advised-definers |
3923 | '(defun defmacro fset defalias define-function)) | |
ee7bf2ad RM |
3924 | |
3925 | (defadvice defun (after ad-definition-hooks first disable preact) | |
3926 | "Whenever a function gets re/defined with `defun' all hook functions | |
3927 | in `ad-definition-hooks' will be run after the re/definition with | |
3928 | `ad-defined-function' bound to the name of the function." | |
3929 | (let ((ad-defined-function (ad-get-arg 0))) | |
3930 | (run-hooks 'ad-definition-hooks))) | |
3931 | ||
3932 | (defadvice defmacro (after ad-definition-hooks first disable preact) | |
3933 | "Whenever a macro gets re/defined with `defmacro' all hook functions | |
3934 | in `ad-definition-hooks' will be run after the re/definition with | |
3935 | `ad-defined-function' bound to the name of the function." | |
3936 | (let ((ad-defined-function (ad-get-arg 0))) | |
3937 | (run-hooks 'ad-definition-hooks))) | |
3938 | ||
3939 | (defadvice fset (after ad-definition-hooks first disable preact) | |
3940 | "Whenever a function gets re/defined with `fset' all hook functions | |
3941 | in `ad-definition-hooks' will be run after the re/definition with | |
6e2f6f45 | 3942 | `ad-defined-function' bound to the name of the function. This advice was |
ee7bf2ad RM |
3943 | mainly created to handle forward-advice for byte-compiled files created |
3944 | by jwz's byte-compiler used in Lemacs. | |
3945 | CAUTION: If you need the primitive `fset' behavior either deactivate | |
3946 | its advice or use `ad-real-fset' instead!" | |
3947 | (let ((ad-defined-function (ad-get-arg 0))) | |
3948 | (run-hooks 'ad-definition-hooks))) | |
3949 | ||
6e2f6f45 | 3950 | ;; In Lemacs this is just a noop: |
ee7bf2ad RM |
3951 | (defadvice defalias (after ad-definition-hooks first disable preact) |
3952 | "Whenever a function gets re/defined with `defalias' all hook functions | |
3953 | in `ad-definition-hooks' will be run after the re/definition with | |
6e2f6f45 | 3954 | `ad-defined-function' bound to the name of the function." |
ee7bf2ad RM |
3955 | (let ((ad-defined-function (ad-get-arg 0))) |
3956 | ;; The new `byte-compile' uses `defalias' to set the definition which | |
3957 | ;; leads to infinite recursion if it gets to use the advised version | |
3958 | ;; (with `fset' this didn't matter because the compiled `byte-compile' | |
6e2f6f45 | 3959 | ;; called it via its byte-code). Should there be a general provision to |
ee7bf2ad RM |
3960 | ;; avoid recursive application of definition hooks? |
3961 | (ad-with-originals (defalias) | |
3962 | (run-hooks 'ad-definition-hooks)))) | |
3963 | ||
6e2f6f45 RS |
3964 | ;; Needed for Emacs (seems to be an identical copy of `defalias', but |
3965 | ;; it is used in `simple.el' and might be used later, hence, advise it): | |
ee7bf2ad RM |
3966 | (defadvice define-function (after ad-definition-hooks first disable preact) |
3967 | "Whenever a function gets re/defined with `define-function' all hook | |
3968 | functions in `ad-definition-hooks' will be run after the re/definition with | |
3969 | `ad-defined-function' bound to the name of the function." | |
3970 | (let ((ad-defined-function (ad-get-arg 0))) | |
3971 | (ad-with-originals (define-function) | |
3972 | (run-hooks 'ad-definition-hooks)))) | |
3973 | ||
3974 | (defadvice documentation (after ad-advised-docstring first disable preact) | |
3975 | "Builds an advised docstring if FUNCTION is advised." | |
3976 | ;; Because we get the function name from the advised docstring | |
3977 | ;; this will work for function names as well as for definitions: | |
3978 | (if (and (stringp ad-return-value) | |
3979 | (string-match | |
3980 | ad-advised-definition-docstring-regexp ad-return-value)) | |
3981 | (let ((function | |
3982 | (car (read-from-string | |
3983 | ad-return-value (match-beginning 1) (match-end 1))))) | |
3984 | (cond ((ad-is-advised function) | |
3985 | (setq ad-return-value (ad-make-advised-docstring function)) | |
6e2f6f45 | 3986 | ;; Handle optional `raw' argument: |
ee7bf2ad RM |
3987 | (if (not (ad-get-arg 1)) |
3988 | (setq ad-return-value | |
3989 | (substitute-command-keys ad-return-value)))))))) | |
835cd48e | 3990 | |
6e2f6f45 RS |
3991 | ;; The following two advised functions are a (hopefully temporary) kludge |
3992 | ;; to fix a problem with the compilation of embedded (or non-top-level) | |
3993 | ;; `defun/defmacro's when automatic activation of advice is enabled. For | |
3994 | ;; the time of the compilation they backdefine `defun/defmacro' to their | |
3995 | ;; original definition to make sure they are not treated as plain macros. | |
3996 | ;; Both advices are forward advices, hence, they will only be activated if | |
3997 | ;; automatic advice activation is enabled, but since that is the actual | |
3998 | ;; situation where we have a problem, we can be sure that the advices will | |
f643a891 RS |
3999 | ;; be active when we need them. |
4000 | ||
4001 | ;; We only need this in Lemacs, because in Emacs it is | |
4002 | ;; now taken care of directly by the byte-compiler: | |
4003 | (cond ((ad-lemacs-p) | |
4004 | ||
4005 | (defvar ad-advised-byte-compilers | |
4006 | '(byte-compile-from-buffer byte-compile-top-level)) | |
6e2f6f45 RS |
4007 | |
4008 | (defadvice byte-compile-from-buffer (around ad-deactivate-defun-defmacro | |
4009 | first disable preact) | |
4010 | "Deactivates `defun/defmacro' for proper compilation when they are embedded." | |
4011 | (let (;; make sure no `require' starts them again by accident: | |
4012 | (ad-advised-definers '(fset defalias define-function))) | |
4013 | (ad-with-originals (defun defmacro) | |
4014 | ad-do-it))) | |
4015 | ||
4016 | (defadvice byte-compile-top-level (around ad-deactivate-defun-defmacro | |
4017 | first disable preact) | |
4018 | "Deactivates `defun/defmacro' for proper compilation when they are embedded." | |
4019 | (let (;; make sure no `require' starts them again by accident: | |
4020 | (ad-advised-definers '(fset defalias define-function))) | |
4021 | (ad-with-originals (defun defmacro) | |
4022 | ad-do-it))) | |
4023 | ||
f643a891 RS |
4024 | )) ;; end of cond |
4025 | ||
6e2f6f45 RS |
4026 | ;; Make sure advice-infos are not allocated in pure space |
4027 | ;; (this might not be necessary anymore): | |
4028 | (ad-dolist (advised-function (cons 'documentation | |
4029 | (append ad-advised-definers | |
f643a891 RS |
4030 | (if (ad-lemacs-p) |
4031 | ad-advised-byte-compilers)))) | |
835cd48e | 4032 | (ad-set-advice-info advised-function (ad-copy-advice-info advised-function))) |
ee7bf2ad | 4033 | |
ee7bf2ad RM |
4034 | |
4035 | ;; @@ Forward advice support for jwz's byte-compiler (M-x serious-HACK-mode-on) | |
4036 | ;; ============================================================================ | |
4037 | ;; Jamie Zawinski's optimizing byte-compiler used in v19 (and by some daring | |
4038 | ;; folks in v18) produces compiled files that do not define functions via | |
4039 | ;; explicit calls to `defun/defmacro', it rather uses `fset' for functions with | |
4040 | ;; documentation strings, and hunks of byte-code for sets of functions without | |
6e2f6f45 | 4041 | ;; any documentation. In Jamie's byte-compiler a series of compiled functions |
ee7bf2ad RM |
4042 | ;; without docstrings get hunked as |
4043 | ;; (progn (fset 'f1 <code1>) (fset 'f2 <code2>) ...). | |
4044 | ;; The resulting progn will be compiled and the compiled form will be written | |
6e2f6f45 | 4045 | ;; to the compiled file as `(byte-code [progn-code] [constants] [depth])'. To |
ee7bf2ad | 4046 | ;; handle forward advice we have to know when functions get defined so we can |
6e2f6f45 | 4047 | ;; activate any advice there might be. For standard v18 byte-compiled files |
ee7bf2ad RM |
4048 | ;; we can do this by simply advising `defun/defmacro' because these subrs are |
4049 | ;; evaluated explicitly when such a file is loaded. For Jamie's v19 compiler | |
4050 | ;; our only choice is to additionally advise `fset' and change the subr | |
4051 | ;; `byte-code' such that it analyzes its byte-code string looking for fset's | |
4052 | ;; when we are currently loading a file. In v19 the general overhead caused | |
4053 | ;; by the advice of `byte-code' shouldn't be too bad, because byte-compiled | |
6e2f6f45 | 4054 | ;; functions do not call byte-code explicitly (as done in v18). In v18 this |
ee7bf2ad RM |
4055 | ;; is a problem because with the changed `byte-code' function function calls |
4056 | ;; become more expensive. | |
4057 | ;; | |
4058 | ;; Wish-List: | |
4059 | ;; - special defining functions for use in byte-compiled files, e.g., | |
4060 | ;; `byte-compile-fset' and `byte-code-tl' which do the same as their | |
4061 | ;; standard brothers, but which can be advised for forward advice without | |
4062 | ;; the problems that advising `byte-code' generates. | |
4063 | ;; - More generally, a symbol definition hook that could be used for | |
4064 | ;; forward advice and related purposes. | |
4065 | ;; | |
4066 | ;; Until then: For the analysis of the byte-code string we simply scan it for | |
4067 | ;; an `fset' opcode (M in ascii) that is preceded by two constant references, | |
4068 | ;; the first of which points to the function name and the second to its code. | |
4069 | ;; A constant reference can either be a simple one-byte one, or a three-byte | |
6e2f6f45 RS |
4070 | ;; one if the function has more than 64 constants. The scanning can pretty |
4071 | ;; efficiently be done with a regular expression. Here it goes: | |
ee7bf2ad RM |
4072 | |
4073 | ;; Have to hardcode these opcodes if I don't | |
4074 | ;; want to require the byte-compiler: | |
4075 | (defvar byte-constant 192) | |
4076 | (defvar byte-constant-limit 64) | |
4077 | (defvar byte-constant2 129) | |
4078 | (defvar byte-fset 77) | |
4079 | ||
4080 | ;; Matches a byte-compiled fset operation with two constant arguments: | |
4081 | (defvar ad-byte-code-fset-regexp | |
4082 | (let* ((constant-reference | |
4083 | (format "[%s-%s]" | |
4084 | (char-to-string byte-constant) | |
4085 | (char-to-string (+ byte-constant (1- byte-constant-limit))))) | |
4086 | (constant2-reference | |
4087 | ;; \0 makes it necessary to use concat instead of format in 18.57: | |
4088 | (concat (char-to-string byte-constant2) "[\0-\377][\0-\377]")) | |
4089 | (fset-opcode (char-to-string byte-fset))) | |
4090 | (concat "\\(" constant-reference "\\|" constant2-reference "\\)" | |
4091 | "\\(" constant-reference "\\|" constant2-reference "\\)" | |
4092 | fset-opcode))) | |
4093 | ||
4094 | (defun ad-find-fset-in-byte-code (code constants start) | |
4095 | ;;"Finds the first two-constant fset operation in CODE after START. | |
4096 | ;;Returns a three element list consisting of the name of the defined | |
4097 | ;;function, its code (both taken from the CONSTANTS vector), and an | |
4098 | ;;advanced start index." | |
4099 | (let ((start | |
4100 | ;; The odd case that this regexp matches something that isn't an | |
4101 | ;; actual fset operation is handled by additional tests and a | |
4102 | ;; condition handler in ad-scan-byte-code-for-fsets: | |
4103 | (string-match ad-byte-code-fset-regexp code start)) | |
4104 | name-index code-index) | |
4105 | (cond (start | |
4106 | (cond ((= (aref code start) byte-constant2) | |
4107 | (setq name-index | |
4108 | (+ (aref code (setq start (1+ start))) | |
4109 | (* (aref code (setq start (1+ start))) 256))) | |
4110 | (setq start (1+ start))) | |
4111 | (t (setq name-index (- (aref code start) byte-constant)) | |
4112 | (setq start (1+ start)))) | |
4113 | (cond ((= (aref code start) byte-constant2) | |
4114 | (setq code-index | |
4115 | (+ (aref code (setq start (1+ start))) | |
4116 | (* (aref code (setq start (1+ start))) 256))) | |
4117 | (setq start (1+ start))) | |
4118 | (t (setq code-index (- (aref code start) byte-constant)) | |
4119 | (setq start (1+ start)))) | |
4120 | (list (aref constants name-index) | |
4121 | (aref constants code-index) | |
4122 | ;; start points to fset opcode: | |
4123 | start)) | |
4124 | (t nil)))) | |
4125 | ||
4126 | (defun ad-scan-byte-code-for-fsets (ad-code ad-constants) | |
4127 | ;; In case anything in here goes wrong we reset `byte-code' to its real | |
6e2f6f45 | 4128 | ;; identity. In particular, the handler of the condition-case uses |
ee7bf2ad RM |
4129 | ;; `byte-code', so it better be the real one if we have an error: |
4130 | (ad-real-fset 'byte-code (symbol-function 'ad-real-byte-code)) | |
6e2f6f45 | 4131 | (condition-case nil |
ee7bf2ad RM |
4132 | (let ((fset-args '(0 0 0))) |
4133 | (while (setq fset-args (ad-find-fset-in-byte-code | |
4134 | ad-code ad-constants | |
4135 | (car (cdr (cdr fset-args))))) | |
4136 | (if (and (symbolp (car fset-args)) | |
4137 | (fboundp (car fset-args)) | |
4138 | (eq (symbol-function (car fset-args)) | |
4139 | (car (cdr fset-args)))) | |
4140 | ;; We've found an fset that was executed during this call | |
4141 | ;; to byte-code, and whose definition is still eq to the | |
4142 | ;; current definition of the defined function: | |
4143 | (let ((ad-defined-function (car fset-args))) | |
4144 | (run-hooks 'ad-definition-hooks)))) | |
4145 | ;; Everything worked fine, readvise `byte-code': | |
4146 | (ad-real-fset 'byte-code (symbol-function 'ad-advised-byte-code))) | |
4147 | (error nil))) | |
4148 | ||
4149 | ;; CAUTION: Don't try this at home!! Changing `byte-code' is a | |
4150 | ;; pretty suicidal activity. | |
4151 | ;; To allow v19 forward advice we cannot advise `byte-code' as a subr as | |
4152 | ;; we did for `defun' etc., because `ad-subr-args' of the advised | |
4153 | ;; `byte-code' would shield references to `ad-subr-args' in the body of | |
4154 | ;; v18 compiled advised subrs such as `defun', and, more importantly, the | |
4155 | ;; changed version of `byte-code' has to be as small and efficient as | |
4156 | ;; possible because it is used in every call to a compiled function. | |
4157 | ;; Hence, we previously saved its original definition and redefine it as | |
4158 | ;; the following function - yuck: | |
4159 | ||
4160 | ;; The arguments will scope around the body of every byte-compiled | |
4161 | ;; function, hence they have to be obscure enough to not be equal to any | |
4162 | ;; global or argument variable referenced by any compiled function: | |
6e2f6f45 RS |
4163 | (defun ad-advised-byte-code (ad-cOdE ad-cOnStAnTs ad-dEpTh) |
4164 | "Modified version of `byte-code' subr used by the Advice package. | |
ee7bf2ad | 4165 | `byte-code' has been modified to allow automatic activation of forward |
6e2f6f45 | 4166 | advice for functions that are defined in byte-compiled files. |
ee7bf2ad RM |
4167 | See `ad-real-byte-code' for original documentation." |
4168 | (prog1 (ad-real-byte-code ad-cOdE ad-cOnStAnTs ad-dEpTh) | |
4169 | (if load-in-progress | |
4170 | (ad-scan-byte-code-for-fsets ad-cOdE ad-cOnStAnTs)))) | |
4171 | ||
ee7bf2ad RM |
4172 | (defun ad-recover-byte-code () |
4173 | "Recovers the real `byte-code' functionality." | |
4174 | (interactive) | |
4175 | (ad-real-fset 'byte-code (symbol-function 'ad-real-byte-code))) | |
4176 | ||
ee7bf2ad RM |
4177 | (defun ad-enable-definition-hooks () |
4178 | ;;"Enables definition hooks by redefining definition primitives. | |
6e2f6f45 RS |
4179 | ;;Activates the advice of defun/defmacro/fset and redefines `byte-code'. |
4180 | ;;Redefining these primitives might lead to problems. Use | |
4181 | ;;`ad-disable-definition-hooks' or `ad-stop-advice' in such a case | |
4182 | ;;to establish a safe state." | |
4183 | (ad-dolist (definer ad-advised-definers) | |
ee7bf2ad RM |
4184 | (ad-enable-advice definer 'after 'ad-definition-hooks) |
4185 | (ad-activate definer 'compile)) | |
f643a891 RS |
4186 | (if (ad-lemacs-p) |
4187 | (ad-dolist (byte-compiler ad-advised-byte-compilers) | |
4188 | (ad-enable-advice byte-compiler 'around 'ad-deactivate-defun-defmacro) | |
4189 | (ad-activate byte-compiler 'compile))) | |
6e2f6f45 RS |
4190 | ;; Now redefine byte-code... |
4191 | (ad-real-fset 'byte-code (symbol-function 'ad-advised-byte-code))) | |
ee7bf2ad RM |
4192 | |
4193 | (defun ad-disable-definition-hooks () | |
4194 | ;;"Disables definition hooks by resetting definition primitives." | |
4195 | (ad-recover-byte-code) | |
6e2f6f45 RS |
4196 | (ad-dolist (definer ad-advised-definers) |
4197 | (ad-disable-advice definer 'after 'ad-definition-hooks) | |
4198 | (ad-update definer)) | |
f643a891 RS |
4199 | (if (ad-lemacs-p) |
4200 | (ad-dolist (byte-compiler ad-advised-byte-compilers) | |
4201 | (ad-disable-advice byte-compiler 'around 'ad-deactivate-defun-defmacro) | |
4202 | (ad-update byte-compiler 'compile)))) | |
ee7bf2ad RM |
4203 | |
4204 | ||
4205 | ;; @@ Starting, stopping and recovering from the advice package magic: | |
4206 | ;; =================================================================== | |
4207 | ||
4208 | ;;;###autoload | |
4209 | (defun ad-start-advice () | |
4210 | "Redefines some primitives to start the advice magic. | |
4211 | If `ad-activate-on-definition' is t then advice information will | |
4212 | automatically get activated whenever an advised function gets defined or | |
4213 | redefined. This will enable goodies such as forward advice and | |
6e2f6f45 | 4214 | automatically enable function definition hooks. If its value is nil but |
ee7bf2ad RM |
4215 | the value of `ad-enable-definition-hooks' is t then definition hooks |
4216 | will be enabled without having automatic advice activation, otherwise | |
6e2f6f45 | 4217 | function definition hooks will be disabled too. If definition hooks are |
ee7bf2ad RM |
4218 | enabled then functions stored in `ad-definition-hooks' are run whenever |
4219 | a function gets defined or redefined." | |
4220 | (interactive) | |
4221 | (ad-enable-advice 'documentation 'after 'ad-advised-docstring) | |
4222 | (ad-activate 'documentation 'compile) | |
4223 | (if (or ad-activate-on-definition | |
4224 | ad-enable-definition-hooks) | |
4225 | (ad-enable-definition-hooks) | |
4226 | (ad-disable-definition-hooks)) | |
4227 | (setq ad-definition-hooks | |
4228 | (if ad-activate-on-definition | |
4229 | (if (memq 'ad-activate-defined-function ad-definition-hooks) | |
4230 | ad-definition-hooks | |
4231 | (cons 'ad-activate-defined-function ad-definition-hooks)) | |
4232 | (delq 'ad-activate-defined-function ad-definition-hooks)))) | |
4233 | ||
4234 | (defun ad-stop-advice () | |
4235 | "Undefines some primitives to stop the advice magic. | |
4236 | This can also be used to recover from advice related emergencies." | |
4237 | (interactive) | |
4238 | (ad-recover-byte-code) | |
4239 | (ad-disable-advice 'documentation 'after 'ad-advised-docstring) | |
4240 | (ad-update 'documentation) | |
4241 | (ad-disable-definition-hooks) | |
4242 | (setq ad-definition-hooks | |
4243 | (delq 'ad-activate-defined-function ad-definition-hooks))) | |
4244 | ||
ee7bf2ad RM |
4245 | (defun ad-recover-normality () |
4246 | "Undoes all advice related redefinitions and unadvises everything. | |
4247 | Use only in REAL emergencies." | |
4248 | (interactive) | |
4249 | (ad-recover-byte-code) | |
4250 | (ad-recover-all) | |
4251 | (setq ad-advised-functions nil)) | |
4252 | ||
ee7bf2ad RM |
4253 | (if (and ad-start-advice-on-load |
4254 | ;; ...but only if we are compiled: | |
6e2f6f45 | 4255 | (ad-compiled-p (symbol-function 'ad-start-advice))) |
ee7bf2ad RM |
4256 | (ad-start-advice)) |
4257 | ||
4258 | (provide 'advice) | |
4259 | ||
4260 | ;;; advice.el ends here | |
f643a891 | 4261 |