annotate lisp/emacs-lisp/advice.el @ 72863:526dc1f36b09

(produce_image_glyph): Automatically crop wide images at right window edge so we can draw the cursor on the same row to avoid confusing redisplay by placing the cursor outside the visible window area.
author Kim F. Storm <storm@cua.dk>
date Thu, 14 Sep 2006 09:37:44 +0000
parents b920ab84fba8
children 25e1db3fd0ed a8190f7e546e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1 ;;; advice.el --- an overloading mechanism for Emacs Lisp functions
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2
64751
5b1a238fcbb4 Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents: 64085
diff changeset
3 ;; Copyright (C) 1993, 1994, 2000, 2001, 2004,
68648
067115a6e738 Update years in copyright notice; nfc.
Thien-Thi Nguyen <ttn@gnuvola.org>
parents: 66398
diff changeset
4 ;; 2005, 2006 Free Software Foundation, Inc.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
5
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
6 ;; Author: Hans Chalupsky <hans@cs.buffalo.edu>
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
7 ;; Maintainer: FSF
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
8 ;; Created: 12 Dec 1992
5140
9cde7d7fea1f Comment change.
Richard M. Stallman <rms@gnu.org>
parents: 5138
diff changeset
9 ;; Keywords: extensions, lisp, tools
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
10
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
11 ;; This file is part of GNU Emacs.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
12
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
13 ;; GNU Emacs is free software; you can redistribute it and/or modify
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
14 ;; it under the terms of the GNU General Public License as published by
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
15 ;; the Free Software Foundation; either version 2, or (at your option)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
16 ;; any later version.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
17
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
18 ;; GNU Emacs is distributed in the hope that it will be useful,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
21 ;; GNU General Public License for more details.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
22
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
23 ;; You should have received a copy of the GNU General Public License
14169
83f275dcd93a Update FSF's address.
Erik Naggum <erik@naggum.no>
parents: 11035
diff changeset
24 ;; along with GNU Emacs; see the file COPYING. If not, write to the
64085
18a818a2ee7c Update FSF's address.
Lute Kamstra <lute@gnu.org>
parents: 60923
diff changeset
25 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18a818a2ee7c Update FSF's address.
Lute Kamstra <lute@gnu.org>
parents: 60923
diff changeset
26 ;; Boston, MA 02110-1301, USA.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
27
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
28 ;; LCD Archive Entry:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
29 ;; advice|Hans Chalupsky|hans@cs.buffalo.edu|
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
30 ;; Overloading mechanism for Emacs Lisp functions|
8458
a95ca44cec95 (ad-subr-arglist): Adapted to new DOC file format.
Richard M. Stallman <rms@gnu.org>
parents: 8445
diff changeset
31 ;; 1994/08/05 03:42:04|2.14|~/packages/advice.el.Z|
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
32
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
33
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
34 ;;; Commentary:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
35
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
36 ;; NOTE: This documentation is slightly out of date. In particular, all the
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
37 ;; references to Emacs-18 are obsolete now, because it is not any longer
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
38 ;; supported by this version of Advice.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
39
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
40 ;; Advice is documented in the Emacs Lisp Manual.
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
41
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
42 ;; @ Introduction:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
43 ;; ===============
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
44 ;; This package implements a full-fledged Lisp-style advice mechanism
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
45 ;; for Emacs Lisp. Advice is a clean and efficient way to modify the
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
46 ;; behavior of Emacs Lisp functions without having to keep personal
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
47 ;; modified copies of such functions around. A great number of such
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
48 ;; modifications can be achieved by treating the original function as a
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
49 ;; black box and specifying a different execution environment for it
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
50 ;; with a piece of advice. Think of a piece of advice as a kind of fancy
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
51 ;; hook that you can attach to any function/macro/subr.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
52
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
53 ;; @ Highlights:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
54 ;; =============
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
55 ;; - Clean definition of multiple, named before/around/after advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
56 ;; for functions, macros, subrs and special forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
57 ;; - Full control over the arguments an advised function will receive,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
58 ;; the binding environment in which it will be executed, as well as the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
59 ;; value it will return.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
60 ;; - Allows re/definition of interactive behavior for functions and subrs
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
61 ;; - Every piece of advice can have its documentation string which will be
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
62 ;; combined with the original documentation of the advised function at
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
63 ;; call-time of `documentation' for proper command-key substitution.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
64 ;; - The execution of every piece of advice can be protected against error
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
65 ;; and non-local exits in preceding code or advices.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
66 ;; - Simple argument access either by name, or, more portable but as
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
67 ;; efficient, via access macros
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
68 ;; - Allows the specification of a different argument list for the advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
69 ;; version of a function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
70 ;; - Advised functions can be byte-compiled either at file-compile time
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
71 ;; (see preactivation) or activation time.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
72 ;; - Separation of advice definition and activation
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
73 ;; - Forward advice is possible, that is
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
74 ;; as yet undefined or autoload functions can be advised without having to
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
75 ;; preload the file in which they are defined.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
76 ;; - Forward redefinition is possible because around advice can be used to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
77 ;; completely redefine a function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
78 ;; - A caching mechanism for advised definition provides for cheap deactivation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
79 ;; and reactivation of advised functions.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
80 ;; - Preactivation allows efficient construction and compilation of advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
81 ;; definitions at file compile time without giving up the flexibility of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
82 ;; the advice mechanism.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
83 ;; - En/disablement mechanism allows the use of different "views" of advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
84 ;; functions depending on what pieces of advice are currently en/disabled
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
85 ;; - Provides manipulation mechanisms for sets of advised functions via
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
86 ;; regular expressions that match advice names
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
87
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
88 ;; @ How to get Advice for Emacs-18:
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
89 ;; =================================
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
90 ;; `advice18.el', a version of Advice that also works in Emacs-18 is available
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
91 ;; either via anonymous ftp from `ftp.cs.buffalo.edu (128.205.32.9)' with
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
92 ;; pathname `/pub/Emacs/advice18.el', or from one of the Emacs Lisp archive
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
93 ;; sites, or send email to <hans@cs.buffalo.edu> and I'll mail it to you.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
94
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
95 ;; @ Overview, or how to read this file:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
96 ;; =====================================
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
97 ;; NOTE: This documentation is slightly out of date. In particular, all the
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
98 ;; references to Emacs-18 are obsolete now, because it is not any longer
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
99 ;; supported by this version of Advice. An up-to-date version will soon be
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
100 ;; available as an info file (thanks to the kind help of Jack Vinson and
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
101 ;; David M. Smith). Until then you can use `outline-mode' to help you read
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
102 ;; this documentation (set `outline-regexp' to `";; @+"').
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
103 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
104 ;; The four major sections of this file are:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
105 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
106 ;; @ This initial information ...installation, customization etc.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
107 ;; @ Advice documentation: ...general documentation
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
108 ;; @ Foo games: An advice tutorial ...teaches about Advice by example
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
109 ;; @ Advice implementation: ...actual code, yeah!!
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
110 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
111 ;; The latter three are actual headings which you can search for
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
112 ;; directly in case `outline-mode' doesn't work for you.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
113
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
114 ;; @ Restrictions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
115 ;; ===============
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
116 ;; - This version of Advice only works for Emacs 19.26 and later. It uses
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
117 ;; new versions of the built-in functions `fset/defalias' which are not
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
118 ;; yet available in Lucid Emacs, hence, it won't work there.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
119 ;; - Advised functions/macros/subrs will only exhibit their advised behavior
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
120 ;; when they are invoked via their function cell. This means that advice will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
121 ;; not work for the following:
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
122 ;; + advised subrs that are called directly from other subrs or C-code
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
123 ;; + advised subrs that got replaced with their byte-code during
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
124 ;; byte-compilation (e.g., car)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
125 ;; + advised macros which were expanded during byte-compilation before
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
126 ;; their advice was activated.
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
127
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
128 ;; @ Credits:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
129 ;; ==========
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
130 ;; This package is an extension and generalization of packages such as
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
131 ;; insert-hooks.el written by Noah S. Friedman, and advise.el written by
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
132 ;; Raul J. Acevedo. Some ideas used in here come from these packages,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
133 ;; others come from the various Lisp advice mechanisms I've come across
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
134 ;; so far, and a few are simply mine.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
135
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
136 ;; @ Comments, suggestions, bug reports:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
137 ;; =====================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
138 ;; If you find any bugs, have suggestions for new advice features, find the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
139 ;; documentation wrong, confusing, incomplete, or otherwise unsatisfactory,
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
140 ;; have any questions about Advice, or have otherwise enlightening
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
141 ;; comments feel free to send me email at <hans@cs.buffalo.edu>.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
142
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
143 ;; @ Safety Rules and Emergency Exits:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
144 ;; ===================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
145 ;; Before we begin: CAUTION!!
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
146 ;; Advice provides you with a lot of rope to hang yourself on very
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
147 ;; easily accessible trees, so, here are a few important things you
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
148 ;; should know: Once Advice has been started with `ad-start-advice'
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
149 ;; (which happens automatically when you load this file), it
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
150 ;; generates an advised definition of the `documentation' function, and
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
151 ;; it will enable automatic advice activation when functions get defined.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
152 ;; All of this can be undone at any time with `M-x ad-stop-advice'.
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
153 ;;
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
154 ;; If you experience any strange behavior/errors etc. that you attribute to
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
155 ;; Advice or to some ill-advised function do one of the following:
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
156
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
157 ;; - M-x ad-deactivate FUNCTION (if you have a definite suspicion what
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
158 ;; function gives you problems)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
159 ;; - M-x ad-deactivate-all (if you don't have a clue what's going wrong)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
160 ;; - M-x ad-stop-advice (if you think the problem is related to the
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
161 ;; advised functions used by Advice itself)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
162 ;; - M-x ad-recover-normality (for real emergencies)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
163 ;; - If none of the above solves your Advice-related problem go to another
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
164 ;; terminal, kill your Emacs process and send me some hate mail.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
165
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
166 ;; The first three measures have restarts, i.e., once you've figured out
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
167 ;; the problem you can reactivate advised functions with either `ad-activate',
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
168 ;; `ad-activate-all', or `ad-start-advice'. `ad-recover-normality' unadvises
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
169 ;; everything so you won't be able to reactivate any advised functions, you'll
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
170 ;; have to stick with their standard incarnations for the rest of the session.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
171
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
172 ;; IMPORTANT: With Advice loaded always do `M-x ad-deactivate-all' before
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
173 ;; you byte-compile a file, because advised special forms and macros can lead
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
174 ;; to unwanted compilation results. When you are done compiling use
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
175 ;; `M-x ad-activate-all' to go back to the advised state of all your
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
176 ;; advised functions.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
177
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
178 ;; RELAX: Advice is pretty safe even if you are oblivious to the above.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
179 ;; I use it extensively and haven't run into any serious trouble in a long
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
180 ;; time. Just wanted you to be warned.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
181
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
182 ;; @ Customization:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
183 ;; ================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
184
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
185 ;; Look at the documentation of `ad-redefinition-action' for possible values
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
186 ;; of this variable. Its default value is `warn' which will print a warning
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
187 ;; message when an already defined advised function gets redefined with a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
188 ;; new original definition and de/activated.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
189
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
190 ;; Look at the documentation of `ad-default-compilation-action' for possible
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
191 ;; values of this variable. Its default value is `maybe' which will compile
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
192 ;; advised definitions during activation in case the byte-compiler is already
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
193 ;; loaded. Otherwise, it will leave them uncompiled.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
194
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
195 ;; @ Motivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
196 ;; =============
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
197 ;; Before I go on explaining how advice works, here are four simple examples
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
198 ;; how this package can be used. The first three are very useful, the last one
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
199 ;; is just a joke:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
200
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
201 ;;(defadvice switch-to-buffer (before existing-buffers-only activate)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
202 ;; "When called interactively switch to existing buffers only, unless
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
203 ;;when called with a prefix argument."
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
204 ;; (interactive
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
205 ;; (list (read-buffer "Switch to buffer: " (other-buffer)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
206 ;; (null current-prefix-arg)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
207 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
208 ;;(defadvice switch-to-buffer (around confirm-non-existing-buffers activate)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
209 ;; "Switch to non-existing buffers only upon confirmation."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
210 ;; (interactive "BSwitch to buffer: ")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
211 ;; (if (or (get-buffer (ad-get-arg 0))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
212 ;; (y-or-n-p (format "`%s' does not exist, create? " (ad-get-arg 0))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
213 ;; ad-do-it))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
214 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
215 ;;(defadvice find-file (before existing-files-only activate)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
216 ;; "Find existing files only"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
217 ;; (interactive "fFind file: "))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
218 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
219 ;;(defadvice car (around interactive activate)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
220 ;; "Make `car' an interactive function."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
221 ;; (interactive "xCar of list: ")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
222 ;; ad-do-it
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
223 ;; (if (interactive-p)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
224 ;; (message "%s" ad-return-value)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
225
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
226
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
227 ;; @ Advice documentation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
228 ;; =======================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
229 ;; Below is general documentation of the various features of advice. For more
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
230 ;; concrete examples check the corresponding sections in the tutorial part.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
231
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
232 ;; @@ Terminology:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
233 ;; ===============
24875
7177532e6e8b Comment fix.
Karl Heuer <kwzh@gnu.org>
parents: 23946
diff changeset
234 ;; - Emacs, Emacs-19: Emacs as released by the GNU Project
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
235 ;; - Lemacs: Lucid's version of Emacs with major version 19
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
236 ;; - v18: Any Emacs with major version 18 or built as an extension to that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
237 ;; (such as Epoch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
238 ;; - v19: Any Emacs with major version 19
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
239 ;; - jwz: Jamie Zawinski - former keeper of Lemacs and creator of the optimizing
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
240 ;; byte-compiler used in v19s.
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
241 ;; - Advice: The name of this package.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
242 ;; - advices: Short for "pieces of advice".
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
243
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
244 ;; @@ Defining a piece of advice with `defadvice':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
245 ;; ===============================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
246 ;; The main means of defining a piece of advice is the macro `defadvice',
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
247 ;; there is no interactive way of specifying a piece of advice. A call to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
248 ;; `defadvice' has the following syntax which is similar to the syntax of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
249 ;; `defun/defmacro':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
250 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
251 ;; (defadvice <function> (<class> <name> [<position>] [<arglist>] {<flags>}*)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
252 ;; [ [<documentation-string>] [<interactive-form>] ]
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
253 ;; {<body-form>}* )
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
254
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
255 ;; <function> is the name of the function/macro/subr to be advised.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
256
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
257 ;; <class> is the class of the advice which has to be one of `before',
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
258 ;; `around', `after', `activation' or `deactivation' (the last two allow
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
259 ;; definition of special act/deactivation hooks).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
260
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
261 ;; <name> is the name of the advice which has to be a non-nil symbol.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
262 ;; Names uniquely identify a piece of advice in a certain advice class,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
263 ;; hence, advices can be redefined by defining an advice with the same class
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
264 ;; and name. Advice names are global symbols, hence, the same name space
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
265 ;; conventions used for function names should be applied.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
266
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
267 ;; An optional <position> specifies where in the current list of advices of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
268 ;; the specified <class> this new advice will be placed. <position> has to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
269 ;; be either `first', `last' or a number that specifies a zero-based
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
270 ;; position (`first' is equivalent to 0). If no position is specified
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
271 ;; `first' will be used as a default. If this call to `defadvice' redefines
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
272 ;; an already existing advice (see above) then the position argument will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
273 ;; be ignored and the position of the already existing advice will be used.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
274
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
275 ;; An optional <arglist> which has to be a list can be used to define the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
276 ;; argument list of the advised function. This argument list should of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
277 ;; course be compatible with the argument list of the original function,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
278 ;; otherwise functions that call the advised function with the original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
279 ;; argument list in mind will break. If more than one advice specify an
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
280 ;; argument list then the first one (the one with the smallest position)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
281 ;; found in the list of before/around/after advices will be used.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
282
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
283 ;; <flags> is a list of symbols that specify further information about the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
284 ;; advice. All flags can be specified with unambiguous initial substrings.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
285 ;; `activate': Specifies that the advice information of the advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
286 ;; function should be activated right after this advice has been
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
287 ;; defined. In forward advices `activate' will be ignored.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
288 ;; `protect': Specifies that this advice should be protected against
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
289 ;; non-local exits and errors in preceding code/advices.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
290 ;; `compile': Specifies that the advised function should be byte-compiled.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
291 ;; This flag will be ignored unless `activate' is also specified.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
292 ;; `disable': Specifies that the defined advice should be disabled, hence,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
293 ;; it will not be used in an activation until somebody enables it.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
294 ;; `preactivate': Specifies that the advised function should get preactivated
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
295 ;; at macro-expansion/compile time of this `defadvice'. This
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
296 ;; generates a compiled advised definition according to the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
297 ;; current advice state which will be used during activation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
298 ;; if appropriate. Only use this if the `defadvice' gets
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
299 ;; actually compiled (with a v18 byte-compiler put the `defadvice'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
300 ;; into the body of a `defun' to accomplish proper compilation).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
301
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
302 ;; An optional <documentation-string> can be supplied to document the advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
303 ;; On call of the `documentation' function it will be combined with the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
304 ;; documentation strings of the original function and other advices.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
305
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
306 ;; An optional <interactive-form> form can be supplied to change/add
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
307 ;; interactive behavior of the original function. If more than one advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
308 ;; has an `(interactive ...)' specification then the first one (the one
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
309 ;; with the smallest position) found in the list of before/around/after
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
310 ;; advices will be used.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
311
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
312 ;; A possibly empty list of <body-forms> specifies the body of the advice in
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
313 ;; an implicit progn. The body of an advice can access/change arguments,
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
314 ;; the return value, the binding environment, and can have all sorts of
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
315 ;; other side effects.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
316
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
317 ;; @@ Assembling advised definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
318 ;; ==================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
319 ;; Suppose a function/macro/subr/special-form has N pieces of before advice,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
320 ;; M pieces of around advice and K pieces of after advice. Assuming none of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
321 ;; the advices is protected, its advised definition will look like this
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
322 ;; (body-form indices correspond to the position of the respective advice in
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
323 ;; that advice class):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
324
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
325 ;; ([macro] lambda <arglist>
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
326 ;; [ [<advised-docstring>] [(interactive ...)] ]
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
327 ;; (let (ad-return-value)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
328 ;; {<before-0-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
329 ;; ....
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
330 ;; {<before-N-1-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
331 ;; {<around-0-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
332 ;; {<around-1-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
333 ;; ....
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
334 ;; {<around-M-1-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
335 ;; (setq ad-return-value
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
336 ;; <apply original definition to <arglist>>)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
337 ;; {<other-around-M-1-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
338 ;; ....
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
339 ;; {<other-around-1-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
340 ;; {<other-around-0-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
341 ;; {<after-0-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
342 ;; ....
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
343 ;; {<after-K-1-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
344 ;; ad-return-value))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
345
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
346 ;; Macros and special forms will be redefined as macros, hence the optional
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
347 ;; [macro] in the beginning of the definition.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
348
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
349 ;; <arglist> is either the argument list of the original function or the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
350 ;; first argument list defined in the list of before/around/after advices.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
351 ;; The values of <arglist> variables can be accessed/changed in the body of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
352 ;; an advice by simply referring to them by their original name, however,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
353 ;; more portable argument access macros are also provided (see below). For
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
354 ;; subrs/special-forms for which neither explicit argument list definitions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
355 ;; are available, nor their documentation strings contain such definitions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
356 ;; (as they do v19s), `(&rest ad-subr-args)' will be used.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
357
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
358 ;; <advised-docstring> is an optional, special documentation string which will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
359 ;; be expanded into a proper documentation string upon call of `documentation'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
360
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
361 ;; (interactive ...) is an optional interactive form either taken from the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
362 ;; original function or from a before/around/after advice. For advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
363 ;; interactive subrs that do not have an interactive form specified in any
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
364 ;; advice we have to use (interactive) and then call the subr interactively
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
365 ;; if the advised function was called interactively, because the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
366 ;; interactive specification of subrs is not accessible. This is the only
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
367 ;; case where changing the values of arguments will not have an affect
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
368 ;; because they will be reset by the interactive specification of the subr.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
369 ;; If this is a problem one can always specify an interactive form in a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
370 ;; before/around/after advice to gain control over argument values that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
371 ;; were supplied interactively.
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
372 ;;
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
373 ;; Then the body forms of the various advices in the various classes of advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
374 ;; are assembled in order. The forms of around advice L are normally part of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
375 ;; one of the forms of around advice L-1. An around advice can specify where
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
376 ;; the forms of the wrapped or surrounded forms should go with the special
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
377 ;; keyword `ad-do-it', which will be substituted with a `progn' containing the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
378 ;; forms of the surrounded code.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
379
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
380 ;; The innermost part of the around advice onion is
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
381 ;; <apply original definition to <arglist>>
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
382 ;; whose form depends on the type of the original function. The variable
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
383 ;; `ad-return-value' will be set to its result. This variable is visible to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
384 ;; all pieces of advice which can access and modify it before it gets returned.
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
385 ;;
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
386 ;; The semantic structure of advised functions that contain protected pieces
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
387 ;; of advice is the same. The only difference is that `unwind-protect' forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
388 ;; make sure that the protected advice gets executed even if some previous
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
389 ;; piece of advice had an error or a non-local exit. If any around advice is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
390 ;; protected then the whole around advice onion will be protected.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
391
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
392 ;; @@ Argument access in advised functions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
393 ;; ========================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
394 ;; As already mentioned, the simplest way to access the arguments of an
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
395 ;; advised function in the body of an advice is to refer to them by name. To
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
396 ;; do that, the advice programmer needs to know either the names of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
397 ;; argument variables of the original function, or the names used in the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
398 ;; argument list redefinition given in a piece of advice. While this simple
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
399 ;; method might be sufficient in many cases, it has the disadvantage that it
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
400 ;; is not very portable because it hardcodes the argument names into the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
401 ;; advice. If the definition of the original function changes the advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
402 ;; might break even though the code might still be correct. Situations like
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
403 ;; that arise, for example, if one advises a subr like `eval-region' which
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
404 ;; gets redefined in a non-advice style into a function by the edebug
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
405 ;; package. If the advice assumes `eval-region' to be a subr it might break
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
406 ;; once edebug is loaded. Similar situations arise when one wants to use the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
407 ;; same piece of advice across different versions of Emacs. Some subrs in a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
408 ;; v18 Emacs are functions in v19 and vice versa, but for the most part the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
409 ;; semantics remain the same, hence, the same piece of advice might be usable
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
410 ;; in both Emacs versions.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
411
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
412 ;; As a solution to that advice provides argument list access macros that get
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
413 ;; translated into the proper access forms at activation time, i.e., when the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
414 ;; advised definition gets constructed. Access macros access actual arguments
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
415 ;; by position regardless of how these actual argument get distributed onto
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
416 ;; the argument variables of a function. The rational behind this is that in
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
417 ;; Emacs Lisp the semantics of an argument is strictly determined by its
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
418 ;; position (there are no keyword arguments).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
419
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
420 ;; Suppose the function `foo' is defined as
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
421 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
422 ;; (defun foo (x y &optional z &rest r) ....)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
423 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
424 ;; and is then called with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
425 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
426 ;; (foo 0 1 2 3 4 5 6)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
427
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
428 ;; which means that X=0, Y=1, Z=2 and R=(3 4 5 6). The assumption is that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
429 ;; the semantics of an actual argument is determined by its position. It is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
430 ;; this semantics that has to be known by the advice programmer. Then s/he
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
431 ;; can access these arguments in a piece of advice with some of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
432 ;; following macros (the arrows indicate what value they will return):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
433
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
434 ;; (ad-get-arg 0) -> 0
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
435 ;; (ad-get-arg 1) -> 1
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
436 ;; (ad-get-arg 2) -> 2
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
437 ;; (ad-get-arg 3) -> 3
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
438 ;; (ad-get-args 2) -> (2 3 4 5 6)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
439 ;; (ad-get-args 4) -> (4 5 6)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
440
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
441 ;; `(ad-get-arg <position>)' will return the actual argument that was supplied
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
442 ;; at <position>, `(ad-get-args <position>)' will return the list of actual
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
443 ;; arguments supplied starting at <position>. Note that these macros can be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
444 ;; used without any knowledge about the form of the actual argument list of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
445 ;; the original function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
446
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
447 ;; Similarly, `(ad-set-arg <position> <value-form>)' can be used to set the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
448 ;; value of the actual argument at <position> to <value-form>. For example,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
449 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
450 ;; (ad-set-arg 5 "five")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
451 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
452 ;; will have the effect that R=(3 4 "five" 6) once the original function is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
453 ;; called. `(ad-set-args <position> <value-list-form>)' can be used to set
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
454 ;; the list of actual arguments starting at <position> to <value-list-form>.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
455 ;; For example,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
456 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
457 ;; (ad-set-args 0 '(5 4 3 2 1 0))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
458 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
459 ;; will have the effect that X=5, Y=4, Z=3 and R=(2 1 0) once the original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
460 ;; function is called.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
461
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
462 ;; All these access macros are text macros rather than real Lisp macros. When
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
463 ;; the advised definition gets constructed they get replaced with actual access
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
464 ;; forms depending on the argument list of the advised function, i.e., after
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
465 ;; that argument access is in most cases as efficient as using the argument
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
466 ;; variable names directly.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
467
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
468 ;; @@@ Accessing argument bindings of arbitrary functions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
469 ;; =======================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
470 ;; Some functions (such as `trace-function' defined in trace.el) need a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
471 ;; method of accessing the names and bindings of the arguments of an
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
472 ;; arbitrary advised function. To do that within an advice one can use the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
473 ;; special keyword `ad-arg-bindings' which is a text macro that will be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
474 ;; substituted with a form that will evaluate to a list of binding
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
475 ;; specifications, one for every argument variable. These binding
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
476 ;; specifications can then be examined in the body of the advice. For
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
477 ;; example, somewhere in an advice we could do this:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
478 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
479 ;; (let* ((bindings ad-arg-bindings)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
480 ;; (firstarg (car bindings))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
481 ;; (secondarg (car (cdr bindings))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
482 ;; ;; Print info about first argument
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
483 ;; (print (format "%s=%s (%s)"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
484 ;; (ad-arg-binding-field firstarg 'name)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
485 ;; (ad-arg-binding-field firstarg 'value)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
486 ;; (ad-arg-binding-field firstarg 'type)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
487 ;; ....)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
488 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
489 ;; The `type' of an argument is either `required', `optional' or `rest'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
490 ;; Wherever `ad-arg-bindings' appears a form will be inserted that evaluates
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
491 ;; to the list of bindings, hence, in order to avoid multiple unnecessary
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
492 ;; evaluations one should always bind it to some variable.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
493
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
494 ;; @@@ Argument list mapping:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
495 ;; ==========================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
496 ;; Because `defadvice' allows the specification of the argument list of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
497 ;; advised function we need a mapping mechanism that maps this argument list
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
498 ;; onto that of the original function. For example, somebody might specify
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
499 ;; `(sym newdef)' as the argument list of `fset', while advice might use
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
500 ;; `(&rest ad-subr-args)' as the argument list of the original function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
501 ;; (depending on what Emacs version is used). Hence SYM and NEWDEF have to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
502 ;; be properly mapped onto the &rest variable when the original definition is
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
503 ;; called. Advice automatically takes care of that mapping, hence, the advice
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
504 ;; programmer can specify an argument list without having to know about the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
505 ;; exact structure of the original argument list as long as the new argument
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
506 ;; list takes a compatible number/magnitude of actual arguments.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
507
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
508 ;; @@@ Definition of subr argument lists:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
509 ;; ======================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
510 ;; When advice constructs the advised definition of a function it has to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
511 ;; know the argument list of the original function. For functions and macros
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
512 ;; the argument list can be determined from the actual definition, however,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
513 ;; for subrs there is no such direct access available. In Lemacs and for some
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
514 ;; subrs in Emacs-19 the argument list of a subr can be determined from
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
515 ;; its documentation string, in a v18 Emacs even that is not possible. If
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
516 ;; advice cannot at all determine the argument list of a subr it uses
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
517 ;; `(&rest ad-subr-args)' which will always work but is inefficient because
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
518 ;; it conses up arguments. The macro `ad-define-subr-args' can be used by
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
519 ;; the advice programmer to explicitly tell advice about the argument list
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
520 ;; of a certain subr, for example,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
521 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
522 ;; (ad-define-subr-args 'fset '(sym newdef))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
523 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
524 ;; is used by advice itself to tell a v18 Emacs about the arguments of `fset'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
525 ;; The following can be used to undo such a definition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
526 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
527 ;; (ad-undefine-subr-args 'fset)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
528 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
529 ;; The argument list definition is stored on the property list of the subr
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
530 ;; name symbol. When an argument list could be determined from the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
531 ;; documentation string it will be cached under that property. The general
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
532 ;; mechanism for looking up the argument list of a subr is the following:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
533 ;; 1) look for a definition stored on the property list
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
534 ;; 2) if that failed try to infer it from the documentation string and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
535 ;; if successful cache it on the property list
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
536 ;; 3) otherwise use `(&rest ad-subr-args)'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
537
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
538 ;; @@ Activation and deactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
539 ;; ===============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
540 ;; The definition of an advised function does not change until all its advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
541 ;; gets actually activated. Activation can either happen with the `activate'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
542 ;; flag specified in the `defadvice', with an explicit call or interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
543 ;; invocation of `ad-activate', or if forward advice is enabled (i.e., the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
544 ;; value of `ad-activate-on-definition' is t) at the time an already advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
545 ;; function gets defined.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
546
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
547 ;; When a function gets first activated its original definition gets saved,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
548 ;; all defined and enabled pieces of advice will get combined with the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
549 ;; original definition, the resulting definition might get compiled depending
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
550 ;; on some conditions described below, and then the function will get
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
551 ;; redefined with the advised definition. This also means that undefined
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
552 ;; functions cannot get activated even though they might be already advised.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
553
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
554 ;; The advised definition will get compiled either if `ad-activate' was called
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
555 ;; interactively with a prefix argument, or called explicitly with its second
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
556 ;; argument as t, or, if `ad-default-compilation-action' justifies it according
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
557 ;; to the current system state. If the advised definition was
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
558 ;; constructed during "preactivation" (see below) then that definition will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
559 ;; be already compiled because it was constructed during byte-compilation of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
560 ;; the file that contained the `defadvice' with the `preactivate' flag.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
561
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
562 ;; `ad-deactivate' can be used to back-define an advised function to its
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
563 ;; original definition. It can be called interactively or directly. Because
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
564 ;; `ad-activate' caches the advised definition the function can be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
565 ;; reactivated via `ad-activate' with only minor overhead (it is checked
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
566 ;; whether the current advice state is consistent with the cached
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
567 ;; definition, see the section on caching below).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
568
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
569 ;; `ad-activate-regexp' and `ad-deactivate-regexp' can be used to de/activate
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
570 ;; all currently advised function that have a piece of advice with a name that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
571 ;; contains a match for a regular expression. These functions can be used to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
572 ;; de/activate sets of functions depending on certain advice naming
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
573 ;; conventions.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
574
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
575 ;; Finally, `ad-activate-all' and `ad-deactivate-all' can be used to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
576 ;; de/activate all currently advised functions. These are useful to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
577 ;; (temporarily) return to an un/advised state.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
578
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
579 ;; @@@ Reasons for the separation of advice definition and activation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
580 ;; ===================================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
581 ;; As already mentioned, advising happens in two stages:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
582
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
583 ;; 1) definition of various pieces of advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
584 ;; 2) activation of all advice currently defined and enabled
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
585
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
586 ;; The advantage of this is that various pieces of advice can be defined
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
587 ;; before they get combined into an advised definition which avoids
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
588 ;; unnecessary constructions of intermediate advised definitions. The more
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
589 ;; important advantage is that it allows the implementation of forward advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
590 ;; Advice information for a certain function accumulates as the value of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
591 ;; `advice-info' property of the function symbol. This accumulation is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
592 ;; completely independent of the fact that that function might not yet be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
593 ;; defined. The special forms `defun' and `defmacro' have been advised to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
594 ;; check whether the function/macro they defined had advice information
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
595 ;; associated with it. If so and forward advice is enabled, the original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
596 ;; definition will be saved, and then the advice will be activated. When a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
597 ;; file is loaded in a v18 Emacs the functions/macros it defines are also
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
598 ;; defined with calls to `defun/defmacro'. Hence, we can forward advise
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
599 ;; functions/macros which will be defined later during a load/autoload of some
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
600 ;; file (for compiled files generated by jwz's byte-compiler in a v19 Emacs
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
601 ;; this is slightly more complicated but the basic idea is the same).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
602
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
603 ;; @@ Enabling/disabling pieces or sets of advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
604 ;; ===============================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
605 ;; A major motivation for the development of this advice package was to bring
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
606 ;; a little bit more structure into the function overloading chaos in Emacs
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
607 ;; Lisp. Many packages achieve some of their functionality by adding a little
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
608 ;; bit (or a lot) to the standard functionality of some Emacs Lisp function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
609 ;; ange-ftp is a very popular package that achieves its magic by overloading
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
610 ;; most Emacs Lisp functions that deal with files. A popular function that's
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
611 ;; overloaded by many packages is `expand-file-name'. The situation that one
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
612 ;; function is multiply overloaded can arise easily.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
613
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
614 ;; Once in a while it would be desirable to be able to disable some/all
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
615 ;; overloads of a particular package while keeping all the rest. Ideally -
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
616 ;; at least in my opinion - these overloads would all be done with advice,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
617 ;; I know I am dreaming right now... In that ideal case the enable/disable
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
618 ;; mechanism of advice could be used to achieve just that.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
619
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
620 ;; Every piece of advice is associated with an enablement flag. When the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
621 ;; advised definition of a particular function gets constructed (e.g., during
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
622 ;; activation) only the currently enabled pieces of advice will be considered.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
623 ;; This mechanism allows one to have different "views" of an advised function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
624 ;; dependent on what pieces of advice are currently enabled.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
625
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
626 ;; Another motivation for this mechanism is that it allows one to define a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
627 ;; piece of advice for some function yet keep it dormant until a certain
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
628 ;; condition is met. Until then activation of the function will not make use
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
629 ;; of that piece of advice. Once the condition is met the advice can be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
630 ;; enabled and a reactivation of the function will add its functionality as
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
631 ;; part of the new advised definition. For example, the advices of `defun'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
632 ;; etc. used by advice itself will stay disabled until `ad-start-advice' is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
633 ;; called and some variables have the proper values. Hence, if somebody
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
634 ;; else advised these functions too and activates them the advices defined
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
635 ;; by advice will get used only if they are intended to be used.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
636
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
637 ;; The main interface to this mechanism are the interactive functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
638 ;; `ad-enable-advice' and `ad-disable-advice'. For example, the following
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
639 ;; would disable a particular advice of the function `foo':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
640 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
641 ;; (ad-disable-advice 'foo 'before 'my-advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
642 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
643 ;; This call by itself only changes the flag, to get the proper effect in
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
644 ;; the advised definition too one has to activate `foo' with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
645 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
646 ;; (ad-activate 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
647 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
648 ;; or interactively. To disable whole sets of advices one can use a regular
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
649 ;; expression mechanism. For example, let us assume that ange-ftp actually
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
650 ;; used advice to overload all its functions, and that it used the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
651 ;; "ange-ftp-" prefix for all its advice names, then we could temporarily
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
652 ;; disable all its advices with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
653 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
654 ;; (ad-disable-regexp "^ange-ftp-")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
655 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
656 ;; and the following call would put that actually into effect:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
657 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
658 ;; (ad-activate-regexp "^ange-ftp-")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
659 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
660 ;; A saver way would have been to use
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
661 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
662 ;; (ad-update-regexp "^ange-ftp-")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
663 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
664 ;; instead which would have only reactivated currently actively advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
665 ;; functions, but not functions that were currently deactivated. All these
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
666 ;; functions can also be called interactively.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
667
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
668 ;; A certain piece of advice is considered a match if its name contains a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
669 ;; match for the regular expression. To enable ange-ftp again we would use
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
670 ;; `ad-enable-regexp' and then activate or update again.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
671
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
672 ;; @@ Forward advice, automatic advice activation:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
673 ;; ===============================================
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
674 ;; Because most Emacs Lisp packages are loaded on demand via an autoload
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
675 ;; mechanism it is essential to be able to "forward advise" functions.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
676 ;; Otherwise, proper advice definition and activation would make it necessary
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
677 ;; to preload every file that defines a certain function before it can be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
678 ;; advised, which would partly defeat the purpose of the advice mechanism.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
679
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
680 ;; In the following, "forward advice" always implies its automatic activation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
681 ;; once a function gets defined, and not just the accumulation of advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
682 ;; information for a possibly undefined function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
683
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
684 ;; Advice implements forward advice mainly via the following: 1) Separation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
685 ;; of advice definition and activation that makes it possible to accumulate
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
686 ;; advice information without having the original function already defined,
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
687 ;; 2) special versions of the built-in functions `fset/defalias' which check
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
688 ;; for advice information whenever they define a function. If advice
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
689 ;; information was found then the advice will immediately get activated when
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
690 ;; the function gets defined.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
691
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
692 ;; Automatic advice activation means, that whenever a function gets defined
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
693 ;; with either `defun', `defmacro', `fset' or by loading a byte-compiled
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
694 ;; file, and the function has some advice-info stored with it then that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
695 ;; advice will get activated right away.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
696
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
697 ;; @@@ Enabling automatic advice activation:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
698 ;; =========================================
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
699 ;; Automatic advice activation is enabled by default. It can be disabled by
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
700 ;; doint `M-x ad-stop-advice' and enabled again with `M-x ad-start-advice'.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
701
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
702 ;; @@ Caching of advised definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
703 ;; ==================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
704 ;; After an advised definition got constructed it gets cached as part of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
705 ;; advised function's advice-info so it can be reused, for example, after an
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
706 ;; intermediate deactivation. Because the advice-info of a function might
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
707 ;; change between the time of caching and reuse a cached definition gets
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
708 ;; a cache-id associated with it so it can be verified whether the cached
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
709 ;; definition is still valid (the main application of this is preactivation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
710 ;; - see below).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
711
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
712 ;; When an advised function gets activated and a verifiable cached definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
713 ;; is available, then that definition will be used instead of creating a new
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
714 ;; advised definition from scratch. If you want to make sure that a new
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
715 ;; definition gets constructed then you should use `ad-clear-cache' before you
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
716 ;; activate the advised function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
717
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
718 ;; @@ Preactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
719 ;; =================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
720 ;; Constructing an advised definition is moderately expensive. In a situation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
721 ;; where one package defines a lot of advised functions it might be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
722 ;; prohibitively expensive to do all the advised definition construction at
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
723 ;; runtime. Preactivation is a mechanism that allows compile-time construction
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
724 ;; of compiled advised definitions that can be activated cheaply during
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
725 ;; runtime. Preactivation uses the caching mechanism to do that. Here's how it
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
726 ;; works:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
727
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
728 ;; When the byte-compiler compiles a `defadvice' that has the `preactivate'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
729 ;; flag specified, it uses the current original definition of the advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
730 ;; function plus the advice specified in this `defadvice' (even if it is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
731 ;; specified as disabled) and all other currently enabled pieces of advice to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
732 ;; construct an advised definition and an identifying cache-id and makes them
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
733 ;; part of the `defadvice' expansion which will then be compiled by the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
734 ;; byte-compiler (to ensure that in a v18 emacs you have to put the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
735 ;; `defadvice' inside a `defun' to get it compiled and then you have to call
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
736 ;; that compiled `defun' in order to actually execute the `defadvice'). When
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
737 ;; the file with the compiled, preactivating `defadvice' gets loaded the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
738 ;; precompiled advised definition will be cached on the advised function's
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
739 ;; advice-info. When it gets activated (can be immediately on execution of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
740 ;; `defadvice' or any time later) the cache-id gets checked against the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
741 ;; current state of advice and if it is verified the precompiled definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
742 ;; will be used directly (the verification is pretty cheap). If it couldn't get
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
743 ;; verified a new advised definition for that function will be built from
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
744 ;; scratch, hence, the efficiency added by the preactivation mechanism does
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
745 ;; not at all impair the flexibility of the advice mechanism.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
746
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
747 ;; MORAL: In order get all the efficiency out of preactivation the advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
748 ;; state of an advised function at the time the file with the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
749 ;; preactivating `defadvice' gets byte-compiled should be exactly
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
750 ;; the same as it will be when the advice of that function gets
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
751 ;; actually activated. If it is not there is a high chance that the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
752 ;; cache-id will not match and hence a new advised definition will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
753 ;; have to be constructed at runtime.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
754
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
755 ;; Preactivation and forward advice do not contradict each other. It is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
756 ;; perfectly ok to load a file with a preactivating `defadvice' before the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
757 ;; original definition of the advised function is available. The constructed
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
758 ;; advised definition will be used once the original function gets defined and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
759 ;; its advice gets activated. The only constraint is that at the time the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
760 ;; file with the preactivating `defadvice' got compiled the original function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
761 ;; definition was available.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
762
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
763 ;; TIPS: Here are some indications that a preactivation did not work the way
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
764 ;; you intended it to work:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
765 ;; - Activation of the advised function takes longer than usual/expected
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
766 ;; - The byte-compiler gets loaded while an advised function gets
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
767 ;; activated
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
768 ;; - `byte-compile' is part of the `features' variable even though you
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
769 ;; did not use the byte-compiler
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
770 ;; Right now advice does not provide an elegant way to find out whether
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
771 ;; and why a preactivation failed. What you can do is to trace the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
772 ;; function `ad-cache-id-verification-code' (with the function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
773 ;; `trace-function-background' defined in my trace.el package) before
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
774 ;; any of your advised functions get activated. After they got
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
775 ;; activated check whether all calls to `ad-cache-id-verification-code'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
776 ;; returned `verified' as a result. Other values indicate why the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
777 ;; verification failed which should give you enough information to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
778 ;; fix your preactivation/compile/load/activation sequence.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
779
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
780 ;; IMPORTANT: There is one case (that I am aware of) that can make
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
781 ;; preactivation fail, i.e., a preconstructed advised definition that does
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
782 ;; NOT match the current state of advice gets used nevertheless. That case
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
783 ;; arises if one package defines a certain piece of advice which gets used
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
784 ;; during preactivation, and another package incompatibly redefines that
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
785 ;; very advice (i.e., same function/class/name), and it is the second advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
786 ;; that is available when the preconstructed definition gets activated, and
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
787 ;; that was the only definition of that advice so far (`ad-add-advice'
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
788 ;; catches advice redefinitions and clears the cache in such a case).
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
789 ;; Catching that would make the cache verification too expensive.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
790
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
791 ;; MORAL-II: Redefining somebody else's advice is BAAAAD (to speak with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
792 ;; George Walker Bush), and why would you redefine your own advice anyway?
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
793 ;; Advice is a mechanism to facilitate function redefinition, not advice
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
794 ;; redefinition (wait until I write Meta-Advice :-). If you really have
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
795 ;; to undo somebody else's advice try to write a "neutralizing" advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
796
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
797 ;; @@ Advising macros and special forms and other dangerous things:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
798 ;; ================================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
799 ;; Look at the corresponding tutorial sections for more information on
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
800 ;; these topics. Here it suffices to point out that the special treatment
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
801 ;; of macros and special forms by the byte-compiler can lead to problems
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
802 ;; when they get advised. Macros can create problems because they get
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
803 ;; expanded at compile time, hence, they might not have all the necessary
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
804 ;; runtime support and such advice cannot be de/activated or changed as
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
805 ;; it is possible for functions. Special forms create problems because they
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
806 ;; have to be advised "into" macros, i.e., an advised special form is a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
807 ;; implemented as a macro, hence, in most cases the byte-compiler will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
808 ;; not recognize it as a special form anymore which can lead to very strange
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
809 ;; results.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
810 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
811 ;; MORAL: - Only advise macros or special forms when you are absolutely sure
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
812 ;; what you are doing.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
813 ;; - As a safety measure, always do `ad-deactivate-all' before you
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
814 ;; byte-compile a file to make sure that even if some inconsiderate
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
815 ;; person advised some special forms you'll get proper compilation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
816 ;; results. After compilation do `ad-activate-all' to get back to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
817 ;; the previous state.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
818
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
819 ;; @@ Adding a piece of advice with `ad-add-advice':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
820 ;; =================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
821 ;; The non-interactive function `ad-add-advice' can be used to add a piece of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
822 ;; advice to some function without using `defadvice'. This is useful if advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
823 ;; has to be added somewhere by a function (also look at `ad-make-advice').
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
824
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
825 ;; @@ Activation/deactivation advices, file load hooks:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
826 ;; ====================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
827 ;; There are two special classes of advice called `activation' and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
828 ;; `deactivation'. The body forms of these advices are not included into the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
829 ;; advised definition of a function, rather they are assembled into a hook
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
830 ;; form which will be evaluated whenever the advice-info of the advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
831 ;; function gets activated or deactivated. One application of this mechanism
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
832 ;; is to define file load hooks for files that do not provide such hooks
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
833 ;; (v19s already come with a general file-load-hook mechanism, v18s don't).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
834 ;; For example, suppose you want to print a message whenever `file-x' gets
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
835 ;; loaded, and suppose the last function defined in `file-x' is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
836 ;; `file-x-last-fn'. Then we can define the following advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
837 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
838 ;; (defadvice file-x-last-fn (activation file-x-load-hook)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
839 ;; "Executed whenever file-x is loaded"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
840 ;; (if load-in-progress (message "Loaded file-x")))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
841 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
842 ;; This will constitute a forward advice for function `file-x-last-fn' which
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
843 ;; will get activated when `file-x' is loaded (only if forward advice is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
844 ;; enabled of course). Because there are no "real" pieces of advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
845 ;; available for it, its definition will not be changed, but the activation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
846 ;; advice will be run during its activation which is equivalent to having a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
847 ;; file load hook for `file-x'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
848
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
849 ;; @@ Summary of main advice concepts:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
850 ;; ===================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
851 ;; - Definition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
852 ;; A piece of advice gets defined with `defadvice' and added to the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
853 ;; `advice-info' property of a function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
854 ;; - Enablement:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
855 ;; Every piece of advice has an enablement flag associated with it. Only
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
856 ;; enabled advices are considered during construction of an advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
857 ;; definition.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
858 ;; - Activation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
859 ;; Redefine an advised function with its advised definition. Constructs
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
860 ;; an advised definition from scratch if no verifiable cached advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
861 ;; definition is available and caches it.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
862 ;; - Deactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
863 ;; Back-define an advised function to its original definition.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
864 ;; - Update:
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
865 ;; Reactivate an advised function but only if its advice is currently
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
866 ;; active. This can be used to bring all currently advised function up
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
867 ;; to date with the current state of advice without also activating
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
868 ;; currently deactivated functions.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
869 ;; - Caching:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
870 ;; Is the saving of an advised definition and an identifying cache-id so
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
871 ;; it can be reused, for example, for activation after deactivation.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
872 ;; - Preactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
873 ;; Is the construction of an advised definition according to the current
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
874 ;; state of advice during byte-compilation of a file with a preactivating
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
875 ;; `defadvice'. That advised definition can then rather cheaply be used
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
876 ;; during activation without having to construct an advised definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
877 ;; from scratch at runtime.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
878
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
879 ;; @@ Summary of interactive advice manipulation functions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
880 ;; ========================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
881 ;; The following interactive functions can be used to manipulate the state
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
882 ;; of advised functions (all of them support completion on function names,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
883 ;; advice classes and advice names):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
884
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
885 ;; - ad-activate to activate the advice of a FUNCTION
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
886 ;; - ad-deactivate to deactivate the advice of a FUNCTION
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
887 ;; - ad-update to activate the advice of a FUNCTION unless it was not
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
888 ;; yet activated or is currently deactivated.
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
889 ;; - ad-unadvise deactivates a FUNCTION and removes all of its advice
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
890 ;; information, hence, it cannot be activated again
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
891 ;; - ad-recover tries to redefine a FUNCTION to its original definition and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
892 ;; discards all advice information (a low-level `ad-unadvise').
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
893 ;; Use only in emergencies.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
894
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
895 ;; - ad-remove-advice removes a particular piece of advice of a FUNCTION.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
896 ;; You still have to do call `ad-activate' or `ad-update' to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
897 ;; activate the new state of advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
898 ;; - ad-enable-advice enables a particular piece of advice of a FUNCTION.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
899 ;; - ad-disable-advice disables a particular piece of advice of a FUNCTION.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
900 ;; - ad-enable-regexp maps over all currently advised functions and enables
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
901 ;; every advice whose name contains a match for a regular
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
902 ;; expression.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
903 ;; - ad-disable-regexp disables matching advices.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
904
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
905 ;; - ad-activate-regexp activates all advised function with a matching advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
906 ;; - ad-deactivate-regexp deactivates all advised function with matching advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
907 ;; - ad-update-regexp updates all advised function with a matching advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
908 ;; - ad-activate-all activates all advised functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
909 ;; - ad-deactivate-all deactivates all advised functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
910 ;; - ad-update-all updates all advised functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
911 ;; - ad-unadvise-all unadvises all advised functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
912 ;; - ad-recover-all recovers all advised functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
913
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
914 ;; - ad-compile byte-compiles a function/macro if it is compilable.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
915
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
916 ;; @@ Summary of forms with special meanings when used within an advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
917 ;; =====================================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
918 ;; ad-return-value name of the return value variable (get/settable)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
919 ;; ad-subr-args name of &rest argument variable used for advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
920 ;; subrs whose actual argument list cannot be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
921 ;; determined (get/settable)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
922 ;; (ad-get-arg <pos>), (ad-get-args <pos>),
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
923 ;; (ad-set-arg <pos> <value>), (ad-set-args <pos> <value-list>)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
924 ;; argument access text macros to get/set the values of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
925 ;; actual arguments at a certain position
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
926 ;; ad-arg-bindings text macro that returns the actual names, values
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
927 ;; and types of the arguments as a list of bindings. The
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
928 ;; order of the bindings corresponds to the order of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
929 ;; arguments. The individual fields of every binding (name,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
930 ;; value and type) can be accessed with the function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
931 ;; `ad-arg-binding-field' (see example above).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
932 ;; ad-do-it text macro that identifies the place where the original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
933 ;; or wrapped definition should go in an around advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
934
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
935
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
936 ;; @ Foo games: An advice tutorial
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
937 ;; ===============================
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
938 ;; The following tutorial was created in Emacs 18.59. Left-justified
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
939 ;; s-expressions are input forms followed by one or more result forms.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
940 ;; First we have to start the advice magic:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
941 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
942 ;; (ad-start-advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
943 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
944 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
945 ;; We start by defining an innocent looking function `foo' that simply
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
946 ;; adds 1 to its argument X:
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
947 ;;
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
948 ;; (defun foo (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
949 ;; "Add 1 to X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
950 ;; (1+ x))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
951 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
952 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
953 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
954 ;; 4
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
955 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
956 ;; @@ Defining a simple piece of advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
957 ;; =====================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
958 ;; Now let's define the first piece of advice for `foo'. To do that we
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
959 ;; use the macro `defadvice' which takes a function name, a list of advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
960 ;; specifiers and a list of body forms as arguments. The first element of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
961 ;; the advice specifiers is the class of the advice, the second is its name,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
962 ;; the third its position and the rest are some flags. The class of our
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
963 ;; first advice is `before', its name is `fg-add2', its position among the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
964 ;; currently defined before advices (none so far) is `first', and the advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
965 ;; will be `activate'ed immediately. Advice names are global symbols, hence,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
966 ;; the name space conventions used for function names should be applied. All
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
967 ;; advice names in this tutorial will be prefixed with `fg' for `Foo Games'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
968 ;; (because everybody has the right to be inconsistent all the function names
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
969 ;; used in this tutorial do NOT follow this convention).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
970 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
971 ;; In the body of an advice we can refer to the argument variables of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
972 ;; original function by name. Here we add 1 to X so the effect of calling
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
973 ;; `foo' will be to actually add 2. All of the advice definitions below only
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
974 ;; have one body form for simplicity, but there is no restriction to that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
975 ;; extent. Every piece of advice can have a documentation string which will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
976 ;; be combined with the documentation of the original function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
977 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
978 ;; (defadvice foo (before fg-add2 first activate)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
979 ;; "Add 2 to X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
980 ;; (setq x (1+ x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
981 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
982 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
983 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
984 ;; 5
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
985 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
986 ;; @@ Specifying the position of an advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
987 ;; ========================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
988 ;; Now we define the second before advice which will cancel the effect of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
989 ;; the previous advice. This time we specify the position as 0 which is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
990 ;; equivalent to `first'. A number can be used to specify the zero-based
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
991 ;; position of an advice among the list of advices in the same class. This
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
992 ;; time we already have one before advice hence the position specification
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
993 ;; actually has an effect. So, after the following definition the position
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
994 ;; of the previous advice will be 1 even though we specified it with `first'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
995 ;; above, the reason for this is that the position argument is relative to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
996 ;; the currently defined pieces of advice which by now has changed.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
997 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
998 ;; (defadvice foo (before fg-cancel-add2 0 activate)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
999 ;; "Again only add 1 to X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1000 ;; (setq x (1- x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1001 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1002 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1003 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1004 ;; 4
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1005 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1006 ;; @@ Redefining a piece of advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1007 ;; ================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1008 ;; Now we define an advice with the same class and same name but with a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1009 ;; different position. Defining an advice in a class in which an advice with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1010 ;; that name already exists is interpreted as a redefinition of that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1011 ;; particular advice, in which case the position argument will be ignored
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1012 ;; and the previous position of the redefined piece of advice is used.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1013 ;; Advice flags can be specified with non-ambiguous initial substrings, hence,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1014 ;; from now on we'll use `act' instead of the verbose `activate'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1015 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1016 ;; (defadvice foo (before fg-cancel-add2 last act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1017 ;; "Again only add 1 to X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1018 ;; (setq x (1- x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1019 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1020 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1021 ;; @@ Assembly of advised documentation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1022 ;; =====================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1023 ;; The documentation strings of the various pieces of advice are assembled
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1024 ;; in order which shows that advice `fg-cancel-add2' is still the first
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1025 ;; `before' advice even though we specified position `last' above:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1026 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1027 ;; (documentation 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1028 ;; "Add 1 to X.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1029 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1030 ;; This function is advised with the following advice(s):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1031 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1032 ;; fg-cancel-add2 (before):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1033 ;; Again only add 1 to X.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1034 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1035 ;; fg-add2 (before):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1036 ;; Add 2 to X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1037 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1038 ;; @@ Advising interactive behavior:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1039 ;; =================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1040 ;; We can make a function interactive (or change its interactive behavior)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1041 ;; by specifying an interactive form in one of the before or around
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1042 ;; advices (there could also be body forms in this advice). The particular
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1043 ;; definition always assigns 5 as an argument to X which gives us 6 as a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1044 ;; result when we call foo interactively:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1045 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1046 ;; (defadvice foo (before fg-inter last act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1047 ;; "Use 5 as argument when called interactively."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1048 ;; (interactive (list 5)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1049 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1050 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1051 ;; (call-interactively 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1052 ;; 6
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1053 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1054 ;; If more than one advice have an interactive declaration, then the one of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1055 ;; the advice with the smallest position will be used (before advices go
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1056 ;; before around and after advices), hence, the declaration below does
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1057 ;; not have any effect:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1058 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1059 ;; (defadvice foo (before fg-inter2 last act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1060 ;; (interactive (list 6)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1061 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1062 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1063 ;; (call-interactively 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1064 ;; 6
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1065 ;;
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1066 ;; Let's have a look at what the definition of `foo' looks like now
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1067 ;; (indentation added by hand for legibility):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1068 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1069 ;; (symbol-function 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1070 ;; (lambda (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1071 ;; "$ad-doc: foo$"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1072 ;; (interactive (list 5))
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1073 ;; (let (ad-return-value)
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1074 ;; (setq x (1- x))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1075 ;; (setq x (1+ x))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1076 ;; (setq ad-return-value (ad-Orig-foo x))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1077 ;; ad-return-value))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1078 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1079 ;; @@ Around advices:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1080 ;; ==================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1081 ;; Now we'll try some `around' advices. An around advice is a wrapper around
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1082 ;; the original definition. It can shadow or establish bindings for the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1083 ;; original definition, and it can look at and manipulate the value returned
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1084 ;; by the original function. The position of the special keyword `ad-do-it'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1085 ;; specifies where the code of the original function will be executed. The
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1086 ;; keyword can appear multiple times which will result in multiple calls of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1087 ;; the original function in the resulting advised code. Note, that if we don't
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1088 ;; specify a position argument (i.e., `first', `last' or a number), then
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1089 ;; `first' (or 0) is the default):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1090 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1091 ;; (defadvice foo (around fg-times-2 act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1092 ;; "First double X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1093 ;; (let ((x (* x 2)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1094 ;; ad-do-it))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1095 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1096 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1097 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1098 ;; 7
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1099 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1100 ;; Around advices are assembled like onion skins where the around advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1101 ;; with position 0 is the outermost skin and the advice at the last position
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1102 ;; is the innermost skin which is directly wrapped around the call of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1103 ;; original definition of the function. Hence, after the next `defadvice' we
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1104 ;; will first multiply X by 2 then add 1 and then call the original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1105 ;; definition (i.e., add 1 again):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1106 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1107 ;; (defadvice foo (around fg-add-1 last act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1108 ;; "Add 1 to X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1109 ;; (let ((x (1+ x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1110 ;; ad-do-it))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1111 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1112 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1113 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1114 ;; 8
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1115 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1116 ;; Again, let's see what the definition of `foo' looks like so far:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1117 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1118 ;; (symbol-function 'foo)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1119 ;; (lambda (x)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1120 ;; "$ad-doc: foo$"
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1121 ;; (interactive (list 5))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1122 ;; (let (ad-return-value)
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1123 ;; (setq x (1- x))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1124 ;; (setq x (1+ x))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1125 ;; (let ((x (* x 2)))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1126 ;; (let ((x (1+ x)))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1127 ;; (setq ad-return-value (ad-Orig-foo x))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1128 ;; ad-return-value))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1129 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1130 ;; @@ Controlling advice activation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1131 ;; =================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1132 ;; In every `defadvice' so far we have used the flag `activate' to activate
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1133 ;; the advice immediately after its definition, and that's what we want in
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1134 ;; most cases. However, if we define multiple pieces of advice for a single
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1135 ;; function then activating every advice immediately is inefficient. A
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1136 ;; better way to do this is to only activate the last defined advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1137 ;; For example:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1138 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1139 ;; (defadvice foo (after fg-times-x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1140 ;; "Multiply the result with X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1141 ;; (setq ad-return-value (* ad-return-value x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1142 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1143 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1144 ;; This still yields the same result as before:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1145 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1146 ;; 8
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1147 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1148 ;; Now we define another advice and activate which will also activate the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1149 ;; previous advice `fg-times-x'. Note the use of the special variable
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1150 ;; `ad-return-value' in the body of the advice which is set to the result of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1151 ;; the original function. If we change its value then the value returned by
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1152 ;; the advised function will be changed accordingly:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1153 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1154 ;; (defadvice foo (after fg-times-x-again act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1155 ;; "Again multiply the result with X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1156 ;; (setq ad-return-value (* ad-return-value x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1157 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1158 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1159 ;; Now the advices have an effect:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1160 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1161 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1162 ;; 72
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1163 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1164 ;; @@ Protecting advice execution:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1165 ;; ===============================
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1166 ;; Once in a while we define an advice to perform some cleanup action,
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1167 ;; for example:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1168 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1169 ;; (defadvice foo (after fg-cleanup last act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1170 ;; "Do some cleanup."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1171 ;; (print "Let's clean up now!"))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1172 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1173 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1174 ;; However, in case of an error the cleanup won't be performed:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1175 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1176 ;; (condition-case error
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1177 ;; (foo t)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1178 ;; (error 'error-in-foo))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1179 ;; error-in-foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1180 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1181 ;; To make sure a certain piece of advice gets executed even if some error or
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1182 ;; non-local exit occurred in any preceding code, we can protect it by using
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1183 ;; the `protect' keyword. (if any of the around advices is protected then the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1184 ;; whole around advice onion will be protected):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1185 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1186 ;; (defadvice foo (after fg-cleanup prot act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1187 ;; "Do some protected cleanup."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1188 ;; (print "Let's clean up now!"))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1189 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1190 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1191 ;; Now the cleanup form will be executed even in case of an error:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1192 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1193 ;; (condition-case error
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1194 ;; (foo t)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1195 ;; (error 'error-in-foo))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1196 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1197 ;; error-in-foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1198 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1199 ;; Again, let's see what `foo' looks like:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1200 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1201 ;; (symbol-function 'foo)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1202 ;; (lambda (x)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1203 ;; "$ad-doc: foo$"
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1204 ;; (interactive (list 5))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1205 ;; (let (ad-return-value)
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1206 ;; (unwind-protect
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1207 ;; (progn (setq x (1- x))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1208 ;; (setq x (1+ x))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1209 ;; (let ((x (* x 2)))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1210 ;; (let ((x (1+ x)))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1211 ;; (setq ad-return-value (ad-Orig-foo x))))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1212 ;; (setq ad-return-value (* ad-return-value x))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1213 ;; (setq ad-return-value (* ad-return-value x)))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1214 ;; (print "Let's clean up now!"))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1215 ;; ad-return-value))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1216 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1217 ;; @@ Compilation of advised definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1218 ;; ======================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1219 ;; Finally, we can specify the `compile' keyword in a `defadvice' to say
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1220 ;; that we want the resulting advised function to be byte-compiled
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1221 ;; (`compile' will be ignored unless we also specified `activate'):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1222 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1223 ;; (defadvice foo (after fg-cleanup prot act comp)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1224 ;; "Do some protected cleanup."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1225 ;; (print "Let's clean up now!"))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1226 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1227 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1228 ;; Now `foo' is byte-compiled:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1229 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1230 ;; (symbol-function 'foo)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1231 ;; (lambda (x)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1232 ;; "$ad-doc: foo$"
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1233 ;; (interactive (byte-code "....." [5] 1))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1234 ;; (byte-code "....." [ad-return-value x nil ((byte-code "....." [print "Let's clean up now!"] 2)) * 2 ad-Orig-foo] 6))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1235 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1236 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1237 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1238 ;; 72
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1239 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1240 ;; @@ Enabling and disabling pieces of advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1241 ;; ===========================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1242 ;; Once in a while it is desirable to temporarily disable a piece of advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1243 ;; so that it won't be considered during activation, for example, if two
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1244 ;; different packages advise the same function and one wants to temporarily
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1245 ;; neutralize the effect of the advice of one of the packages.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1246 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1247 ;; The following disables the after advice `fg-times-x' in the function `foo'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1248 ;; All that does is to change a flag for this particular advice. All the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1249 ;; other information defining it will be left unchanged (e.g., its relative
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1250 ;; position in this advice class, etc.).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1251 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1252 ;; (ad-disable-advice 'foo 'after 'fg-times-x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1253 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1254 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1255 ;; For this to have an effect we have to activate `foo':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1256 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1257 ;; (ad-activate 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1258 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1259 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1260 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1261 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1262 ;; 24
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1263 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1264 ;; If we want to disable all multiplication advices in `foo' we can use a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1265 ;; regular expression that matches the names of such advices. Actually, any
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1266 ;; advice name that contains a match for the regular expression will be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1267 ;; called a match. A special advice class `any' can be used to consider
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1268 ;; all advice classes:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1269 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1270 ;; (ad-disable-advice 'foo 'any "^fg-.*times")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1271 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1272 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1273 ;; (ad-activate 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1274 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1275 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1276 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1277 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1278 ;; 5
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1279 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1280 ;; To enable the disabled advice we could use either `ad-enable-advice'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1281 ;; similar to `ad-disable-advice', or as an alternative `ad-enable-regexp'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1282 ;; which will enable matching advices in ALL currently advised functions.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1283 ;; Hence, this can be used to dis/enable advices made by a particular
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1284 ;; package to a set of functions as long as that package obeys standard
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1285 ;; advice name conventions. We prefixed all advice names with `fg-', hence
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1286 ;; the following will do the trick (`ad-enable-regexp' returns the number
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1287 ;; of matched advices):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1288 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1289 ;; (ad-enable-regexp "^fg-")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1290 ;; 9
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1291 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1292 ;; The following will activate all currently active advised functions that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1293 ;; contain some advice matched by the regular expression. This is a save
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1294 ;; way to update the activation of advised functions whose advice changed
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1295 ;; in some way or other without accidentally also activating currently
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1296 ;; deactivated functions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1297 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1298 ;; (ad-update-regexp "^fg-")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1299 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1300 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1301 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1302 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1303 ;; 72
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1304 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1305 ;; Another use for the dis/enablement mechanism is to define a piece of advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1306 ;; and keep it "dormant" until a particular condition is satisfied, i.e., until
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1307 ;; then the advice will not be used during activation. The `disable' flag lets
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1308 ;; one do that with `defadvice':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1309 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1310 ;; (defadvice foo (before fg-1-more dis)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1311 ;; "Add yet 1 more."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1312 ;; (setq x (1+ x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1313 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1314 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1315 ;; (ad-activate 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1316 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1317 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1318 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1319 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1320 ;; 72
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1321 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1322 ;; (ad-enable-advice 'foo 'before 'fg-1-more)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1323 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1324 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1325 ;; (ad-activate 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1326 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1327 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1328 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1329 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1330 ;; 160
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1331 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1332 ;; @@ Caching:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1333 ;; ===========
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1334 ;; Advised definitions get cached to allow efficient activation/deactivation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1335 ;; without having to reconstruct them if nothing in the advice-info of a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1336 ;; function has changed. The following idiom can be used to temporarily
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1337 ;; deactivate functions that have a piece of advice defined by a certain
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1338 ;; package (we save the old definition to check out caching):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1339 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1340 ;; (setq old-definition (symbol-function 'foo))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1341 ;; (lambda (x) ....)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1342 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1343 ;; (ad-deactivate-regexp "^fg-")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1344 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1345 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1346 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1347 ;; 4
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1348 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1349 ;; (ad-activate-regexp "^fg-")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1350 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1351 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1352 ;; (eq old-definition (symbol-function 'foo))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1353 ;; t
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1354 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1355 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1356 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1357 ;; 160
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1358 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1359 ;; @@ Forward advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1360 ;; ==================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1361 ;; To enable automatic activation of forward advice we first have to set
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1362 ;; `ad-activate-on-definition' to t and restart advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1363 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1364 ;; (setq ad-activate-on-definition t)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1365 ;; t
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1366 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1367 ;; (ad-start-advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1368 ;; (ad-activate-defined-function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1369 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1370 ;; Let's define a piece of advice for an undefined function:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1371 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1372 ;; (defadvice bar (before fg-sub-1-more act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1373 ;; "Subtract one more from X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1374 ;; (setq x (1- x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1375 ;; bar
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1376 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1377 ;; `bar' is not yet defined:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1378 ;; (fboundp 'bar)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1379 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1380 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1381 ;; Now we define it and the forward advice will get activated (only because
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1382 ;; `ad-activate-on-definition' was t when we started advice above with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1383 ;; `ad-start-advice'):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1384 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1385 ;; (defun bar (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1386 ;; "Subtract 1 from X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1387 ;; (1- x))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1388 ;; bar
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1389 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1390 ;; (bar 4)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1391 ;; 2
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1392 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1393 ;; Redefinition will activate any available advice if the value of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1394 ;; `ad-redefinition-action' is either `warn', `accept' or `discard':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1395 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1396 ;; (defun bar (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1397 ;; "Subtract 2 from X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1398 ;; (- x 2))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1399 ;; bar
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1400 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1401 ;; (bar 4)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1402 ;; 1
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1403 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1404 ;; @@ Preactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1405 ;; =================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1406 ;; Constructing advised definitions is moderately expensive, hence, it is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1407 ;; desirable to have a way to construct them at byte-compile time.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1408 ;; Preactivation is a mechanism that allows one to do that.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1409 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1410 ;; (defun fie (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1411 ;; "Multiply X by 2."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1412 ;; (* x 2))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1413 ;; fie
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1414 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1415 ;; (defadvice fie (before fg-times-4 preact)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1416 ;; "Multiply X by 4."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1417 ;; (setq x (* x 2)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1418 ;; fie
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1419 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1420 ;; This advice did not affect `fie'...
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1421 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1422 ;; (fie 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1423 ;; 4
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1424 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1425 ;; ...but it constructed a cached definition that will be used once `fie' gets
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1426 ;; activated as long as its current advice state is the same as it was during
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1427 ;; preactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1428 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1429 ;; (setq cached-definition (ad-get-cache-definition 'fie))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1430 ;; (lambda (x) ....)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1431 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1432 ;; (ad-activate 'fie)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1433 ;; fie
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1434 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1435 ;; (eq cached-definition (symbol-function 'fie))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1436 ;; t
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1437 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1438 ;; (fie 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1439 ;; 8
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1440 ;;
11035
97da4cb32d03 Comment change.
Richard M. Stallman <rms@gnu.org>
parents: 8458
diff changeset
1441 ;; If you put a preactivating `defadvice' into a Lisp file that gets byte-
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1442 ;; compiled then the constructed advised definition will get compiled by
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1443 ;; the byte-compiler. For that to occur in a v18 emacs you have to put the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1444 ;; `defadvice' inside a `defun' because the v18 compiler does not compile
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1445 ;; top-level forms other than `defun' or `defmacro', for example,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1446 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1447 ;; (defun fg-defadvice-fum ()
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1448 ;; (defadvice fum (before fg-times-4 preact act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1449 ;; "Multiply X by 4."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1450 ;; (setq x (* x 2))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1451 ;; fg-defadvice-fum
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1452 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1453 ;; So far, no `defadvice' for `fum' got executed, but when we compile
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1454 ;; `fg-defadvice-fum' the `defadvice' will be expanded by the byte compiler.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1455 ;; In order for preactivation to be effective we have to have a proper
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1456 ;; definition of `fum' around at preactivation time, hence, we define it now:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1457 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1458 ;; (defun fum (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1459 ;; "Multiply X by 2."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1460 ;; (* x 2))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1461 ;; fum
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1462 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1463 ;; Now we compile the defining function which will construct an advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1464 ;; definition during expansion of the `defadvice', compile it and store it
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1465 ;; as part of the compiled `fg-defadvice-fum':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1466 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1467 ;; (ad-compile-function 'fg-defadvice-fum)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1468 ;; (lambda nil (byte-code ...))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1469 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1470 ;; `fum' is still completely unaffected:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1471 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1472 ;; (fum 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1473 ;; 4
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1474 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1475 ;; (ad-get-advice-info 'fum)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1476 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1477 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1478 ;; (fg-defadvice-fum)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1479 ;; fum
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1480 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1481 ;; Now the advised version of `fum' is compiled because the compiled definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1482 ;; constructed during preactivation was used, even though we did not specify
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1483 ;; the `compile' flag:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1484 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1485 ;; (symbol-function 'fum)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1486 ;; (lambda (x)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1487 ;; "$ad-doc: fum$"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1488 ;; (byte-code "....." [ad-return-value x nil * 2 ad-Orig-fum] 4))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1489 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1490 ;; (fum 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1491 ;; 8
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1492 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1493 ;; A preactivated definition will only be used if it matches the current
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1494 ;; function definition and advice information. If it does not match it
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1495 ;; will simply be discarded and a new advised definition will be constructed
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1496 ;; from scratch. For example, let's first remove all advice-info for `fum':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1497 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1498 ;; (ad-unadvise 'fum)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1499 ;; (("fie") ("bar") ("foo") ...)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1500 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1501 ;; And now define a new piece of advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1502 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1503 ;; (defadvice fum (before fg-interactive act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1504 ;; "Make fum interactive."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1505 ;; (interactive "nEnter x: "))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1506 ;; fum
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1507 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1508 ;; When we now try to use a preactivation it will not be used because the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1509 ;; current advice state is different from the one at preactivation time. This
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1510 ;; is no tragedy, everything will work as expected just not as efficient,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1511 ;; because a new advised definition has to be constructed from scratch:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1512 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1513 ;; (fg-defadvice-fum)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1514 ;; fum
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1515 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1516 ;; A new uncompiled advised definition got constructed:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1517 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1518 ;; (ad-compiled-p (symbol-function 'fum))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1519 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1520 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1521 ;; (fum 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1522 ;; 8
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1523 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1524 ;; MORAL: To get all the efficiency out of preactivation the function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1525 ;; definition and advice state at preactivation time must be the same as the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1526 ;; state at activation time. Preactivation does work with forward advice, all
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1527 ;; that's necessary is that the definition of the forward advised function is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1528 ;; available when the `defadvice' with the preactivation gets compiled.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1529 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1530 ;; @@ Portable argument access:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1531 ;; ============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1532 ;; So far, we always used the actual argument variable names to access an
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1533 ;; argument in a piece of advice. For many advice applications this is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1534 ;; perfectly ok and keeps advices simple. However, it decreases portability
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1535 ;; of advices because it assumes specific argument variable names. For example,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1536 ;; if one advises a subr such as `eval-region' which then gets redefined by
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1537 ;; some package (e.g., edebug) into a function with different argument names,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1538 ;; then a piece of advice written for `eval-region' that was written with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1539 ;; the subr arguments in mind will break. Similar situations arise when one
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1540 ;; switches between major Emacs versions, e.g., certain subrs in v18 are
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1541 ;; functions in v19 and vice versa. Also, in v19s subr argument lists
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1542 ;; are available and will be used, while they are not available in v18.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1543 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1544 ;; Argument access text macros allow one to access arguments of an advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1545 ;; function in a portable way without having to worry about all these
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1546 ;; possibilities. These macros will be translated into the proper access forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1547 ;; at activation time, hence, argument access will be as efficient as if
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1548 ;; the arguments had been used directly in the definition of the advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1549 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1550 ;; (defun fuu (x y z)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1551 ;; "Add 3 numbers."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1552 ;; (+ x y z))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1553 ;; fuu
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1554 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1555 ;; (fuu 1 1 1)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1556 ;; 3
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1557 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1558 ;; Argument access macros specify actual arguments at a certain position.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1559 ;; Position 0 access the first actual argument, position 1 the second etc.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1560 ;; For example, the following advice adds 1 to each of the 3 arguments:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1561 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1562 ;; (defadvice fuu (before fg-add-1-to-all act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1563 ;; "Adds 1 to all arguments."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1564 ;; (ad-set-arg 0 (1+ (ad-get-arg 0)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1565 ;; (ad-set-arg 1 (1+ (ad-get-arg 1)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1566 ;; (ad-set-arg 2 (1+ (ad-get-arg 2))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1567 ;; fuu
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1568 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1569 ;; (fuu 1 1 1)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1570 ;; 6
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1571 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1572 ;; Now suppose somebody redefines `fuu' with a rest argument. Our advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1573 ;; will still work because we used access macros (note, that automatic
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1574 ;; advice activation is still in effect, hence, the redefinition of `fuu'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1575 ;; will automatically activate all its advice):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1576 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1577 ;; (defun fuu (&rest numbers)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1578 ;; "Add NUMBERS."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1579 ;; (apply '+ numbers))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1580 ;; fuu
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1581 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1582 ;; (fuu 1 1 1)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1583 ;; 6
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1584 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1585 ;; (fuu 1 1 1 1 1 1)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1586 ;; 9
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1587 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1588 ;; What's important to notice is that argument access macros access actual
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1589 ;; arguments regardless of how they got distributed onto argument variables.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1590 ;; In Emacs Lisp the semantics of an actual argument is determined purely
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1591 ;; by position, hence, as long as nobody changes the semantics of what a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1592 ;; certain actual argument at a certain position means the access macros
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1593 ;; will do the right thing.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1594 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1595 ;; Because of &rest arguments we need a second kind of access macro that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1596 ;; can access all actual arguments starting from a certain position:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1597 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1598 ;; (defadvice fuu (before fg-print-args act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1599 ;; "Print all arguments."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1600 ;; (print (ad-get-args 0)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1601 ;; fuu
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1602 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1603 ;; (fuu 1 2 3 4 5)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1604 ;; (1 2 3 4 5)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1605 ;; 18
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1606 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1607 ;; (defadvice fuu (before fg-set-args act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1608 ;; "Swaps 2nd and 3rd arg and discards all the rest."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1609 ;; (ad-set-args 1 (list (ad-get-arg 2) (ad-get-arg 1))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1610 ;; fuu
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1611 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1612 ;; (fuu 1 2 3 4 4 4 4 4 4)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1613 ;; (1 3 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1614 ;; 9
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1615 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1616 ;; (defun fuu (x y z)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1617 ;; "Add 3 numbers."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1618 ;; (+ x y z))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1619 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1620 ;; (fuu 1 2 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1621 ;; (1 3 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1622 ;; 9
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1623 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1624 ;; @@ Defining the argument list of an advised function:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1625 ;; =====================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1626 ;; Once in a while it might be desirable to advise a function and additionally
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1627 ;; give it an extra argument that controls the advised code, for example, one
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1628 ;; might want to make an interactive function sensitive to a prefix argument.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1629 ;; For such cases `defadvice' allows the specification of an argument list
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1630 ;; for the advised function. Similar to the redefinition of interactive
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1631 ;; behavior, the first argument list specification found in the list of before/
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1632 ;; around/after advices will be used. Of course, the specified argument list
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1633 ;; should be downward compatible with the original argument list, otherwise
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1634 ;; functions that call the advised function with the original argument list
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1635 ;; in mind will break.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1636 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1637 ;; (defun fii (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1638 ;; "Add 1 to X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1639 ;; (1+ x))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1640 ;; fii
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1641 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1642 ;; Now we advise `fii' to use an optional second argument that controls the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1643 ;; amount of incrementation. A list following the (optional) position
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1644 ;; argument of the advice will be interpreted as an argument list
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1645 ;; specification. This means you cannot specify an empty argument list, and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1646 ;; why would you want to anyway?
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1647 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1648 ;; (defadvice fii (before fg-inc-x (x &optional incr) act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1649 ;; "Increment X by INCR (default is 1)."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1650 ;; (setq x (+ x (1- (or incr 1)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1651 ;; fii
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1652 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1653 ;; (fii 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1654 ;; 4
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1655 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1656 ;; (fii 3 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1657 ;; 5
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1658 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1659 ;; @@ Specifying argument lists of subrs:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1660 ;; ======================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1661 ;; The argument lists of subrs cannot be determined directly from Lisp.
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1662 ;; This means that Advice has to use `(&rest ad-subr-args)' as the
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1663 ;; argument list of the advised subr which is not very efficient. In Lemacs
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1664 ;; subr argument lists can be determined from their documentation string, in
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1665 ;; Emacs-19 this is the case for some but not all subrs. To accommodate
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1666 ;; for the cases where the argument lists cannot be determined (e.g., in a
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1667 ;; v18 Emacs) Advice comes with a specification mechanism that allows the
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1668 ;; advice programmer to tell advice what the argument list of a certain subr
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1669 ;; really is.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1670 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1671 ;; In a v18 Emacs the following will return the &rest idiom:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1672 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1673 ;; (ad-arglist (symbol-function 'car))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1674 ;; (&rest ad-subr-args)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1675 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1676 ;; To tell advice what the argument list of `car' really is we
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1677 ;; can do the following:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1678 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1679 ;; (ad-define-subr-args 'car '(list))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1680 ;; ((list))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1681 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1682 ;; Now `ad-arglist' will return the proper argument list (this method is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1683 ;; actually used by advice itself for the advised definition of `fset'):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1684 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1685 ;; (ad-arglist (symbol-function 'car))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1686 ;; (list)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1687 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1688 ;; The defined argument list will be stored on the property list of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1689 ;; subr name symbol. When advice looks for a subr argument list it first
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1690 ;; checks for a definition on the property list, if that fails it tries
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1691 ;; to infer it from the documentation string and caches it on the property
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1692 ;; list if it was successful, otherwise `(&rest ad-subr-args)' will be used.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1693 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1694 ;; @@ Advising interactive subrs:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1695 ;; ==============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1696 ;; For the most part there is no difference between advising functions and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1697 ;; advising subrs. There is one situation though where one might have to write
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1698 ;; slightly different advice code for subrs than for functions. This case
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1699 ;; arises when one wants to access subr arguments in a before/around advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1700 ;; when the arguments were determined by an interactive call to the subr.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1701 ;; Advice cannot determine what `interactive' form determines the interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1702 ;; behavior of the subr, hence, when it calls the original definition in an
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1703 ;; interactive subr invocation it has to use `call-interactively' to generate
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1704 ;; the proper interactive behavior. Thus up to that call the arguments of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1705 ;; interactive subr will be nil. For example, the following advice for
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1706 ;; `kill-buffer' will not work in an interactive invocation...
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1707 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1708 ;; (defadvice kill-buffer (before fg-kill-buffer-hook first act preact comp)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1709 ;; (my-before-kill-buffer-hook (ad-get-arg 0)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1710 ;; kill-buffer
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1711 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1712 ;; ...because the buffer argument will be nil in that case. The way out of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1713 ;; this dilemma is to provide an `interactive' specification that mirrors
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1714 ;; the interactive behavior of the unadvised subr, for example, the following
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1715 ;; will do the right thing even when `kill-buffer' is called interactively:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1716 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1717 ;; (defadvice kill-buffer (before fg-kill-buffer-hook first act preact comp)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1718 ;; (interactive "bKill buffer: ")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1719 ;; (my-before-kill-buffer-hook (ad-get-arg 0)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1720 ;; kill-buffer
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1721 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1722 ;; @@ Advising macros:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1723 ;; ===================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1724 ;; Advising macros is slightly different because there are two significant
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1725 ;; time points in the invocation of a macro: Expansion and evaluation time.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1726 ;; For an advised macro instead of evaluating the original definition we
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1727 ;; use `macroexpand', that is, changing argument values and binding
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1728 ;; environments by pieces of advice has an affect during macro expansion
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1729 ;; but not necessarily during evaluation. In particular, any side effects
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1730 ;; of pieces of advice will occur during macro expansion. To also affect
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1731 ;; the behavior during evaluation time one has to change the value of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1732 ;; `ad-return-value' in a piece of after advice. For example:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1733 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1734 ;; (defmacro foom (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1735 ;; (` (list (, x))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1736 ;; foom
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1737 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1738 ;; (foom '(a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1739 ;; ((a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1740 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1741 ;; (defadvice foom (before fg-print-x act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1742 ;; "Print the value of X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1743 ;; (print x))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1744 ;; foom
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1745 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1746 ;; The following works as expected because evaluation immediately follows
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1747 ;; macro expansion:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1748 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1749 ;; (foom '(a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1750 ;; (quote (a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1751 ;; ((a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1752 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1753 ;; However, the printing happens during expansion (or byte-compile) time:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1754 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1755 ;; (macroexpand '(foom '(a)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1756 ;; (quote (a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1757 ;; (list (quote (a)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1758 ;;
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1759 ;; If we want it to happen during evaluation time we have to do the
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1760 ;; following (first remove the old advice):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1761 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1762 ;; (ad-remove-advice 'foom 'before 'fg-print-x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1763 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1764 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1765 ;; (defadvice foom (after fg-print-x act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1766 ;; "Print the value of X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1767 ;; (setq ad-return-value
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1768 ;; (` (progn (print (, x))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1769 ;; (, ad-return-value)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1770 ;; foom
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1771 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1772 ;; (macroexpand '(foom '(a)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1773 ;; (progn (print (quote (a))) (list (quote (a))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1774 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1775 ;; (foom '(a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1776 ;; (a)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1777 ;; ((a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1778 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1779 ;; While this method might seem somewhat cumbersome, it is very general
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1780 ;; because it allows one to influence macro expansion as well as evaluation.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1781 ;; In general, advising macros should be a rather rare activity anyway, in
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1782 ;; particular, because compile-time macro expansion takes away a lot of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1783 ;; flexibility and effectiveness of the advice mechanism. Macros that were
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1784 ;; compile-time expanded before the advice was activated will of course never
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1785 ;; exhibit the advised behavior.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1786 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1787 ;; @@ Advising special forms:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1788 ;; ==========================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1789 ;; Now for something that should be even more rare than advising macros:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1790 ;; Advising special forms. Because special forms are irregular in their
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1791 ;; argument evaluation behavior (e.g., `setq' evaluates the second but not
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1792 ;; the first argument) they have to be advised into macros. A dangerous
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1793 ;; consequence of this is that the byte-compiler will not recognize them
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1794 ;; as special forms anymore (well, in most cases) and use their expansion
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1795 ;; rather than the proper byte-code. Also, because the original definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1796 ;; of a special form cannot be `funcall'ed, `eval' has to be used instead
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1797 ;; which is less efficient.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1798 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1799 ;; MORAL: Do not advise special forms unless you are completely sure about
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1800 ;; what you are doing (some of the forward advice behavior is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1801 ;; implemented via advice of the special forms `defun' and `defmacro').
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1802 ;; As a safety measure one should always do `ad-deactivate-all' before
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1803 ;; one byte-compiles a file to avoid any interference of advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1804 ;; special forms.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1805 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1806 ;; Apart from the safety concerns advising special forms is not any different
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1807 ;; from advising plain functions or subrs.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1808
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1809
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1810 ;;; Code:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1811
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1812 ;; @ Advice implementation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1813 ;; ========================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1814
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1815 ;; @@ Compilation idiosyncrasies:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1816 ;; ==============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1817
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1818 ;; `defadvice' expansion needs quite a few advice functions and variables,
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1819 ;; hence, I need to preload the file before it can be compiled. To avoid
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1820 ;; interference of bogus compiled files I always preload the source file:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1821 (provide 'advice-preload)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1822 ;; During a normal load this is a noop:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1823 (require 'advice-preload "advice.el")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1824
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1825
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
1826 ;; @@ Variable definitions:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
1827 ;; ========================
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
1828
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1829 (defgroup advice nil
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1830 "An overloading mechanism for Emacs Lisp functions."
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1831 :prefix "ad-"
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1832 :link '(custom-manual "(elisp)Advising Functions")
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1833 :group 'lisp)
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1834
8458
a95ca44cec95 (ad-subr-arglist): Adapted to new DOC file format.
Richard M. Stallman <rms@gnu.org>
parents: 8445
diff changeset
1835 (defconst ad-version "2.14")
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1836
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1837 ;;;###autoload
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1838 (defcustom ad-redefinition-action 'warn
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
1839 "*Defines what to do with redefinitions during Advice de/activation.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1840 Redefinition occurs if a previously activated function that already has an
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1841 original definition associated with it gets redefined and then de/activated.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1842 In such a case we can either accept the current definition as the new
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1843 original definition, discard the current definition and replace it with the
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1844 old original, or keep it and raise an error. The values `accept', `discard',
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1845 `error' or `warn' govern what will be done. `warn' is just like `accept' but
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1846 it additionally prints a warning message. All other values will be
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1847 interpreted as `error'."
22577
c129b4c40a0c (ad-redefinition-action,
Andreas Schwab <schwab@suse.de>
parents: 22061
diff changeset
1848 :type '(choice (const accept) (const discard) (const warn)
c129b4c40a0c (ad-redefinition-action,
Andreas Schwab <schwab@suse.de>
parents: 22061
diff changeset
1849 (other :tag "error" error))
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1850 :group 'advice)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1851
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1852 ;;;###autoload
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1853 (defcustom ad-default-compilation-action 'maybe
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
1854 "*Defines whether to compile advised definitions during activation.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
1855 A value of `always' will result in unconditional compilation, `never' will
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
1856 always avoid compilation, `maybe' will compile if the byte-compiler is already
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
1857 loaded, and `like-original' will compile if the original definition of the
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1858 advised function is compiled or a built-in function. Every other value will
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1859 be interpreted as `maybe'. This variable will only be considered if the
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1860 COMPILE argument of `ad-activate' was supplied as nil."
22577
c129b4c40a0c (ad-redefinition-action,
Andreas Schwab <schwab@suse.de>
parents: 22061
diff changeset
1861 :type '(choice (const always) (const never) (const like-original)
c129b4c40a0c (ad-redefinition-action,
Andreas Schwab <schwab@suse.de>
parents: 22061
diff changeset
1862 (other :tag "maybe" maybe))
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1863 :group 'advice)
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1864
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1865
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1866
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1867 ;; @@ Some utilities:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1868 ;; ==================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1869
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1870 ;; We don't want the local arguments to interfere with anything
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1871 ;; referenced in the supplied functions => the cryptic casing:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1872 (defun ad-substitute-tree (sUbTrEe-TeSt fUnCtIoN tReE)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1873 "Substitute qualifying subTREEs with result of FUNCTION(subTREE).
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1874 Only proper subtrees are considered, for example, if TREE is (1 (2 (3)) 4)
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1875 then the subtrees will be 1 (2 (3)) 2 (3) 3 4, dotted structures are
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1876 allowed too. Once a qualifying subtree has been found its subtrees will
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1877 not be considered anymore. (ad-substitute-tree 'atom 'identity tree)
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1878 generates a copy of TREE."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1879 (cond ((consp tReE)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1880 (cons (if (funcall sUbTrEe-TeSt (car tReE))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1881 (funcall fUnCtIoN (car tReE))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1882 (if (consp (car tReE))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1883 (ad-substitute-tree sUbTrEe-TeSt fUnCtIoN (car tReE))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1884 (car tReE)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1885 (ad-substitute-tree sUbTrEe-TeSt fUnCtIoN (cdr tReE))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1886 ((funcall sUbTrEe-TeSt tReE)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1887 (funcall fUnCtIoN tReE))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1888 (t tReE)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1889
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1890 ;; this is just faster than `ad-substitute-tree':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1891 (defun ad-copy-tree (tree)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1892 "Return a copy of the list structure of TREE."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1893 (cond ((consp tree)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1894 (cons (ad-copy-tree (car tree))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1895 (ad-copy-tree (cdr tree))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1896 (t tree)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1897
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1898 (defmacro ad-dolist (varform &rest body)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1899 "A Common-Lisp-style dolist iterator with the following syntax:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1900
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1901 (ad-dolist (VAR INIT-FORM [RESULT-FORM])
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1902 BODY-FORM...)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1903
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1904 which will iterate over the list yielded by INIT-FORM binding VAR to the
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1905 current head at every iteration. If RESULT-FORM is supplied its value will
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1906 be returned at the end of the iteration, nil otherwise. The iteration can be
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1907 exited prematurely with `(ad-do-return [VALUE])'."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1908 (let ((expansion
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1909 `(let ((ad-dO-vAr ,(car (cdr varform)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1910 ,(car varform))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1911 (while ad-dO-vAr
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1912 (setq ,(car varform) (car ad-dO-vAr))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1913 ,@body
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1914 ;;work around a backquote bug:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1915 ;;(` ((,@ '(foo)) (bar))) => (append '(foo) '(((bar)))) wrong
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1916 ;;(` ((,@ '(foo)) (, '(bar)))) => (append '(foo) (list '(bar)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1917 ,'(setq ad-dO-vAr (cdr ad-dO-vAr)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1918 ,(car (cdr (cdr varform))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1919 ;;ok, this wastes some cons cells but only during compilation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1920 (if (catch 'contains-return
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1921 (ad-substitute-tree
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1922 (function (lambda (subtree)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1923 (cond ((eq (car-safe subtree) 'ad-dolist))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1924 ((eq (car-safe subtree) 'ad-do-return)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1925 (throw 'contains-return t)))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1926 'identity body)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1927 nil)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1928 `(catch 'ad-dO-eXiT ,expansion)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1929 expansion)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1930
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1931 (defmacro ad-do-return (value)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1932 `(throw 'ad-dO-eXiT ,value))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1933
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1934 (if (not (get 'ad-dolist 'lisp-indent-hook))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1935 (put 'ad-dolist 'lisp-indent-hook 1))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1936
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1937
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1938 ;; @@ Save real definitions of subrs used by Advice:
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1939 ;; =================================================
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1940 ;; Advice depends on the real, unmodified functionality of various subrs,
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1941 ;; we save them here so advised versions will not interfere (eventually,
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1942 ;; we will save all subrs used in code generated by Advice):
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1943
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1944 (defmacro ad-save-real-definition (function)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1945 (let ((saved-function (intern (format "ad-real-%s" function))))
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1946 ;; Make sure the compiler is loaded during macro expansion:
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1947 (require 'byte-compile "bytecomp")
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1948 `(if (not (fboundp ',saved-function))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1949 (progn (fset ',saved-function (symbol-function ',function))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1950 ;; Copy byte-compiler properties:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1951 ,@(if (get function 'byte-compile)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1952 `((put ',saved-function 'byte-compile
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1953 ',(get function 'byte-compile))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1954 ,@(if (get function 'byte-opcode)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1955 `((put ',saved-function 'byte-opcode
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1956 ',(get function 'byte-opcode))))))))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1957
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1958 (defun ad-save-real-definitions ()
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1959 ;; Macro expansion will hardcode the values of the various byte-compiler
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1960 ;; properties into the compiled version of this function such that the
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1961 ;; proper values will be available at runtime without loading the compiler:
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1962 (ad-save-real-definition fset)
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
1963 (ad-save-real-definition documentation))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1964
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1965 (ad-save-real-definitions)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1966
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1967
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1968 ;; @@ Advice info access fns:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1969 ;; ==========================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1970
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1971 ;; Advice information for a particular function is stored on the
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1972 ;; advice-info property of the function symbol. It is stored as an
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1973 ;; alist of the following format:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1974 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1975 ;; ((active . t/nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1976 ;; (before adv1 adv2 ...)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1977 ;; (around adv1 adv2 ...)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1978 ;; (after adv1 adv2 ...)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1979 ;; (activation adv1 adv2 ...)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1980 ;; (deactivation adv1 adv2 ...)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1981 ;; (origname . <symbol fbound to origdef>)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1982 ;; (cache . (<advised-definition> . <id>)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1983
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1984 ;; List of currently advised though not necessarily activated functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1985 ;; (this list is maintained as a completion table):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1986 (defvar ad-advised-functions nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1987
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1988 (defmacro ad-pushnew-advised-function (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1989 "Add FUNCTION to `ad-advised-functions' unless its already there."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1990 `(if (not (assoc (symbol-name ,function) ad-advised-functions))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1991 (setq ad-advised-functions
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1992 (cons (list (symbol-name ,function))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1993 ad-advised-functions))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1994
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1995 (defmacro ad-pop-advised-function (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1996 "Remove FUNCTION from `ad-advised-functions'."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1997 `(setq ad-advised-functions
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1998 (delq (assoc (symbol-name ,function) ad-advised-functions)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1999 ad-advised-functions)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2000
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2001 (defmacro ad-do-advised-functions (varform &rest body)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2002 "`ad-dolist'-style iterator that maps over `ad-advised-functions'.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2003 \(ad-do-advised-functions (VAR [RESULT-FORM])
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2004 BODY-FORM...)
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2005 On each iteration VAR will be bound to the name of an advised function
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2006 \(a symbol)."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2007 `(ad-dolist (,(car varform)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2008 ad-advised-functions
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2009 ,(car (cdr varform)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2010 (setq ,(car varform) (intern (car ,(car varform))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2011 ,@body))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2012
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2013 (if (not (get 'ad-do-advised-functions 'lisp-indent-hook))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2014 (put 'ad-do-advised-functions 'lisp-indent-hook 1))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2015
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2016 (defmacro ad-get-advice-info (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2017 `(get ,function 'ad-advice-info))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2018
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2019 (defmacro ad-set-advice-info (function advice-info)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2020 `(put ,function 'ad-advice-info ,advice-info))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2021
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2022 (defmacro ad-copy-advice-info (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2023 `(ad-copy-tree (get ,function 'ad-advice-info)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2024
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2025 (defmacro ad-is-advised (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2026 "Return non-nil if FUNCTION has any advice info associated with it.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2027 This does not mean that the advice is also active."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2028 (list 'ad-get-advice-info function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2029
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2030 (defun ad-initialize-advice-info (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2031 "Initialize the advice info for FUNCTION.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2032 Assumes that FUNCTION has not yet been advised."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2033 (ad-pushnew-advised-function function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2034 (ad-set-advice-info function (list (cons 'active nil))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2035
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2036 (defmacro ad-get-advice-info-field (function field)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2037 "Retrieve the value of the advice info FIELD of FUNCTION."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2038 `(cdr (assq ,field (ad-get-advice-info ,function))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2039
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2040 (defun ad-set-advice-info-field (function field value)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2041 "Destructively modify VALUE of the advice info FIELD of FUNCTION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2042 (and (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2043 (cond ((assq field (ad-get-advice-info function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2044 ;; A field with that name is already present:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2045 (rplacd (assq field (ad-get-advice-info function)) value))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2046 (t;; otherwise, create a new field with that name:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2047 (nconc (ad-get-advice-info function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2048 (list (cons field value)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2049
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2050 ;; Don't make this a macro so we can use it as a predicate:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2051 (defun ad-is-active (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2052 "Return non-nil if FUNCTION is advised and activated."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2053 (ad-get-advice-info-field function 'active))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2054
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2055
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2056 ;; @@ Access fns for single pieces of advice and related predicates:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2057 ;; =================================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2058
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2059 (defun ad-make-advice (name protect enable definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2060 "Constructs single piece of advice to be stored in some advice-info.
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2061 NAME should be a non-nil symbol, PROTECT and ENABLE should each be
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2062 either t or nil, and DEFINITION should be a list of the form
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2063 `(advice lambda ARGLIST [DOCSTRING] [INTERACTIVE-FORM] BODY...)'."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2064 (list name protect enable definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2065
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2066 ;; ad-find-advice uses the alist structure directly ->
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2067 ;; change if this data structure changes!!
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2068 (defmacro ad-advice-name (advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2069 (list 'car advice))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2070 (defmacro ad-advice-protected (advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2071 (list 'nth 1 advice))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2072 (defmacro ad-advice-enabled (advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2073 (list 'nth 2 advice))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2074 (defmacro ad-advice-definition (advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2075 (list 'nth 3 advice))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2076
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2077 (defun ad-advice-set-enabled (advice flag)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2078 (rplaca (cdr (cdr advice)) flag))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2079
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2080 (defun ad-class-p (thing)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2081 (memq thing ad-advice-classes))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2082 (defun ad-name-p (thing)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2083 (and thing (symbolp thing)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2084 (defun ad-position-p (thing)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2085 (or (natnump thing)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2086 (memq thing '(first last))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2087
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2088
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2089 ;; @@ Advice access functions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2090 ;; ===========================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2091
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2092 ;; List of defined advice classes:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2093 (defvar ad-advice-classes '(before around after activation deactivation))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2094
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2095 (defun ad-has-enabled-advice (function class)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2096 "True if at least one of FUNCTION's advices in CLASS is enabled."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2097 (ad-dolist (advice (ad-get-advice-info-field function class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2098 (if (ad-advice-enabled advice) (ad-do-return t))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2099
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2100 (defun ad-has-redefining-advice (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2101 "True if FUNCTION's advice info defines at least 1 redefining advice.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2102 Redefining advices affect the construction of an advised definition."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2103 (and (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2104 (or (ad-has-enabled-advice function 'before)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2105 (ad-has-enabled-advice function 'around)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2106 (ad-has-enabled-advice function 'after))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2107
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2108 (defun ad-has-any-advice (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2109 "True if the advice info of FUNCTION defines at least one advice."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2110 (and (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2111 (ad-dolist (class ad-advice-classes nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2112 (if (ad-get-advice-info-field function class)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2113 (ad-do-return t)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2114
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2115 (defun ad-get-enabled-advices (function class)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2116 "Return the list of enabled advices of FUNCTION in CLASS."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2117 (let (enabled-advices)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2118 (ad-dolist (advice (ad-get-advice-info-field function class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2119 (if (ad-advice-enabled advice)
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2120 (push advice enabled-advices)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2121 (reverse enabled-advices)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2122
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2123
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2124 ;; @@ Dealing with automatic advice activation via `fset/defalias':
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2125 ;; ================================================================
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2126
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2127 ;; Since Emacs 19.26 the built-in versions of `fset' and `defalias'
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2128 ;; take care of automatic advice activation, hence, we don't have to
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2129 ;; hack it anymore by advising `fset/defun/defmacro/byte-code/etc'.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2130
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2131 ;; The functionality of the new `fset' is as follows:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2132 ;;
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2133 ;; fset(sym,newdef)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2134 ;; assign NEWDEF to SYM
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2135 ;; if (get SYM 'ad-advice-info)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
2136 ;; ad-activate-internal(SYM, nil)
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2137 ;; return (symbol-function SYM)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2138 ;;
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2139 ;; Whether advised definitions created by automatic activations will be
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2140 ;; compiled depends on the value of `ad-default-compilation-action'.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2141
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
2142 ;; Since calling `ad-activate-internal' in the built-in definition of `fset' can
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2143 ;; create major disasters we have to be a bit careful. One precaution is
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
2144 ;; to provide a dummy definition for `ad-activate-internal' which can be used to
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2145 ;; turn off automatic advice activation (e.g., when `ad-stop-advice' or
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2146 ;; `ad-recover-normality' are called). Another is to avoid recursive calls
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
2147 ;; to `ad-activate' by using `ad-with-auto-activation-disabled' where
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2148 ;; appropriate, especially in a safe version of `fset'.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2149
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
2150 ;; For now define `ad-activate-internal' to the dummy definition:
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
2151 (defun ad-activate-internal (function &optional compile)
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2152 "Automatic advice activation is disabled. `ad-start-advice' enables it."
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2153 nil)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2154
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2155 ;; This is just a copy of the above:
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
2156 (defun ad-activate-internal-off (function &optional compile)
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2157 "Automatic advice activation is disabled. `ad-start-advice' enables it."
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2158 nil)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2159
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
2160 ;; This will be t for top-level calls to `ad-activate-internal-on':
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2161 (defvar ad-activate-on-top-level t)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2162
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2163 (defmacro ad-with-auto-activation-disabled (&rest body)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2164 `(let ((ad-activate-on-top-level nil))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2165 ,@body))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2166
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2167 (defun ad-safe-fset (symbol definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2168 "A safe `fset' which will never call `ad-activate-internal' recursively."
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2169 (ad-with-auto-activation-disabled
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2170 (ad-real-fset symbol definition)))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2171
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2172
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2173 ;; @@ Access functions for original definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2174 ;; ============================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2175 ;; The advice-info of an advised function contains its `origname' which is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2176 ;; a symbol that is fbound to the original definition available at the first
60923
08f8c7042636 * emacs-lisp/advice.el: Replace `legal' with `valid'.
Werner LEMBERG <wl@gnu.org>
parents: 57879
diff changeset
2177 ;; proper activation of the function after a valid re/definition. If the
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2178 ;; original was defined via fcell indirection then `origname' will be defined
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2179 ;; just so. Hence, to get hold of the actual original definition of a function
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2180 ;; we need to use `ad-real-orig-definition'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2181
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2182 (defun ad-make-origname (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2183 "Make name to be used to call the original FUNCTION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2184 (intern (format "ad-Orig-%s" function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2185
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2186 (defmacro ad-get-orig-definition (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2187 `(let ((origname (ad-get-advice-info-field ,function 'origname)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2188 (if (fboundp origname)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2189 (symbol-function origname))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2190
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2191 (defmacro ad-set-orig-definition (function definition)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2192 `(ad-safe-fset
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2193 (ad-get-advice-info-field function 'origname) ,definition))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2194
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2195 (defmacro ad-clear-orig-definition (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2196 `(fmakunbound (ad-get-advice-info-field ,function 'origname)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2197
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2198
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2199 ;; @@ Interactive input functions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2200 ;; ===============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2201
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2202 (defun ad-read-advised-function (&optional prompt predicate default)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2203 "Read name of advised function with completion from the minibuffer.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2204 An optional PROMPT will be used to prompt for the function. PREDICATE
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2205 plays the same role as for `try-completion' (which see). DEFAULT will
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2206 be returned on empty input (defaults to the first advised function for
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2207 which PREDICATE returns non-nil)."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2208 (if (null ad-advised-functions)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2209 (error "ad-read-advised-function: There are no advised functions"))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2210 (setq default
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2211 (or default
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2212 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2213 (if (or (null predicate)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2214 (funcall predicate function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2215 (ad-do-return function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2216 (error "ad-read-advised-function: %s"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2217 "There are no qualifying advised functions")))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2218 (let* ((ad-pReDiCaTe predicate)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2219 (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2220 (completing-read
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
2221 (format "%s (default %s): " (or prompt "Function") default)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2222 ad-advised-functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2223 (if predicate
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2224 (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2225 (lambda (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2226 ;; Oops, no closures - the joys of dynamic scoping:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2227 ;; `predicate' clashed with the `predicate' argument
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2228 ;; of Lemacs' `completing-read'.....
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2229 (funcall ad-pReDiCaTe (intern (car function))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2230 t)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2231 (if (equal function "")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2232 (if (ad-is-advised default)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2233 default
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2234 (error "ad-read-advised-function: `%s' is not advised" default))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2235 (intern function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2236
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2237 (defvar ad-advice-class-completion-table
29579
05016ef95d0f (ad-advice-class-completion-table)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 26627
diff changeset
2238 (mapcar (lambda (class) (list (symbol-name class)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2239 ad-advice-classes))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2240
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2241 (defun ad-read-advice-class (function &optional prompt default)
60923
08f8c7042636 * emacs-lisp/advice.el: Replace `legal' with `valid'.
Werner LEMBERG <wl@gnu.org>
parents: 57879
diff changeset
2242 "Read a valid advice class with completion from the minibuffer.
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2243 An optional PROMPT will be used to prompt for the class. DEFAULT will
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2244 be returned on empty input (defaults to the first non-empty advice
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2245 class of FUNCTION)."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2246 (setq default
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2247 (or default
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2248 (ad-dolist (class ad-advice-classes)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2249 (if (ad-get-advice-info-field function class)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2250 (ad-do-return class)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2251 (error "ad-read-advice-class: `%s' has no advices" function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2252 (let ((class (completing-read
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
2253 (format "%s (default %s): " (or prompt "Class") default)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2254 ad-advice-class-completion-table nil t)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2255 (if (equal class "")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2256 default
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2257 (intern class))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2258
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2259 (defun ad-read-advice-name (function class &optional prompt)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2260 "Read name of existing advice of CLASS for FUNCTION with completion.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2261 An optional PROMPT is used to prompt for the name."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2262 (let* ((name-completion-table
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2263 (mapcar (function (lambda (advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2264 (list (symbol-name (ad-advice-name advice)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2265 (ad-get-advice-info-field function class)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2266 (default
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2267 (if (null name-completion-table)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2268 (error "ad-read-advice-name: `%s' has no %s advice"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2269 function class)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2270 (car (car name-completion-table))))
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
2271 (prompt (format "%s (default %s): " (or prompt "Name") default))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2272 (name (completing-read prompt name-completion-table nil t)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2273 (if (equal name "")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2274 (intern default)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2275 (intern name))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2276
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2277 (defun ad-read-advice-specification (&optional prompt)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2278 "Read a complete function/class/name specification from minibuffer.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2279 The list of read symbols will be returned. The optional PROMPT will
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2280 be used to prompt for the function."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2281 (let* ((function (ad-read-advised-function prompt))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2282 (class (ad-read-advice-class function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2283 (name (ad-read-advice-name function class)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2284 (list function class name)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2285
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2286 ;; Use previous regexp as a default:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2287 (defvar ad-last-regexp "")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2288
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2289 (defun ad-read-regexp (&optional prompt)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2290 "Read a regular expression from the minibuffer."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2291 (let ((regexp (read-from-minibuffer
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
2292 (concat (or prompt "Regular expression")
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
2293 (if (equal ad-last-regexp "") ": "
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
2294 (format " (default %s): " ad-last-regexp))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2295 (setq ad-last-regexp
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2296 (if (equal regexp "") ad-last-regexp regexp))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2297
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2298
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2299 ;; @@ Finding, enabling, adding and removing pieces of advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2300 ;; ===========================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2301
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2302 (defmacro ad-find-advice (function class name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2303 "Find the first advice of FUNCTION in CLASS with NAME."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2304 `(assq ,name (ad-get-advice-info-field ,function ,class)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2305
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2306 (defun ad-advice-position (function class name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2307 "Return position of first advice of FUNCTION in CLASS with NAME."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2308 (let* ((found-advice (ad-find-advice function class name))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2309 (advices (ad-get-advice-info-field function class)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2310 (if found-advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2311 (- (length advices) (length (memq found-advice advices))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2312
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2313 (defun ad-find-some-advice (function class name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2314 "Find the first of FUNCTION's advices in CLASS matching NAME.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2315 NAME can be a symbol or a regular expression matching part of an advice name.
60923
08f8c7042636 * emacs-lisp/advice.el: Replace `legal' with `valid'.
Werner LEMBERG <wl@gnu.org>
parents: 57879
diff changeset
2316 If CLASS is `any' all valid advice classes will be checked."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2317 (if (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2318 (let (found-advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2319 (ad-dolist (advice-class ad-advice-classes)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2320 (if (or (eq class 'any) (eq advice-class class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2321 (setq found-advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2322 (ad-dolist (advice (ad-get-advice-info-field
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2323 function advice-class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2324 (if (or (and (stringp name)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2325 (string-match
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2326 name (symbol-name
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2327 (ad-advice-name advice))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2328 (eq name (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2329 (ad-do-return advice)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2330 (if found-advice (ad-do-return found-advice))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2331
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2332 (defun ad-enable-advice-internal (function class name flag)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2333 "Set enable FLAG of FUNCTION's advices in CLASS matching NAME.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2334 If NAME is a string rather than a symbol then it's interpreted as a regular
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2335 expression and all advices whose name contain a match for it will be
60923
08f8c7042636 * emacs-lisp/advice.el: Replace `legal' with `valid'.
Werner LEMBERG <wl@gnu.org>
parents: 57879
diff changeset
2336 affected. If CLASS is `any' advices in all valid advice classes will be
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2337 considered. The number of changed advices will be returned (or nil if
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2338 FUNCTION was not advised)."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2339 (if (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2340 (let ((matched-advices 0))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2341 (ad-dolist (advice-class ad-advice-classes)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2342 (if (or (eq class 'any) (eq advice-class class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2343 (ad-dolist (advice (ad-get-advice-info-field
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2344 function advice-class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2345 (cond ((or (and (stringp name)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2346 (string-match
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2347 name (symbol-name (ad-advice-name advice))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2348 (eq name (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2349 (setq matched-advices (1+ matched-advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2350 (ad-advice-set-enabled advice flag))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2351 matched-advices)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2352
70899
b920ab84fba8 (ad-enable-advice, ad-activate, ad-disable-advice): Add autoloads.
Richard M. Stallman <rms@gnu.org>
parents: 68648
diff changeset
2353 ;;;###autoload
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2354 (defun ad-enable-advice (function class name)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2355 "Enables the advice of FUNCTION with CLASS and NAME."
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
2356 (interactive (ad-read-advice-specification "Enable advice of"))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2357 (if (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2358 (if (eq (ad-enable-advice-internal function class name t) 0)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2359 (error "ad-enable-advice: `%s' has no %s advice matching `%s'"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2360 function class name))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2361 (error "ad-enable-advice: `%s' is not advised" function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2362
70899
b920ab84fba8 (ad-enable-advice, ad-activate, ad-disable-advice): Add autoloads.
Richard M. Stallman <rms@gnu.org>
parents: 68648
diff changeset
2363 ;;;###autoload
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2364 (defun ad-disable-advice (function class name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2365 "Disable the advice of FUNCTION with CLASS and NAME."
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
2366 (interactive (ad-read-advice-specification "Disable advice of"))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2367 (if (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2368 (if (eq (ad-enable-advice-internal function class name nil) 0)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2369 (error "ad-disable-advice: `%s' has no %s advice matching `%s'"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2370 function class name))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2371 (error "ad-disable-advice: `%s' is not advised" function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2372
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2373 (defun ad-enable-regexp-internal (regexp class flag)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2374 "Set enable FLAGs of all CLASS advices whose name contains a REGEXP match.
60923
08f8c7042636 * emacs-lisp/advice.el: Replace `legal' with `valid'.
Werner LEMBERG <wl@gnu.org>
parents: 57879
diff changeset
2375 If CLASS is `any' all valid advice classes are considered. The number of
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2376 affected advices will be returned."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2377 (let ((matched-advices 0))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2378 (ad-do-advised-functions (advised-function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2379 (setq matched-advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2380 (+ matched-advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2381 (or (ad-enable-advice-internal
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2382 advised-function class regexp flag)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2383 0))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2384 matched-advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2385
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2386 (defun ad-enable-regexp (regexp)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2387 "Enables all advices with names that contain a match for REGEXP.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2388 All currently advised functions will be considered."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2389 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
2390 (list (ad-read-regexp "Enable advices via regexp")))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2391 (let ((matched-advices (ad-enable-regexp-internal regexp 'any t)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2392 (if (interactive-p)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2393 (message "%d matching advices enabled" matched-advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2394 matched-advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2395
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2396 (defun ad-disable-regexp (regexp)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2397 "Disable all advices with names that contain a match for REGEXP.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2398 All currently advised functions will be considered."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2399 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
2400 (list (ad-read-regexp "Disable advices via regexp")))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2401 (let ((matched-advices (ad-enable-regexp-internal regexp 'any nil)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2402 (if (interactive-p)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2403 (message "%d matching advices disabled" matched-advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2404 matched-advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2405
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2406 (defun ad-remove-advice (function class name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2407 "Remove FUNCTION's advice with NAME from its advices in CLASS.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2408 If such an advice was found it will be removed from the list of advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2409 in that CLASS."
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
2410 (interactive (ad-read-advice-specification "Remove advice of"))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2411 (if (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2412 (let* ((advice-to-remove (ad-find-advice function class name)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2413 (if advice-to-remove
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2414 (ad-set-advice-info-field
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2415 function class
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2416 (delq advice-to-remove (ad-get-advice-info-field function class)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2417 (error "ad-remove-advice: `%s' has no %s advice `%s'"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2418 function class name)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2419 (error "ad-remove-advice: `%s' is not advised" function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2420
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2421 ;;;###autoload
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2422 (defun ad-add-advice (function advice class position)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2423 "Add a piece of ADVICE to FUNCTION's list of advices in CLASS.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2424 If FUNCTION already has one or more pieces of advice of the specified
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2425 CLASS then POSITION determines where the new piece will go. The value
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2426 of POSITION can either be `first', `last' or a number where 0 corresponds
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2427 to `first'. Numbers outside the range will be mapped to the closest
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2428 extreme position. If there was already a piece of ADVICE with the same
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2429 name, then the position argument will be ignored and the old advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2430 will be overwritten with the new one.
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2431 If the FUNCTION was not advised already, then its advice info will be
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2432 initialized. Redefining a piece of advice whose name is part of the cache-id
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2433 will clear the cache."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2434 (cond ((not (ad-is-advised function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2435 (ad-initialize-advice-info function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2436 (ad-set-advice-info-field
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2437 function 'origname (ad-make-origname function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2438 (let* ((previous-position
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2439 (ad-advice-position function class (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2440 (advices (ad-get-advice-info-field function class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2441 ;; Determine a numerical position for the new advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2442 (position (cond (previous-position)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2443 ((eq position 'first) 0)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2444 ((eq position 'last) (length advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2445 ((numberp position)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2446 (max 0 (min position (length advices))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2447 (t 0))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2448 ;; Check whether we have to clear the cache:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2449 (if (memq (ad-advice-name advice) (ad-get-cache-class-id function class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2450 (ad-clear-cache function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2451 (if previous-position
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2452 (setcar (nthcdr position advices) advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2453 (if (= position 0)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2454 (ad-set-advice-info-field function class (cons advice advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2455 (setcdr (nthcdr (1- position) advices)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2456 (cons advice (nthcdr position advices)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2457
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2458
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2459 ;; @@ Accessing and manipulating function definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2460 ;; ===================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2461
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2462 (defmacro ad-macrofy (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2463 "Take a lambda function DEFINITION and make a macro out of it."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2464 `(cons 'macro ,definition))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2465
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2466 (defmacro ad-lambdafy (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2467 "Take a macro function DEFINITION and make a lambda out of it."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2468 `(cdr ,definition))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2469
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2470 ;; There is no way to determine whether some subr is a special form or not,
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2471 ;; hence we need this list (which is probably out of date):
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2472 (defvar ad-special-forms
25260
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2473 (let ((tem '(and catch cond condition-case defconst defmacro
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2474 defun defvar function if interactive let let*
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2475 or prog1 prog2 progn quote save-current-buffer
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2476 save-excursion save-restriction save-window-excursion
33665
b51b000b2c50 (ad-special-forms): Correct the conditional inclusion of `track-mouse'.
Miles Bader <miles@gnu.org>
parents: 29579
diff changeset
2477 setq setq-default unwind-protect while
25260
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2478 with-output-to-temp-buffer)))
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2479 ;; track-mouse could be void in some configurations.
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2480 (if (fboundp 'track-mouse)
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2481 (push 'track-mouse tem))
25260
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2482 (mapcar 'symbol-function tem)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2483
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2484 (defmacro ad-special-form-p (definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2485 ;;"non-nil if DEFINITION is a special form."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2486 (list 'memq definition 'ad-special-forms))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2487
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2488 (defmacro ad-interactive-p (definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2489 ;;"non-nil if DEFINITION can be called interactively."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2490 (list 'commandp definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2491
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2492 (defmacro ad-subr-p (definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2493 ;;"non-nil if DEFINITION is a subr."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2494 (list 'subrp definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2495
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2496 (defmacro ad-macro-p (definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2497 ;;"non-nil if DEFINITION is a macro."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2498 `(eq (car-safe ,definition) 'macro))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2499
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2500 (defmacro ad-lambda-p (definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2501 ;;"non-nil if DEFINITION is a lambda expression."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2502 `(eq (car-safe ,definition) 'lambda))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2503
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2504 ;; see ad-make-advice for the format of advice definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2505 (defmacro ad-advice-p (definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2506 ;;"non-nil if DEFINITION is a piece of advice."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2507 `(eq (car-safe ,definition) 'advice))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2508
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2509 ;; Emacs/Lemacs cross-compatibility
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2510 ;; (compiled-function-p is an obsolete function in Emacs):
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2511 (if (and (not (fboundp 'byte-code-function-p))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2512 (fboundp 'compiled-function-p))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2513 (ad-safe-fset 'byte-code-function-p 'compiled-function-p))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2514
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2515 (defmacro ad-compiled-p (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2516 "Return non-nil if DEFINITION is a compiled byte-code object."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2517 `(or (byte-code-function-p ,definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2518 (and (ad-macro-p ,definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2519 (byte-code-function-p (ad-lambdafy ,definition)))))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2520
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2521 (defmacro ad-compiled-code (compiled-definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2522 "Return the byte-code object of a COMPILED-DEFINITION."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2523 `(if (ad-macro-p ,compiled-definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2524 (ad-lambdafy ,compiled-definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2525 ,compiled-definition))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2526
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2527 (defun ad-lambda-expression (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2528 "Return the lambda expression of a function/macro/advice DEFINITION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2529 (cond ((ad-lambda-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2530 definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2531 ((ad-macro-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2532 (ad-lambdafy definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2533 ((ad-advice-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2534 (cdr definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2535 (t nil)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2536
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2537 (defun ad-arglist (definition &optional name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2538 "Return the argument list of DEFINITION.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2539 If DEFINITION could be from a subr then its NAME should be
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2540 supplied to make subr arglist lookup more efficient."
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2541 (cond ((ad-compiled-p definition)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2542 (aref (ad-compiled-code definition) 0))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2543 ((consp definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2544 (car (cdr (ad-lambda-expression definition))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2545 ((ad-subr-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2546 (if name
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2547 (ad-subr-arglist name)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2548 ;; otherwise get it from its printed representation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2549 (setq name (format "%s" definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2550 (string-match "^#<subr \\([^>]+\\)>$" name)
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2551 (ad-subr-arglist (intern (match-string 1 name)))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2552
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2553 ;; Store subr-args as `((arg1 arg2 ...))' so I can distinguish
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2554 ;; a defined empty arglist `(nil)' from an undefined arglist:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2555 (defmacro ad-define-subr-args (subr arglist)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2556 `(put ,subr 'ad-subr-arglist (list ,arglist)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2557 (defmacro ad-undefine-subr-args (subr)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2558 `(put ,subr 'ad-subr-arglist nil))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2559 (defmacro ad-subr-args-defined-p (subr)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2560 `(get ,subr 'ad-subr-arglist))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2561 (defmacro ad-get-subr-args (subr)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2562 `(car (get ,subr 'ad-subr-arglist)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2563
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2564 (defun ad-subr-arglist (subr-name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2565 "Retrieve arglist of the subr with SUBR-NAME.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2566 Either use the one stored under the `ad-subr-arglist' property,
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2567 or try to retrieve it from the docstring and cache it under
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2568 that property, or otherwise use `(&rest ad-subr-args)'."
54493
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2569 (if (ad-subr-args-defined-p subr-name)
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2570 (ad-get-subr-args subr-name)
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2571 ;; says jwz: Should use this for Lemacs 19.8 and above:
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2572 ;;((fboundp 'subr-min-args)
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2573 ;; ...)
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2574 ;; says hans: I guess what Jamie means is that I should use the values
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2575 ;; of `subr-min-args' and `subr-max-args' to construct the subr arglist
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2576 ;; without having to look it up via parsing the docstring, e.g.,
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2577 ;; values 1 and 2 would suggest `(arg1 &optional arg2)' as an
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2578 ;; argument list. However, that won't work because there is no
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2579 ;; way to distinguish a subr with args `(a &optional b &rest c)' from
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2580 ;; one with args `(a &rest c)' using that mechanism. Also, the argument
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2581 ;; names from the docstring are more meaningful. Hence, I'll stick with
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2582 ;; the old way of doing things.
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2583 (let ((doc (or (ad-real-documentation subr-name t) "")))
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2584 (if (not (string-match "\n\n\\((.+)\\)\\'" doc))
54509
e20bae3e3270 (ad-subr-arglist): Undo part of last patch.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 54493
diff changeset
2585 ;; Signalling an error leads to bugs during bootstrapping because
e20bae3e3270 (ad-subr-arglist): Undo part of last patch.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 54493
diff changeset
2586 ;; the DOC file is not yet built (which is an error, BTW).
e20bae3e3270 (ad-subr-arglist): Undo part of last patch.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 54493
diff changeset
2587 ;; (error "The usage info is missing from the subr %s" subr-name)
e20bae3e3270 (ad-subr-arglist): Undo part of last patch.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 54493
diff changeset
2588 '(&rest ad-subr-args)
54493
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2589 (ad-define-subr-args
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2590 subr-name
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2591 (cdr (car (read-from-string
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2592 (downcase (match-string 1 doc))))))
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2593 (ad-get-subr-args subr-name)))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2594
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2595 (defun ad-docstring (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2596 "Return the unexpanded docstring of DEFINITION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2597 (let ((docstring
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2598 (if (ad-compiled-p definition)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2599 (ad-real-documentation definition t)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2600 (car (cdr (cdr (ad-lambda-expression definition)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2601 (if (or (stringp docstring)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2602 (natnump docstring))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2603 docstring)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2604
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2605 (defun ad-interactive-form (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2606 "Return the interactive form of DEFINITION."
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2607 (cond ((ad-compiled-p definition)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2608 (and (commandp definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2609 (list 'interactive (aref (ad-compiled-code definition) 5))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2610 ((or (ad-advice-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2611 (ad-lambda-p definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2612 (commandp (ad-lambda-expression definition)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2613
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2614 (defun ad-body-forms (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2615 "Return the list of body forms of DEFINITION."
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2616 (cond ((ad-compiled-p definition)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2617 nil)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2618 ((consp definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2619 (nthcdr (+ (if (ad-docstring definition) 1 0)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2620 (if (ad-interactive-form definition) 1 0))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2621 (cdr (cdr (ad-lambda-expression definition)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2622
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2623 ;; Matches the docstring of an advised definition.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2624 ;; The first group of the regexp matches the function name:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2625 (defvar ad-advised-definition-docstring-regexp "^\\$ad-doc: \\(.+\\)\\$$")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2626
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2627 (defun ad-make-advised-definition-docstring (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2628 "Make an identifying docstring for the advised definition of FUNCTION.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2629 Put function name into the documentation string so we can infer
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2630 the name of the advised function from the docstring. This is needed
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2631 to generate a proper advised docstring even if we are just given a
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2632 definition (also see the defadvice for `documentation')."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2633 (format "$ad-doc: %s$" (prin1-to-string function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2634
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2635 (defun ad-advised-definition-p (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2636 "Return non-nil if DEFINITION was generated from advice information."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2637 (if (or (ad-lambda-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2638 (ad-macro-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2639 (ad-compiled-p definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2640 (let ((docstring (ad-docstring definition)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2641 (and (stringp docstring)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2642 (string-match
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2643 ad-advised-definition-docstring-regexp docstring)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2644
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2645 (defun ad-definition-type (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2646 "Return symbol that describes the type of DEFINITION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2647 (if (ad-macro-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2648 'macro
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2649 (if (ad-subr-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2650 (if (ad-special-form-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2651 'special-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2652 'subr)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2653 (if (or (ad-lambda-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2654 (ad-compiled-p definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2655 'function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2656 (if (ad-advice-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2657 'advice)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2658
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2659 (defun ad-has-proper-definition (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2660 "True if FUNCTION is a symbol with a proper definition.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2661 For that it has to be fbound with a non-autoload definition."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2662 (and (symbolp function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2663 (fboundp function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2664 (not (eq (car-safe (symbol-function function)) 'autoload))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2665
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2666 ;; The following two are necessary for the sake of packages such as
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2667 ;; ange-ftp which redefine functions via fcell indirection:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2668 (defun ad-real-definition (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2669 "Find FUNCTION's definition at the end of function cell indirection."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2670 (if (ad-has-proper-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2671 (let ((definition (symbol-function function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2672 (if (symbolp definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2673 (ad-real-definition definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2674 definition))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2675
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2676 (defun ad-real-orig-definition (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2677 "Find FUNCTION's real original definition starting from its `origname'."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2678 (if (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2679 (ad-real-definition (ad-get-advice-info-field function 'origname))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2680
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2681 (defun ad-is-compilable (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2682 "True if FUNCTION has an interpreted definition that can be compiled."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2683 (and (ad-has-proper-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2684 (or (ad-lambda-p (symbol-function function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2685 (ad-macro-p (symbol-function function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2686 (not (ad-compiled-p (symbol-function function)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2687
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2688 (defun ad-compile-function (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2689 "Byte-compiles FUNCTION (or macro) if it is not yet compiled."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2690 (interactive "aByte-compile function: ")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2691 (if (ad-is-compilable function)
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2692 ;; Need to turn off auto-activation
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2693 ;; because `byte-compile' uses `fset':
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2694 (ad-with-auto-activation-disabled
46196
73cafacdf14f (ad-compile-function): Disable cl-function warnings if cl is loaded.
Richard M. Stallman <rms@gnu.org>
parents: 45019
diff changeset
2695 (require 'bytecomp)
73cafacdf14f (ad-compile-function): Disable cl-function warnings if cl is loaded.
Richard M. Stallman <rms@gnu.org>
parents: 45019
diff changeset
2696 (let ((symbol (make-symbol "advice-compilation"))
73cafacdf14f (ad-compile-function): Disable cl-function warnings if cl is loaded.
Richard M. Stallman <rms@gnu.org>
parents: 45019
diff changeset
2697 (byte-compile-warnings
73cafacdf14f (ad-compile-function): Disable cl-function warnings if cl is loaded.
Richard M. Stallman <rms@gnu.org>
parents: 45019
diff changeset
2698 (if (listp byte-compile-warnings) byte-compile-warnings
73cafacdf14f (ad-compile-function): Disable cl-function warnings if cl is loaded.
Richard M. Stallman <rms@gnu.org>
parents: 45019
diff changeset
2699 byte-compile-warning-types)))
73cafacdf14f (ad-compile-function): Disable cl-function warnings if cl is loaded.
Richard M. Stallman <rms@gnu.org>
parents: 45019
diff changeset
2700 (if (featurep 'cl)
73cafacdf14f (ad-compile-function): Disable cl-function warnings if cl is loaded.
Richard M. Stallman <rms@gnu.org>
parents: 45019
diff changeset
2701 (setq byte-compile-warnings
73cafacdf14f (ad-compile-function): Disable cl-function warnings if cl is loaded.
Richard M. Stallman <rms@gnu.org>
parents: 45019
diff changeset
2702 (remq 'cl-functions byte-compile-warnings)))
41936
2fba35852455 (ad-compile-function):
Richard M. Stallman <rms@gnu.org>
parents: 41608
diff changeset
2703 (fset symbol (symbol-function function))
2fba35852455 (ad-compile-function):
Richard M. Stallman <rms@gnu.org>
parents: 41608
diff changeset
2704 (byte-compile symbol)
2fba35852455 (ad-compile-function):
Richard M. Stallman <rms@gnu.org>
parents: 41608
diff changeset
2705 (fset function (symbol-function symbol))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2706
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2707
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2708 ;; @@ Constructing advised definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2709 ;; ====================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2710 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2711 ;; Main design decisions about the form of advised definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2712 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2713 ;; A) How will original definitions be called?
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2714 ;; B) What will argument lists of advised functions look like?
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2715 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2716 ;; Ad A)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2717 ;; I chose to use function indirection for all four types of original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2718 ;; definitions (functions, macros, subrs and special forms), i.e., create
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2719 ;; a unique symbol `ad-Orig-<name>' which is fbound to the original
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2720 ;; definition and call it according to type and arguments. Functions and
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2721 ;; subrs that don't have any &rest arguments can be called directly in a
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2722 ;; `(ad-Orig-<name> ....)' form. If they have a &rest argument we have to
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2723 ;; use `apply'. Macros will be called with
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2724 ;; `(macroexpand '(ad-Orig-<name> ....))', and special forms also need a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2725 ;; form like that with `eval' instead of `macroexpand'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2726 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2727 ;; Ad B)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2728 ;; Use original arguments where possible and `(&rest ad-subr-args)'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2729 ;; otherwise, even though this seems to be more complicated and less
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2730 ;; uniform than a general `(&rest args)' approach. My reason to still
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2731 ;; do it that way is that in most cases my approach leads to the more
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2732 ;; efficient form for the advised function, and portability (e.g., to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2733 ;; make the same advice work regardless of whether something is a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2734 ;; function or a subr) can still be achieved with argument access macros.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2735
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2736
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2737 (defun ad-prognify (forms)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2738 (cond ((<= (length forms) 1)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2739 (car forms))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2740 (t (cons 'progn forms))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2741
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2742 ;; @@@ Accessing argument lists:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2743 ;; =============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2744
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2745 (defun ad-parse-arglist (arglist)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2746 "Parse ARGLIST into its required, optional and rest parameters.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2747 A three-element list is returned, where the 1st element is the list of
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2748 required arguments, the 2nd is the list of optional arguments, and the 3rd
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2749 is the name of an optional rest parameter (or nil)."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2750 (let* (required optional rest)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2751 (setq rest (car (cdr (memq '&rest arglist))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2752 (if rest (setq arglist (reverse (cdr (memq '&rest (reverse arglist))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2753 (setq optional (cdr (memq '&optional arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2754 (if optional
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2755 (setq required (reverse (cdr (memq '&optional (reverse arglist)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2756 (setq required arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2757 (list required optional rest)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2758
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2759 (defun ad-retrieve-args-form (arglist)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2760 "Generate a form which evaluates into names/values/types of ARGLIST.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2761 When the form gets evaluated within a function with that argument list
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2762 it will result in a list with one entry for each argument, where the
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2763 first element of each entry is the name of the argument, the second
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2764 element is its actual current value, and the third element is either
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2765 `required', `optional' or `rest' depending on the type of the argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2766 (let* ((parsed-arglist (ad-parse-arglist arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2767 (rest (nth 2 parsed-arglist)))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2768 `(list
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2769 ,@(mapcar (function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2770 (lambda (req)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2771 `(list ',req ,req 'required)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2772 (nth 0 parsed-arglist))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2773 ,@(mapcar (function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2774 (lambda (opt)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2775 `(list ',opt ,opt 'optional)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2776 (nth 1 parsed-arglist))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2777 ,@(if rest (list `(list ',rest ,rest 'rest))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2778
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2779 (defun ad-arg-binding-field (binding field)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2780 (cond ((eq field 'name) (car binding))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2781 ((eq field 'value) (car (cdr binding)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2782 ((eq field 'type) (car (cdr (cdr binding))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2783
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2784 (defun ad-list-access (position list)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2785 (cond ((= position 0) list)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2786 ((= position 1) (list 'cdr list))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2787 (t (list 'nthcdr position list))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2788
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2789 (defun ad-element-access (position list)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2790 (cond ((= position 0) (list 'car list))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2791 ((= position 1) `(car (cdr ,list)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2792 (t (list 'nth position list))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2793
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2794 (defun ad-access-argument (arglist index)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2795 "Tell how to access ARGLIST's actual argument at position INDEX.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2796 For a required/optional arg it simply returns it, if a rest argument has
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2797 to be accessed, it returns a list with the index and name."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2798 (let* ((parsed-arglist (ad-parse-arglist arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2799 (reqopt-args (append (nth 0 parsed-arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2800 (nth 1 parsed-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2801 (rest-arg (nth 2 parsed-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2802 (cond ((< index (length reqopt-args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2803 (nth index reqopt-args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2804 (rest-arg
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2805 (list (- index (length reqopt-args)) rest-arg)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2806
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2807 (defun ad-get-argument (arglist index)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2808 "Return form to access ARGLIST's actual argument at position INDEX."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2809 (let ((argument-access (ad-access-argument arglist index)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2810 (cond ((consp argument-access)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2811 (ad-element-access
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2812 (car argument-access) (car (cdr argument-access))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2813 (argument-access))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2814
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2815 (defun ad-set-argument (arglist index value-form)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2816 "Return form to set ARGLIST's actual arg at INDEX to VALUE-FORM."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2817 (let ((argument-access (ad-access-argument arglist index)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2818 (cond ((consp argument-access)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2819 ;; should this check whether there actually is something to set?
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2820 `(setcar ,(ad-list-access
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2821 (car argument-access) (car (cdr argument-access)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2822 ,value-form))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2823 (argument-access
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2824 `(setq ,argument-access ,value-form))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2825 (t (error "ad-set-argument: No argument at position %d of `%s'"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2826 index arglist)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2827
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2828 (defun ad-get-arguments (arglist index)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2829 "Return form to access all actual arguments starting at position INDEX."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2830 (let* ((parsed-arglist (ad-parse-arglist arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2831 (reqopt-args (append (nth 0 parsed-arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2832 (nth 1 parsed-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2833 (rest-arg (nth 2 parsed-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2834 args-form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2835 (if (< index (length reqopt-args))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2836 (setq args-form `(list ,@(nthcdr index reqopt-args))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2837 (if rest-arg
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2838 (if args-form
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2839 (setq args-form `(nconc ,args-form ,rest-arg))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2840 (setq args-form (ad-list-access (- index (length reqopt-args))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2841 rest-arg))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2842 args-form))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2843
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2844 (defun ad-set-arguments (arglist index values-form)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2845 "Make form to assign elements of VALUES-FORM as actual ARGLIST args.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2846 The assignment starts at position INDEX."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2847 (let ((values-index 0)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2848 argument-access set-forms)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2849 (while (setq argument-access (ad-access-argument arglist index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2850 (if (symbolp argument-access)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2851 (setq set-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2852 (cons (ad-set-argument
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2853 arglist index
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2854 (ad-element-access values-index 'ad-vAlUeS))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2855 set-forms))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2856 (setq set-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2857 (cons (if (= (car argument-access) 0)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2858 (list 'setq
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2859 (car (cdr argument-access))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2860 (ad-list-access values-index 'ad-vAlUeS))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2861 (list 'setcdr
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2862 (ad-list-access (1- (car argument-access))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2863 (car (cdr argument-access)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2864 (ad-list-access values-index 'ad-vAlUeS)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2865 set-forms))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2866 ;; terminate loop
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2867 (setq arglist nil))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2868 (setq index (1+ index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2869 (setq values-index (1+ values-index)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2870 (if (null set-forms)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2871 (error "ad-set-arguments: No argument at position %d of `%s'"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2872 index arglist)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2873 (if (= (length set-forms) 1)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2874 ;; For exactly one set-form we can use values-form directly,...
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2875 (ad-substitute-tree
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2876 (function (lambda (form) (eq form 'ad-vAlUeS)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2877 (function (lambda (form) values-form))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2878 (car set-forms))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2879 ;; ...if we have more we have to bind it to a variable:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2880 `(let ((ad-vAlUeS ,values-form))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2881 ,@(reverse set-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2882 ;; work around the old backquote bug:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2883 ,'ad-vAlUeS)))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2884
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2885 (defun ad-insert-argument-access-forms (definition arglist)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2886 "Expands arg-access text macros in DEFINITION according to ARGLIST."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2887 (ad-substitute-tree
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2888 (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2889 (lambda (form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2890 (or (eq form 'ad-arg-bindings)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2891 (and (memq (car-safe form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2892 '(ad-get-arg ad-get-args ad-set-arg ad-set-args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2893 (integerp (car-safe (cdr form)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2894 (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2895 (lambda (form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2896 (if (eq form 'ad-arg-bindings)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2897 (ad-retrieve-args-form arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2898 (let ((accessor (car form))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2899 (index (car (cdr form)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2900 (val (car (cdr (ad-insert-argument-access-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2901 (cdr form) arglist)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2902 (cond ((eq accessor 'ad-get-arg)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2903 (ad-get-argument arglist index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2904 ((eq accessor 'ad-set-arg)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2905 (ad-set-argument arglist index val))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2906 ((eq accessor 'ad-get-args)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2907 (ad-get-arguments arglist index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2908 ((eq accessor 'ad-set-args)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2909 (ad-set-arguments arglist index val)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2910 definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2911
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2912 ;; @@@ Mapping argument lists:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2913 ;; ===========================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2914 ;; Here is the problem:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2915 ;; Suppose function foo was called with (foo 1 2 3 4 5), and foo has the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2916 ;; argument list (x y &rest z), and we want to call the function bar which
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2917 ;; has argument list (a &rest b) with a combination of x, y and z so that
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2918 ;; the effect is just as if we had called (bar 1 2 3 4 5) directly.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2919 ;; The mapping should work for any two argument lists.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2920
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2921 (defun ad-map-arglists (source-arglist target-arglist)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2922 "Make `funcall/apply' form to map SOURCE-ARGLIST to TARGET-ARGLIST.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2923 The arguments supplied to TARGET-ARGLIST will be taken from SOURCE-ARGLIST just
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2924 as if they had been supplied to a function with TARGET-ARGLIST directly.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2925 Excess source arguments will be neglected, missing source arguments will be
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2926 supplied as nil. Returns a `funcall' or `apply' form with the second element
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2927 being `function' which has to be replaced by an actual function argument.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2928 Example: `(ad-map-arglists '(a &rest args) '(w x y z))' will return
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2929 `(funcall function a (car args) (car (cdr args)) (nth 2 args))'."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2930 (let* ((parsed-source-arglist (ad-parse-arglist source-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2931 (source-reqopt-args (append (nth 0 parsed-source-arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2932 (nth 1 parsed-source-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2933 (source-rest-arg (nth 2 parsed-source-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2934 (parsed-target-arglist (ad-parse-arglist target-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2935 (target-reqopt-args (append (nth 0 parsed-target-arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2936 (nth 1 parsed-target-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2937 (target-rest-arg (nth 2 parsed-target-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2938 (need-apply (and source-rest-arg target-rest-arg))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2939 (target-arg-index -1))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2940 ;; This produces ``error-proof'' target function calls with the exception
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2941 ;; of a case like (&rest a) mapped onto (x &rest y) where the actual args
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2942 ;; supplied to A might not be enough to supply the required target arg X
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2943 (append (list (if need-apply 'apply 'funcall) 'function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2944 (cond (need-apply
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2945 ;; `apply' can take care of that directly:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2946 (append source-reqopt-args (list source-rest-arg)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2947 (t (mapcar (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2948 (lambda (arg)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2949 (setq target-arg-index (1+ target-arg-index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2950 (ad-get-argument
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2951 source-arglist target-arg-index)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2952 (append target-reqopt-args
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2953 (and target-rest-arg
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2954 ;; If we have a rest arg gobble up
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2955 ;; remaining source args:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2956 (nthcdr (length target-reqopt-args)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2957 source-reqopt-args)))))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2958
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2959 (defun ad-make-mapped-call (source-arglist target-arglist target-function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2960 "Make form to call TARGET-FUNCTION with args from SOURCE-ARGLIST."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2961 (let* ((mapped-form (ad-map-arglists source-arglist target-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2962 (if (eq (car mapped-form) 'funcall)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2963 (cons target-function (cdr (cdr mapped-form)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2964 (prog1 mapped-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2965 (setcar (cdr mapped-form) (list 'quote target-function))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2966
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2967 ;; @@@ Making an advised documentation string:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2968 ;; ===========================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2969 ;; New policy: The documentation string for an advised function will be built
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2970 ;; at the time the advised `documentation' function is called. This has the
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2971 ;; following advantages:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2972 ;; 1) command-key substitutions will automatically be correct
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2973 ;; 2) No wasted string space due to big advised docstrings in caches or
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2974 ;; compiled files that contain preactivations
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2975 ;; The overall overhead for this should be negligible because people normally
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2976 ;; don't lookup documentation for the same function over and over again.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2977
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2978 (defun ad-make-single-advice-docstring (advice class &optional style)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2979 (let ((advice-docstring (ad-docstring (ad-advice-definition advice))))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2980 (cond ((eq style 'plain)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2981 advice-docstring)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2982 ((eq style 'freeze)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2983 (format "Permanent %s-advice `%s':%s%s"
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2984 class (ad-advice-name advice)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2985 (if advice-docstring "\n" "")
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2986 (or advice-docstring "")))
25208
76f5f50e7742 (ad-make-single-advice-docstring): Treat case with no doctring specially.
Dave Love <fx@gnu.org>
parents: 24875
diff changeset
2987 (t (if advice-docstring
76f5f50e7742 (ad-make-single-advice-docstring): Treat case with no doctring specially.
Dave Love <fx@gnu.org>
parents: 24875
diff changeset
2988 (format "%s-advice `%s':\n%s"
76f5f50e7742 (ad-make-single-advice-docstring): Treat case with no doctring specially.
Dave Love <fx@gnu.org>
parents: 24875
diff changeset
2989 (capitalize (symbol-name class))
76f5f50e7742 (ad-make-single-advice-docstring): Treat case with no doctring specially.
Dave Love <fx@gnu.org>
parents: 24875
diff changeset
2990 (ad-advice-name advice)
76f5f50e7742 (ad-make-single-advice-docstring): Treat case with no doctring specially.
Dave Love <fx@gnu.org>
parents: 24875
diff changeset
2991 advice-docstring)
76f5f50e7742 (ad-make-single-advice-docstring): Treat case with no doctring specially.
Dave Love <fx@gnu.org>
parents: 24875
diff changeset
2992 (format "%s-advice `%s'."
76f5f50e7742 (ad-make-single-advice-docstring): Treat case with no doctring specially.
Dave Love <fx@gnu.org>
parents: 24875
diff changeset
2993 (capitalize (symbol-name class))
76f5f50e7742 (ad-make-single-advice-docstring): Treat case with no doctring specially.
Dave Love <fx@gnu.org>
parents: 24875
diff changeset
2994 (ad-advice-name advice)))))))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2995
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2996 (require 'help-fns) ;For help-split-fundoc and help-add-fundoc-usage.
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2997
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2998 (defun ad-make-advised-docstring (function &optional style)
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2999 "Construct a documentation string for the advised FUNCTION.
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3000 It concatenates the original documentation with the documentation
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3001 strings of the individual pieces of advice which will be formatted
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3002 according to STYLE. STYLE can be `plain' or `freeze', everything else
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3003 will be interpreted as `default'. The order of the advice documentation
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3004 strings corresponds to before/around/after and the individual ordering
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3005 in any of these classes."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3006 (let* ((origdef (ad-real-orig-definition function))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3007 (origtype (symbol-name (ad-definition-type origdef)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3008 (origdoc
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3009 ;; Retrieve raw doc, key substitution will be taken care of later:
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3010 (ad-real-documentation origdef t))
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3011 (usage (help-split-fundoc origdoc function))
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3012 paragraphs advice-docstring ad-usage)
50842
b64d29a02737 (ad-make-advised-docstring): Adjust usage for new help-add-fundoc-usage.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 50800
diff changeset
3013 (setq usage (if (null usage) t (setq origdoc (cdr usage)) (car usage)))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3014 (if origdoc (setq paragraphs (list origdoc)))
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3015 (unless (eq style 'plain)
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3016 (push (concat "This " origtype " is advised.") paragraphs))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3017 (ad-dolist (class ad-advice-classes)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3018 (ad-dolist (advice (ad-get-enabled-advices function class))
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3019 (setq advice-docstring
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3020 (ad-make-single-advice-docstring advice class style))
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3021 (if advice-docstring
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3022 (push advice-docstring paragraphs))))
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3023 (setq origdoc (if paragraphs
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3024 ;; separate paragraphs with blank lines:
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3025 (mapconcat 'identity (nreverse paragraphs) "\n\n")))
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3026 (help-add-fundoc-usage origdoc usage)))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3027
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3028 (defun ad-make-plain-docstring (function)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3029 (ad-make-advised-docstring function 'plain))
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3030 (defun ad-make-freeze-docstring (function)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3031 (ad-make-advised-docstring function 'freeze))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3032
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3033 ;; @@@ Accessing overriding arglists and interactive forms:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3034 ;; ========================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3035
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3036 (defun ad-advised-arglist (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3037 "Find first defined arglist in FUNCTION's redefining advices."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3038 (ad-dolist (advice (append (ad-get-enabled-advices function 'before)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3039 (ad-get-enabled-advices function 'around)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3040 (ad-get-enabled-advices function 'after)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3041 (let ((arglist (ad-arglist (ad-advice-definition advice))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3042 (if arglist
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3043 ;; We found the first one, use it:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3044 (ad-do-return arglist)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3045
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3046 (defun ad-advised-interactive-form (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3047 "Find first interactive form in FUNCTION's redefining advices."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3048 (ad-dolist (advice (append (ad-get-enabled-advices function 'before)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3049 (ad-get-enabled-advices function 'around)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3050 (ad-get-enabled-advices function 'after)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3051 (let ((interactive-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3052 (ad-interactive-form (ad-advice-definition advice))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3053 (if interactive-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3054 ;; We found the first one, use it:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3055 (ad-do-return interactive-form)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3056
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3057 ;; @@@ Putting it all together:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3058 ;; ============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3059
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3060 (defun ad-make-advised-definition (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3061 "Generate an advised definition of FUNCTION from its advice info."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3062 (if (and (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3063 (ad-has-redefining-advice function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3064 (let* ((origdef (ad-real-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3065 (origname (ad-get-advice-info-field function 'origname))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3066 (orig-interactive-p (ad-interactive-p origdef))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3067 (orig-subr-p (ad-subr-p origdef))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3068 (orig-special-form-p (ad-special-form-p origdef))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3069 (orig-macro-p (ad-macro-p origdef))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3070 ;; Construct the individual pieces that we need for assembly:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3071 (orig-arglist (ad-arglist origdef function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3072 (advised-arglist (or (ad-advised-arglist function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3073 orig-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3074 (advised-interactive-form (ad-advised-interactive-form function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3075 (interactive-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3076 (cond (orig-macro-p nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3077 (advised-interactive-form)
38336
d5f3a4fa3bc5 (ad-make-advised-definition): If the
Gerd Moellmann <gerd@gnu.org>
parents: 37304
diff changeset
3078 ((ad-interactive-form origdef)
d5f3a4fa3bc5 (ad-make-advised-definition): If the
Gerd Moellmann <gerd@gnu.org>
parents: 37304
diff changeset
3079 (if (and (symbolp function) (get function 'elp-info))
d5f3a4fa3bc5 (ad-make-advised-definition): If the
Gerd Moellmann <gerd@gnu.org>
parents: 37304
diff changeset
3080 (interactive-form (aref (get function 'elp-info) 2))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3081 (ad-interactive-form origdef)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3082 ;; Otherwise we must have a subr: make it interactive if
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3083 ;; we have to and initialize required arguments in case
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3084 ;; it is called interactively:
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3085 (orig-interactive-p
38336
d5f3a4fa3bc5 (ad-make-advised-definition): If the
Gerd Moellmann <gerd@gnu.org>
parents: 37304
diff changeset
3086 (interactive-form origdef))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3087 (orig-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3088 (cond ((or orig-special-form-p orig-macro-p)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3089 ;; Special forms and macros will be advised into macros.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3090 ;; The trick is to construct an expansion for the advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3091 ;; macro that does the correct thing when it gets eval'ed.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3092 ;; For macros we'll just use the expansion of the original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3093 ;; macro and return that. This way compiled advised macros
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3094 ;; will be expanded into something useful. Note that after
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3095 ;; advices have full control over whether they want to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3096 ;; evaluate the expansion (the value of `ad-return-value')
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3097 ;; at macro expansion time or not. For special forms there
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3098 ;; is no solution that interacts reasonably with the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3099 ;; compiler, hence we just evaluate the original at macro
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3100 ;; expansion time and return the result. The moral of that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3101 ;; is that one should always deactivate advised special
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3102 ;; forms before one byte-compiles a file.
37304
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3103 `(,(if orig-macro-p 'macroexpand 'eval)
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3104 (cons ',origname
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3105 ,(ad-get-arguments advised-arglist 0))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3106 ((and orig-subr-p
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3107 orig-interactive-p
37304
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3108 (not interactive-form)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3109 (not advised-interactive-form))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3110 ;; Check whether we were called interactively
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3111 ;; in order to do proper prompting:
57879
7b2c608f3b0b (ad-make-advised-definition): Use called-interactively-p.
Richard M. Stallman <rms@gnu.org>
parents: 54509
diff changeset
3112 `(if (called-interactively-p)
37304
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3113 (call-interactively ',origname)
66398
df04170ba46b (ad-make-advised-definition): Fix arg-order.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 65680
diff changeset
3114 ,(ad-make-mapped-call advised-arglist
df04170ba46b (ad-make-advised-definition): Fix arg-order.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 65680
diff changeset
3115 orig-arglist
37304
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3116 origname)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3117 ;; And now for normal functions and non-interactive subrs
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3118 ;; (or subrs whose interactive behavior was advised):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3119 (t (ad-make-mapped-call
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3120 advised-arglist orig-arglist origname)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3121
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3122 ;; Finally, build the sucker:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3123 (ad-assemble-advised-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3124 (cond (orig-macro-p 'macro)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3125 (orig-special-form-p 'special-form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3126 (t 'function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3127 advised-arglist
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3128 (ad-make-advised-definition-docstring function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3129 interactive-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3130 orig-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3131 (ad-get-enabled-advices function 'before)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3132 (ad-get-enabled-advices function 'around)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3133 (ad-get-enabled-advices function 'after)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3134
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3135 (defun ad-assemble-advised-definition
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3136 (type args docstring interactive orig &optional befores arounds afters)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3137
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3138 "Assembles an original and its advices into an advised function.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3139 It constructs a function or macro definition according to TYPE which has to
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3140 be either `macro', `function' or `special-form'. ARGS is the argument list
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3141 that has to be used, DOCSTRING if non-nil defines the documentation of the
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3142 definition, INTERACTIVE if non-nil is the interactive form to be used,
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3143 ORIG is a form that calls the body of the original unadvised function,
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3144 and BEFORES, AROUNDS and AFTERS are the lists of advices with which ORIG
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3145 should be modified. The assembled function will be returned."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3146
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3147 (let (before-forms around-form around-form-protected after-forms definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3148 (ad-dolist (advice befores)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3149 (cond ((and (ad-advice-protected advice)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3150 before-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3151 (setq before-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3152 `((unwind-protect
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3153 ,(ad-prognify before-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3154 ,@(ad-body-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3155 (ad-advice-definition advice))))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3156 (t (setq before-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3157 (append before-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3158 (ad-body-forms (ad-advice-definition advice)))))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3159
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3160 (setq around-form `(setq ad-return-value ,orig))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3161 (ad-dolist (advice (reverse arounds))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3162 ;; If any of the around advices is protected then we
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3163 ;; protect the complete around advice onion:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3164 (if (ad-advice-protected advice)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3165 (setq around-form-protected t))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3166 (setq around-form
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3167 (ad-substitute-tree
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3168 (function (lambda (form) (eq form 'ad-do-it)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3169 (function (lambda (form) around-form))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3170 (ad-prognify (ad-body-forms (ad-advice-definition advice))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3171
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3172 (setq after-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3173 (if (and around-form-protected before-forms)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3174 `((unwind-protect
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3175 ,(ad-prognify before-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3176 ,around-form))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3177 (append before-forms (list around-form))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3178 (ad-dolist (advice afters)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3179 (cond ((and (ad-advice-protected advice)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3180 after-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3181 (setq after-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3182 `((unwind-protect
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3183 ,(ad-prognify after-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3184 ,@(ad-body-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3185 (ad-advice-definition advice))))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3186 (t (setq after-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3187 (append after-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3188 (ad-body-forms (ad-advice-definition advice)))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3189
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3190 (setq definition
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3191 `(,@(if (memq type '(macro special-form)) '(macro))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3192 lambda
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3193 ,args
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3194 ,@(if docstring (list docstring))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3195 ,@(if interactive (list interactive))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3196 (let (ad-return-value)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3197 ,@after-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3198 ,(if (eq type 'special-form)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3199 '(list 'quote ad-return-value)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3200 'ad-return-value))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3201
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3202 (ad-insert-argument-access-forms definition args)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3203
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3204 ;; This is needed for activation/deactivation hooks:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3205 (defun ad-make-hook-form (function hook-name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3206 "Make hook-form from FUNCTION's advice bodies in class HOOK-NAME."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3207 (let ((hook-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3208 (mapcar (function (lambda (advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3209 (ad-body-forms (ad-advice-definition advice))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3210 (ad-get-enabled-advices function hook-name))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3211 (if hook-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3212 (ad-prognify (apply 'append hook-forms)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3213
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3214
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3215 ;; @@ Caching:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3216 ;; ===========
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3217 ;; Generating an advised definition of a function is moderately expensive,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3218 ;; hence, it makes sense to cache it so we can reuse it in appropriate
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3219 ;; circumstances. Of course, it only makes sense to reuse a cached
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3220 ;; definition if the current advice and function definition state is the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3221 ;; same as it was at the time when the cached definition was generated.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3222 ;; For that purpose we associate every cache with an id so we can verify
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3223 ;; if it is still valid at a certain point in time. This id mechanism
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3224 ;; makes it possible to preactivate advised functions, write the compiled
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3225 ;; advised definitions to a file and reuse them during the actual
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3226 ;; activation without having to risk that the resulting definition will be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3227 ;; incorrect, well, almost.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3228 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3229 ;; A cache id is a list with six elements:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3230 ;; 1) the list of names of enabled before advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3231 ;; 2) the list of names of enabled around advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3232 ;; 3) the list of names of enabled after advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3233 ;; 4) the type of the original function (macro, subr, etc.)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3234 ;; 5) the arglist of the original definition (or t if it was equal to the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3235 ;; arglist of the cached definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3236 ;; 6) t if the interactive form of the original definition was equal to the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3237 ;; interactive form of the cached definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3238 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3239 ;; Here's how a cache can get invalidated or be incorrect:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3240 ;; A) a piece of advice used in the cache gets redefined
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3241 ;; B) the current list of enabled advices is different from the ones used
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3242 ;; for the cache
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3243 ;; C) the type of the original function changed, e.g., a function became a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3244 ;; macro, or a subr became a function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3245 ;; D) the arglist of the original function changed
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3246 ;; E) the interactive form of the original function changed
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3247 ;; F) a piece of advice used in the cache got redefined before the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3248 ;; defadvice with the cached definition got loaded: This is a PROBLEM!
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3249 ;;
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3250 ;; Cases A and B are the normal ones. A is taken care of by `ad-add-advice'
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3251 ;; which clears the cache in such a case, B is easily checked during
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3252 ;; verification at activation time.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3253 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3254 ;; Cases C, D and E have to be considered if one is slightly paranoid, i.e.,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3255 ;; if one considers the case that the original function could be different
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3256 ;; from the one available at caching time (e.g., for forward advice of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3257 ;; functions that get redefined by some packages - such as `eval-region' gets
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3258 ;; redefined by edebug). All these cases can be easily checked during
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3259 ;; verification. Element 4 of the id lets one check case C, element 5 takes
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3260 ;; care of case D (using t in the equality case saves some space, because the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3261 ;; arglist can be recovered at validation time from the cached definition),
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3262 ;; and element 6 takes care of case E which is only a problem if the original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3263 ;; was actually a function whose interactive form was not overridden by a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3264 ;; piece of advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3265 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3266 ;; Case F is the only one which will lead to an incorrect advised function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3267 ;; There is no way to avoid this without storing the complete advice definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3268 ;; in the cache-id which is not feasible.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3269 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3270 ;; The cache-id of a typical advised function with one piece of advice and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3271 ;; no arglist redefinition takes 7 conses which is a small price to pay for
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3272 ;; the added efficiency. The validation itself is also pretty cheap, certainly
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3273 ;; a lot cheaper than reconstructing an advised definition.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3274
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3275 (defmacro ad-get-cache-definition (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3276 `(car (ad-get-advice-info-field ,function 'cache)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3277
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3278 (defmacro ad-get-cache-id (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3279 `(cdr (ad-get-advice-info-field ,function 'cache)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3280
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3281 (defmacro ad-set-cache (function definition id)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3282 `(ad-set-advice-info-field
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3283 ,function 'cache (cons ,definition ,id)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3284
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3285 (defun ad-clear-cache (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3286 "Clears a previously cached advised definition of FUNCTION.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3287 Clear the cache if you want to force `ad-activate' to construct a new
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3288 advised definition from scratch."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3289 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3290 (list (ad-read-advised-function "Clear cached definition of")))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3291 (ad-set-advice-info-field function 'cache nil))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3292
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3293 (defun ad-make-cache-id (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3294 "Generate an identifying image of the current advices of FUNCTION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3295 (let ((original-definition (ad-real-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3296 (cached-definition (ad-get-cache-definition function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3297 (list (mapcar (function (lambda (advice) (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3298 (ad-get-enabled-advices function 'before))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3299 (mapcar (function (lambda (advice) (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3300 (ad-get-enabled-advices function 'around))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3301 (mapcar (function (lambda (advice) (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3302 (ad-get-enabled-advices function 'after))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3303 (ad-definition-type original-definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3304 (if (equal (ad-arglist original-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3305 (ad-arglist cached-definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3306 t
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3307 (ad-arglist original-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3308 (if (eq (ad-definition-type original-definition) 'function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3309 (equal (ad-interactive-form original-definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3310 (ad-interactive-form cached-definition))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3311
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3312 (defun ad-get-cache-class-id (function class)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3313 "Return the part of FUNCTION's cache id that identifies CLASS."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3314 (let ((cache-id (ad-get-cache-id function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3315 (if (eq class 'before)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3316 (car cache-id)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3317 (if (eq class 'around)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3318 (nth 1 cache-id)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3319 (nth 2 cache-id)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3320
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3321 (defun ad-verify-cache-class-id (cache-class-id advices)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3322 (ad-dolist (advice advices (null cache-class-id))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3323 (if (ad-advice-enabled advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3324 (if (eq (car cache-class-id) (ad-advice-name advice))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3325 (setq cache-class-id (cdr cache-class-id))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3326 (ad-do-return nil)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3327
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3328 ;; There should be a way to monitor if and why a cache verification failed
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3329 ;; in order to determine whether a certain preactivation could be used or
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3330 ;; not. Right now the only way to find out is to trace
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3331 ;; `ad-cache-id-verification-code'. The code it returns indicates where the
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3332 ;; verification failed. Tracing `ad-verify-cache-class-id' might provide
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3333 ;; some additional useful information.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3334
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3335 (defun ad-cache-id-verification-code (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3336 (let ((cache-id (ad-get-cache-id function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3337 (code 'before-advice-mismatch))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3338 (and (ad-verify-cache-class-id
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3339 (car cache-id) (ad-get-advice-info-field function 'before))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3340 (setq code 'around-advice-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3341 (ad-verify-cache-class-id
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3342 (nth 1 cache-id) (ad-get-advice-info-field function 'around))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3343 (setq code 'after-advice-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3344 (ad-verify-cache-class-id
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3345 (nth 2 cache-id) (ad-get-advice-info-field function 'after))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3346 (setq code 'definition-type-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3347 (let ((original-definition (ad-real-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3348 (cached-definition (ad-get-cache-definition function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3349 (and (eq (nth 3 cache-id) (ad-definition-type original-definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3350 (setq code 'arglist-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3351 (equal (if (eq (nth 4 cache-id) t)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3352 (ad-arglist original-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3353 (nth 4 cache-id) )
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3354 (ad-arglist cached-definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3355 (setq code 'interactive-form-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3356 (or (null (nth 5 cache-id))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3357 (equal (ad-interactive-form original-definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3358 (ad-interactive-form cached-definition)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3359 (setq code 'verified))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3360 code))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3361
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3362 (defun ad-verify-cache-id (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3363 "True if FUNCTION's cache-id is compatible with its current advices."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3364 (eq (ad-cache-id-verification-code function) 'verified))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3365
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3366
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3367 ;; @@ Preactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3368 ;; =================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3369 ;; Preactivation can be used to generate compiled advised definitions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3370 ;; at compile time without having to give up the dynamic runtime flexibility
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3371 ;; of the advice mechanism. Preactivation is a special feature of `defadvice',
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3372 ;; it involves the following steps:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3373 ;; - remembering the function's current state (definition and advice-info)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3374 ;; - advising it with the defined piece of advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3375 ;; - clearing its cache
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3376 ;; - generating an interpreted advised definition by activating it, this will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3377 ;; make use of all its current active advice and its current definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3378 ;; - saving the so generated cached definition and id
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3379 ;; - resetting the function's advice and definition state to what it was
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3380 ;; before the preactivation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3381 ;; - Returning the saved definition and its id to be used in the expansion of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3382 ;; `defadvice' to assign it as an initial cache, hence it will be compiled
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3383 ;; at time the `defadvice' gets compiled.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3384 ;; Naturally, for preactivation to be effective it has to be applied/compiled
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3385 ;; at the right time, i.e., when the current state of advices and function
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3386 ;; definition exactly reflects the state at activation time. Should that not
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3387 ;; be the case, the precompiled definition will just be discarded and a new
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3388 ;; advised definition will be generated.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3389
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3390 (defun ad-preactivate-advice (function advice class position)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3391 "Preactivate FUNCTION and returns the constructed cache."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3392 (let* ((function-defined-p (fboundp function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3393 (old-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3394 (if function-defined-p
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3395 (symbol-function function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3396 (old-advice-info (ad-copy-advice-info function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3397 (ad-advised-functions ad-advised-functions))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3398 (unwind-protect
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3399 (progn
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3400 (ad-add-advice function advice class position)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3401 (ad-enable-advice function class (ad-advice-name advice))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3402 (ad-clear-cache function)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3403 (ad-activate function -1)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3404 (if (and (ad-is-active function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3405 (ad-get-cache-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3406 (list (ad-get-cache-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3407 (ad-get-cache-id function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3408 (ad-set-advice-info function old-advice-info)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3409 ;; Don't `fset' function to nil if it was previously unbound:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3410 (if function-defined-p
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3411 (ad-safe-fset function old-definition)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3412 (fmakunbound function)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3413
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3414
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3415 ;; @@ Freezing:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3416 ;; ============
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3417 ;; Freezing transforms a `defadvice' into a redefining `defun/defmacro'
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3418 ;; for the advised function without keeping any advice information. This
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3419 ;; feature was jwz's idea: It generates a dumpable function definition
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3420 ;; whose documentation can be written to the DOC file, and the generated
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3421 ;; code does not need any Advice runtime support. Of course, frozen advices
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3422 ;; cannot be undone.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3423
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3424 ;; Freezing only considers the advice of the particular `defadvice', other
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3425 ;; already existing advices for the same function will be ignored. To ensure
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3426 ;; proper interaction when an already advised function gets redefined with
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3427 ;; a frozen advice, frozen advices always use the actual original definition
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3428 ;; of the function, i.e., they are always at the core of the onion. E.g., if
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3429 ;; an already advised function gets redefined with a frozen advice and then
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3430 ;; unadvised, the frozen advice remains as the new definition of the function.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3431
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3432 ;; While multiple freeze advices for a single function or freeze-advising
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3433 ;; of an already advised function are possible, they are better avoided,
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3434 ;; because definition/compile/load ordering is relevant, and it becomes
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3435 ;; incomprehensible pretty quickly.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3436
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3437 (defun ad-make-freeze-definition (function advice class position)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3438 (if (not (ad-has-proper-definition function))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3439 (error
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3440 "ad-make-freeze-definition: `%s' is not yet defined"
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3441 function))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3442 (let* ((name (ad-advice-name advice))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3443 ;; With a unique origname we can have multiple freeze advices
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3444 ;; for the same function, each overloading the previous one:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3445 (unique-origname
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3446 (intern (format "%s-%s-%s" (ad-make-origname function) class name)))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3447 (orig-definition
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3448 ;; If FUNCTION is already advised, we'll use its current origdef
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3449 ;; as the original definition of the frozen advice:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3450 (or (ad-get-orig-definition function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3451 (symbol-function function)))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3452 (old-advice-info
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3453 (if (ad-is-advised function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3454 (ad-copy-advice-info function)))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3455 (real-docstring-fn
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3456 (symbol-function 'ad-make-advised-definition-docstring))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3457 (real-origname-fn
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3458 (symbol-function 'ad-make-origname))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3459 (frozen-definition
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3460 (unwind-protect
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3461 (progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3462 ;; Make sure we construct a proper docstring:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3463 (ad-safe-fset 'ad-make-advised-definition-docstring
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3464 'ad-make-freeze-docstring)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3465 ;; Make sure `unique-origname' is used as the origname:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3466 (ad-safe-fset 'ad-make-origname (lambda (x) unique-origname))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3467 ;; No we reset all current advice information to nil and
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3468 ;; generate an advised definition that's solely determined
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3469 ;; by ADVICE and the current origdef of FUNCTION:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3470 (ad-set-advice-info function nil)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3471 (ad-add-advice function advice class position)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3472 ;; The following will provide proper real docstrings as
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3473 ;; well as a definition that will make the compiler happy:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3474 (ad-set-orig-definition function orig-definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3475 (ad-make-advised-definition function))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3476 ;; Restore the old advice state:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3477 (ad-set-advice-info function old-advice-info)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3478 ;; Restore functions:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3479 (ad-safe-fset
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3480 'ad-make-advised-definition-docstring real-docstring-fn)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3481 (ad-safe-fset 'ad-make-origname real-origname-fn))))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3482 (if frozen-definition
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3483 (let* ((macro-p (ad-macro-p frozen-definition))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3484 (body (cdr (if macro-p
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3485 (ad-lambdafy frozen-definition)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3486 frozen-definition))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3487 `(progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3488 (if (not (fboundp ',unique-origname))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3489 (fset ',unique-origname
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3490 ;; avoid infinite recursion in case the function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3491 ;; we want to freeze is already advised:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3492 (or (ad-get-orig-definition ',function)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3493 (symbol-function ',function))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3494 (,(if macro-p 'defmacro 'defun)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3495 ,function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3496 ,@body))))))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3497
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3498
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3499 ;; @@ Activation and definition handling:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3500 ;; ======================================
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3501
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3502 (defun ad-should-compile (function compile)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3503 "Return non-nil if the advised FUNCTION should be compiled.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3504 If COMPILE is non-nil and not a negative number then it returns t.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3505 If COMPILE is a negative number then it returns nil.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3506 If COMPILE is nil then the result depends on the value of
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3507 `ad-default-compilation-action' (which see)."
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3508 (if (integerp compile)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3509 (>= compile 0)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3510 (if compile
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3511 compile
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3512 (cond ((eq ad-default-compilation-action 'never)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3513 nil)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3514 ((eq ad-default-compilation-action 'always)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3515 t)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3516 ((eq ad-default-compilation-action 'like-original)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3517 (or (ad-subr-p (ad-get-orig-definition function))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3518 (ad-compiled-p (ad-get-orig-definition function))))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3519 ;; everything else means `maybe':
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3520 (t (featurep 'byte-compile))))))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3521
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3522 (defun ad-activate-advised-definition (function compile)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3523 "Redefine FUNCTION with its advised definition from cache or scratch.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3524 The resulting FUNCTION will be compiled if `ad-should-compile' returns t.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3525 The current definition and its cache-id will be put into the cache."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3526 (let ((verified-cached-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3527 (if (ad-verify-cache-id function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3528 (ad-get-cache-definition function))))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3529 (ad-safe-fset function
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3530 (or verified-cached-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3531 (ad-make-advised-definition function)))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3532 (if (ad-should-compile function compile)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3533 (ad-compile-function function))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3534 (if verified-cached-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3535 (if (not (eq verified-cached-definition (symbol-function function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3536 ;; we must have compiled, cache the compiled definition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3537 (ad-set-cache
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3538 function (symbol-function function) (ad-get-cache-id function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3539 ;; We created a new advised definition, cache it with a proper id:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3540 (ad-clear-cache function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3541 ;; ad-make-cache-id needs the new cached definition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3542 (ad-set-cache function (symbol-function function) nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3543 (ad-set-cache
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3544 function (symbol-function function) (ad-make-cache-id function)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3545
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3546 (defun ad-handle-definition (function)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3547 "Handle re/definition of an advised FUNCTION during de/activation.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3548 If FUNCTION does not have an original definition associated with it and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3549 the current definition is usable, then it will be stored as FUNCTION's
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3550 original definition. If no current definition is available (even in the
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3551 case of undefinition) nothing will be done. In the case of redefinition
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3552 the action taken depends on the value of `ad-redefinition-action' (which
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3553 see). Redefinition occurs when FUNCTION already has an original definition
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3554 associated with it but got redefined with a new definition and then
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3555 de/activated. If you do not like the current redefinition action change
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3556 the value of `ad-redefinition-action' and de/activate again."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3557 (let ((original-definition (ad-get-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3558 (current-definition (if (ad-real-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3559 (symbol-function function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3560 (if original-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3561 (if current-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3562 (if (and (not (eq current-definition original-definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3563 ;; Redefinition with an advised definition from a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3564 ;; different function won't count as such:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3565 (not (ad-advised-definition-p current-definition)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3566 ;; we have a redefinition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3567 (if (not (memq ad-redefinition-action '(accept discard warn)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3568 (error "ad-handle-definition (see its doc): `%s' %s"
22061
eed26995bfad (ad-handle-definition, defadvice): Fix error messages.
Richard M. Stallman <rms@gnu.org>
parents: 21365
diff changeset
3569 function "invalidly redefined")
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3570 (if (eq ad-redefinition-action 'discard)
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3571 (ad-safe-fset function original-definition)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3572 (ad-set-orig-definition function current-definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3573 (if (eq ad-redefinition-action 'warn)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3574 (message "ad-handle-definition: `%s' got redefined"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3575 function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3576 ;; either advised def or correct original is in place:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3577 nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3578 ;; we have an undefinition, ignore it:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3579 nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3580 (if current-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3581 ;; we have a first definition, save it as original:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3582 (ad-set-orig-definition function current-definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3583 ;; we don't have anything noteworthy:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3584 nil))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3585
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3586
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3587 ;; @@ The top-level advice interface:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3588 ;; ==================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3589
70899
b920ab84fba8 (ad-enable-advice, ad-activate, ad-disable-advice): Add autoloads.
Richard M. Stallman <rms@gnu.org>
parents: 68648
diff changeset
3590 ;;;###autoload
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3591 (defun ad-activate (function &optional compile)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3592 "Activate all the advice information of an advised FUNCTION.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3593 If FUNCTION has a proper original definition then an advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3594 definition will be generated from FUNCTION's advice info and the
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3595 definition of FUNCTION will be replaced with it. If a previously
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3596 cached advised definition was available, it will be used.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3597 The optional COMPILE argument determines whether the resulting function
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3598 or a compilable cached definition will be compiled. If it is negative
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3599 no compilation will be performed, if it is positive or otherwise non-nil
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3600 the resulting function will be compiled, if it is nil the behavior depends
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3601 on the value of `ad-default-compilation-action' (which see).
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3602 Activation of an advised function that has an advice info but no actual
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3603 pieces of advice is equivalent to a call to `ad-unadvise'. Activation of
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3604 an advised function that has actual pieces of advice but none of them are
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3605 enabled is equivalent to a call to `ad-deactivate'. The current advised
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3606 definition will always be cached for later usage."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3607 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3608 (list (ad-read-advised-function "Activate advice of")
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3609 current-prefix-arg))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3610 (if ad-activate-on-top-level
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3611 ;; avoid recursive calls to `ad-activate':
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3612 (ad-with-auto-activation-disabled
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3613 (if (not (ad-is-advised function))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3614 (error "ad-activate: `%s' is not advised" function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3615 (ad-handle-definition function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3616 ;; Just return for forward advised and not yet defined functions:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3617 (if (ad-get-orig-definition function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3618 (if (not (ad-has-any-advice function))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3619 (ad-unadvise function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3620 ;; Otherwise activate the advice:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3621 (cond ((ad-has-redefining-advice function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3622 (ad-activate-advised-definition function compile)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3623 (ad-set-advice-info-field function 'active t)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3624 (eval (ad-make-hook-form function 'activation))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3625 function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3626 ;; Here we are if we have all disabled advices:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3627 (t (ad-deactivate function)))))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3628
26247
f96b2bc4ef08 (ad-activate-on): Make it an alias for ad-activate.
Gerd Moellmann <gerd@gnu.org>
parents: 26217
diff changeset
3629 (defalias 'ad-activate-on 'ad-activate)
f96b2bc4ef08 (ad-activate-on): Make it an alias for ad-activate.
Gerd Moellmann <gerd@gnu.org>
parents: 26217
diff changeset
3630
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3631 (defun ad-deactivate (function)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3632 "Deactivate the advice of an actively advised FUNCTION.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3633 If FUNCTION has a proper original definition, then the current
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3634 definition of FUNCTION will be replaced with it. All the advice
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3635 information will still be available so it can be activated again with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3636 a call to `ad-activate'."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3637 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3638 (list (ad-read-advised-function "Deactivate advice of" 'ad-is-active)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3639 (if (not (ad-is-advised function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3640 (error "ad-deactivate: `%s' is not advised" function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3641 (cond ((ad-is-active function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3642 (ad-handle-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3643 (if (not (ad-get-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3644 (error "ad-deactivate: `%s' has no original definition"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3645 function)
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3646 (ad-safe-fset function (ad-get-orig-definition function))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3647 (ad-set-advice-info-field function 'active nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3648 (eval (ad-make-hook-form function 'deactivation))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3649 function)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3650
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3651 (defun ad-update (function &optional compile)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3652 "Update the advised definition of FUNCTION if its advice is active.
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3653 See `ad-activate' for documentation on the optional COMPILE argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3654 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3655 (list (ad-read-advised-function
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3656 "Update advised definition of" 'ad-is-active)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3657 (if (ad-is-active function)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3658 (ad-activate function compile)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3659
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3660 (defun ad-unadvise (function)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3661 "Deactivate FUNCTION and then remove all its advice information.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3662 If FUNCTION was not advised this will be a noop."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3663 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3664 (list (ad-read-advised-function "Unadvise function")))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3665 (cond ((ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3666 (if (ad-is-active function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3667 (ad-deactivate function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3668 (ad-clear-orig-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3669 (ad-set-advice-info function nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3670 (ad-pop-advised-function function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3671
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3672 (defun ad-recover (function)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3673 "Try to recover FUNCTION's original definition, and unadvise it.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3674 This is more low-level than `ad-unadvise' in that it does not do
26627
173f907a5812 Fix last change.
Dave Love <fx@gnu.org>
parents: 26622
diff changeset
3675 deactivation, which might run hooks and get into other trouble.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3676 Use in emergencies."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3677 ;; Use more primitive interactive behavior here: Accept any symbol that's
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3678 ;; currently defined in obarray, not necessarily with a function definition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3679 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3680 (list (intern
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3681 (completing-read "Recover advised function: " obarray nil t))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3682 (cond ((ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3683 (cond ((ad-get-orig-definition function)
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3684 (ad-safe-fset function (ad-get-orig-definition function))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3685 (ad-clear-orig-definition function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3686 (ad-set-advice-info function nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3687 (ad-pop-advised-function function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3688
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3689 (defun ad-activate-regexp (regexp &optional compile)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3690 "Activate functions with an advice name containing a REGEXP match.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3691 This activates the advice for each function
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3692 that has at least one piece of advice whose name includes a match for REGEXP.
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3693 See `ad-activate' for documentation on the optional COMPILE argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3694 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3695 (list (ad-read-regexp "Activate via advice regexp")
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3696 current-prefix-arg))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3697 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3698 (if (ad-find-some-advice function 'any regexp)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3699 (ad-activate function compile))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3700
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3701 (defun ad-deactivate-regexp (regexp)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3702 "Deactivate functions with an advice name containing REGEXP match.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3703 This deactivates the advice for each function
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3704 that has at least one piece of advice whose name includes a match for REGEXP."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3705 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3706 (list (ad-read-regexp "Deactivate via advice regexp")))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3707 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3708 (if (ad-find-some-advice function 'any regexp)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3709 (ad-deactivate function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3710
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3711 (defun ad-update-regexp (regexp &optional compile)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3712 "Update functions with an advice name containing a REGEXP match.
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3713 This reactivates the advice for each function
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3714 that has at least one piece of advice whose name includes a match for REGEXP.
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3715 See `ad-activate' for documentation on the optional COMPILE argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3716 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3717 (list (ad-read-regexp "Update via advice regexp")
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3718 current-prefix-arg))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3719 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3720 (if (ad-find-some-advice function 'any regexp)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3721 (ad-update function compile))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3722
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3723 (defun ad-activate-all (&optional compile)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3724 "Activate all currently advised functions.
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3725 See `ad-activate' for documentation on the optional COMPILE argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3726 (interactive "P")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3727 (ad-do-advised-functions (function)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3728 (ad-activate function compile)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3729
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3730 (defun ad-deactivate-all ()
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3731 "Deactivate all currently advised functions."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3732 (interactive)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3733 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3734 (ad-deactivate function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3735
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3736 (defun ad-update-all (&optional compile)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3737 "Update all currently advised functions.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3738 With prefix argument, COMPILE resulting advised definitions."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3739 (interactive "P")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3740 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3741 (ad-update function compile)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3742
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3743 (defun ad-unadvise-all ()
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3744 "Unadvise all currently advised functions."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3745 (interactive)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3746 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3747 (ad-unadvise function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3748
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3749 (defun ad-recover-all ()
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3750 "Recover all currently advised functions. Use in emergencies.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3751 To recover a function means to try to find its original (pre-advice)
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3752 definition, and delete all advice.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3753 This is more low-level than `ad-unadvise' in that it does not do
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3754 deactivation, which might run hooks and get into other trouble."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3755 (interactive)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3756 (ad-do-advised-functions (function)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3757 (condition-case nil
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3758 (ad-recover function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3759 (error nil))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3760
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3761
60923
08f8c7042636 * emacs-lisp/advice.el: Replace `legal' with `valid'.
Werner LEMBERG <wl@gnu.org>
parents: 57879
diff changeset
3762 ;; Completion alist of valid `defadvice' flags
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3763 (defvar ad-defadvice-flags
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3764 '(("protect") ("disable") ("activate")
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3765 ("compile") ("preactivate") ("freeze")))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3766
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3767 ;;;###autoload
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3768 (defmacro defadvice (function args &rest body)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3769 "Define a piece of advice for FUNCTION (a symbol).
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3770 The syntax of `defadvice' is as follows:
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3771
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3772 \(defadvice FUNCTION (CLASS NAME [POSITION] [ARGLIST] FLAG...)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3773 [DOCSTRING] [INTERACTIVE-FORM]
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3774 BODY... )
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3775
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3776 FUNCTION ::= Name of the function to be advised.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3777 CLASS ::= `before' | `around' | `after' | `activation' | `deactivation'.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3778 NAME ::= Non-nil symbol that names this piece of advice.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3779 POSITION ::= `first' | `last' | NUMBER. Optional, defaults to `first',
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3780 see also `ad-add-advice'.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3781 ARGLIST ::= An optional argument list to be used for the advised function
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3782 instead of the argument list of the original. The first one found in
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3783 before/around/after-advices will be used.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3784 FLAG ::= `protect'|`disable'|`activate'|`compile'|`preactivate'|`freeze'.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3785 All flags can be specified with unambiguous initial substrings.
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3786 DOCSTRING ::= Optional documentation for this piece of advice.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3787 INTERACTIVE-FORM ::= Optional interactive form to be used for the advised
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3788 function. The first one found in before/around/after-advices will be used.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3789 BODY ::= Any s-expression.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3790
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3791 Semantics of the various flags:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3792 `protect': The piece of advice will be protected against non-local exits in
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3793 any code that precedes it. If any around-advice of a function is protected
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3794 then automatically all around-advices will be protected (the complete onion).
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3795
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3796 `activate': All advice of FUNCTION will be activated immediately if
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3797 FUNCTION has been properly defined prior to this application of `defadvice'.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3798
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3799 `compile': In conjunction with `activate' specifies that the resulting
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3800 advised function should be compiled.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3801
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3802 `disable': The defined advice will be disabled, hence, it will not be used
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3803 during activation until somebody enables it.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3804
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3805 `preactivate': Preactivates the advised FUNCTION at macro-expansion/compile
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3806 time. This generates a compiled advised definition according to the current
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3807 advice state that will be used during activation if appropriate. Only use
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3808 this if the `defadvice' gets actually compiled.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3809
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3810 `freeze': Expands the `defadvice' into a redefining `defun/defmacro' according
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3811 to this particular single advice. No other advice information will be saved.
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3812 Frozen advices cannot be undone, they behave like a hard redefinition of
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3813 the advised function. `freeze' implies `activate' and `preactivate'. The
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3814 documentation of the advised function can be dumped onto the `DOC' file
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3815 during preloading.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3816
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3817 See Info node `(elisp)Advising Functions' for comprehensive documentation."
66398
df04170ba46b (ad-make-advised-definition): Fix arg-order.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 65680
diff changeset
3818 (declare (doc-string 3))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3819 (if (not (ad-name-p function))
22061
eed26995bfad (ad-handle-definition, defadvice): Fix error messages.
Richard M. Stallman <rms@gnu.org>
parents: 21365
diff changeset
3820 (error "defadvice: Invalid function name: %s" function))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3821 (let* ((class (car args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3822 (name (if (not (ad-class-p class))
22061
eed26995bfad (ad-handle-definition, defadvice): Fix error messages.
Richard M. Stallman <rms@gnu.org>
parents: 21365
diff changeset
3823 (error "defadvice: Invalid advice class: %s" class)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3824 (nth 1 args)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3825 (position (if (not (ad-name-p name))
22061
eed26995bfad (ad-handle-definition, defadvice): Fix error messages.
Richard M. Stallman <rms@gnu.org>
parents: 21365
diff changeset
3826 (error "defadvice: Invalid advice name: %s" name)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3827 (setq args (nthcdr 2 args))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3828 (if (ad-position-p (car args))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3829 (prog1 (car args)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3830 (setq args (cdr args))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3831 (arglist (if (listp (car args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3832 (prog1 (car args)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3833 (setq args (cdr args)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3834 (flags
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3835 (mapcar
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3836 (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3837 (lambda (flag)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3838 (let ((completion
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3839 (try-completion (symbol-name flag) ad-defadvice-flags)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3840 (cond ((eq completion t) flag)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3841 ((assoc completion ad-defadvice-flags)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3842 (intern completion))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3843 (t (error "defadvice: Invalid or ambiguous flag: %s"
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3844 flag))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3845 args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3846 (advice (ad-make-advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3847 name (memq 'protect flags)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3848 (not (memq 'disable flags))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3849 `(advice lambda ,arglist ,@body)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3850 (preactivation (if (memq 'preactivate flags)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3851 (ad-preactivate-advice
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3852 function advice class position))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3853 ;; Now for the things to be done at evaluation time:
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3854 (if (memq 'freeze flags)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3855 ;; jwz's idea: Freeze the advised definition into a dumpable
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3856 ;; defun/defmacro whose docs can be written to the DOC file:
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3857 (ad-make-freeze-definition function advice class position)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3858 ;; the normal case:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3859 `(progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3860 (ad-add-advice ',function ',advice ',class ',position)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3861 ,@(if preactivation
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3862 `((ad-set-cache
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3863 ',function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3864 ;; the function will get compiled:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3865 ,(cond ((ad-macro-p (car preactivation))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3866 `(ad-macrofy
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3867 (function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3868 ,(ad-lambdafy
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3869 (car preactivation)))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3870 (t `(function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3871 ,(car preactivation))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3872 ',(car (cdr preactivation)))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3873 ,@(if (memq 'activate flags)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3874 `((ad-activate ',function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3875 ,(if (memq 'compile flags) t))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3876 ',function))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3877
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3878
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3879 ;; @@ Tools:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3880 ;; =========
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3881
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3882 (defmacro ad-with-originals (functions &rest body)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3883 "Binds FUNCTIONS to their original definitions and execute BODY.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3884 For any members of FUNCTIONS that are not currently advised the rebinding will
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3885 be a noop. Any modifications done to the definitions of FUNCTIONS will be
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3886 undone on exit of this macro."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3887 (let* ((index -1)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3888 ;; Make let-variables to store current definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3889 (current-bindings
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3890 (mapcar (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3891 (lambda (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3892 (setq index (1+ index))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3893 (list (intern (format "ad-oRiGdEf-%d" index))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3894 `(symbol-function ',function))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3895 functions)))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3896 `(let ,current-bindings
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3897 (unwind-protect
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3898 (progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3899 ,@(progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3900 ;; Make forms to redefine functions to their
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3901 ;; original definitions if they are advised:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3902 (setq index -1)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3903 (mapcar
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3904 (function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3905 (lambda (function)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3906 (setq index (1+ index))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3907 `(ad-safe-fset
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3908 ',function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3909 (or (ad-get-orig-definition ',function)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3910 ,(car (nth index current-bindings))))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3911 functions))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3912 ,@body)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3913 ,@(progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3914 ;; Make forms to back-define functions to the definitions
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3915 ;; they had outside this macro call:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3916 (setq index -1)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3917 (mapcar
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3918 (function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3919 (lambda (function)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3920 (setq index (1+ index))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3921 `(ad-safe-fset
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3922 ',function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3923 ,(car (nth index current-bindings)))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3924 functions))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3925
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3926 (if (not (get 'ad-with-originals 'lisp-indent-hook))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3927 (put 'ad-with-originals 'lisp-indent-hook 1))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3928
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3929
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3930 ;; @@ Advising `documentation':
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3931 ;; ============================
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3932 ;; Use the advice mechanism to advise `documentation' to make it
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3933 ;; generate proper documentation strings for advised definitions:
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3934
45019
c726a3eeeb0f (documentation): Add ad-define-subr-args call.
Richard M. Stallman <rms@gnu.org>
parents: 41936
diff changeset
3935 ;; This makes sure we get the right arglist for `documentation'
c726a3eeeb0f (documentation): Add ad-define-subr-args call.
Richard M. Stallman <rms@gnu.org>
parents: 41936
diff changeset
3936 ;; during bootstrapping.
c726a3eeeb0f (documentation): Add ad-define-subr-args call.
Richard M. Stallman <rms@gnu.org>
parents: 41936
diff changeset
3937 (ad-define-subr-args 'documentation '(function &optional raw))
c726a3eeeb0f (documentation): Add ad-define-subr-args call.
Richard M. Stallman <rms@gnu.org>
parents: 41936
diff changeset
3938
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3939 (defadvice documentation (after ad-advised-docstring first disable preact)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3940 "Builds an advised docstring if FUNCTION is advised."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3941 ;; Because we get the function name from the advised docstring
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3942 ;; this will work for function names as well as for definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3943 (if (and (stringp ad-return-value)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3944 (string-match
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3945 ad-advised-definition-docstring-regexp ad-return-value))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3946 (let ((function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3947 (car (read-from-string
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3948 ad-return-value (match-beginning 1) (match-end 1)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3949 (cond ((ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3950 (setq ad-return-value (ad-make-advised-docstring function))
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3951 ;; Handle optional `raw' argument:
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3952 (if (not (ad-get-arg 1))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3953 (setq ad-return-value
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3954 (substitute-command-keys ad-return-value))))))))
5746
94535442be19 (ad-execute-defadvices): Don't allocate advice-infos in pure space, in case we
Karl Heuer <kwzh@gnu.org>
parents: 5140
diff changeset
3955
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3956
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3957 ;; @@ Starting, stopping and recovering from the advice package magic:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3958 ;; ===================================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3959
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3960 (defun ad-start-advice ()
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3961 "Start the automatic advice handling magic."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3962 (interactive)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3963 ;; Advising `ad-activate-internal' means death!!
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3964 (ad-set-advice-info 'ad-activate-internal nil)
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3965 (ad-safe-fset 'ad-activate-internal 'ad-activate)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3966 (ad-enable-advice 'documentation 'after 'ad-advised-docstring)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3967 (ad-activate 'documentation 'compile))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3968
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3969 (defun ad-stop-advice ()
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3970 "Stop the automatic advice handling magic.
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3971 You should only need this in case of Advice-related emergencies."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3972 (interactive)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3973 ;; Advising `ad-activate-internal' means death!!
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3974 (ad-set-advice-info 'ad-activate-internal nil)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3975 (ad-disable-advice 'documentation 'after 'ad-advised-docstring)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3976 (ad-update 'documentation)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3977 (ad-safe-fset 'ad-activate-internal 'ad-activate-internal-off))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3978
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3979 (defun ad-recover-normality ()
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3980 "Undo all advice related redefinitions and unadvises everything.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3981 Use only in REAL emergencies."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3982 (interactive)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3983 ;; Advising `ad-activate-internal' means death!!
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3984 (ad-set-advice-info 'ad-activate-internal nil)
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3985 (ad-safe-fset 'ad-activate-internal 'ad-activate-internal-off)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3986 (ad-recover-all)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3987 (setq ad-advised-functions nil))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3988
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3989 (ad-start-advice)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3990
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3991 (provide 'advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3992
66398
df04170ba46b (ad-make-advised-definition): Fix arg-order.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 65680
diff changeset
3993 ;; arch-tag: 29f8c9a1-8c88-471f-95d7-e28541c6b7c0
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3994 ;;; advice.el ends here