annotate lisp/emacs-lisp/advice.el @ 82447:7206375cd8a6

(copyright-limit): New defsubst. (copyright-update-year, copyright-update) (copyright-fix-years): Use it.
author Thien-Thi Nguyen <ttn@gnuvola.org>
date Fri, 17 Aug 2007 22:05:52 +0000
parents 5800574abbcb
children 0fc42eec71c0 539530fa389c
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
74466
1d4b1a32fd66 Update copyright years.
Glenn Morris <rgm@gnu.org>
parents: 73251
diff changeset
3 ;; Copyright (C) 1993, 1994, 2000, 2001, 2002, 2003, 2004,
75346
7a3f13e2dd57 Add 2007 to copyright years.
Glenn Morris <rgm@gnu.org>
parents: 74466
diff changeset
4 ;; 2005, 2006, 2007 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
78217
935157c0b596 Switch license to GPLv3 or later.
Glenn Morris <rgm@gnu.org>
parents: 78150
diff changeset
15 ;; the Free Software Foundation; either version 3, or (at your option)
4110
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)
73251
25e1db3fd0ed (ad-remove-advice, ad-parse-arglist, ad-make-mapped-call):
Juanma Barranquero <lekktu@gmail.com>
parents: 70899
diff changeset
2412 (let ((advice-to-remove (ad-find-advice function class name)))
4110
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
80879
cdee0fbb5943 (ad-special-forms): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 75346
diff changeset
2470 (defun ad-special-form-p (definition)
cdee0fbb5943 (ad-special-forms): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 75346
diff changeset
2471 "Non-nil iff DEFINITION is a special form."
cdee0fbb5943 (ad-special-forms): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 75346
diff changeset
2472 (if (and (symbolp definition) (fboundp definition))
cdee0fbb5943 (ad-special-forms): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 75346
diff changeset
2473 (setq definition (indirect-function definition)))
cdee0fbb5943 (ad-special-forms): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 75346
diff changeset
2474 (and (subrp definition) (eq (cdr (subr-arity definition)) 'unevalled)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2475
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2476 (defmacro ad-subr-p (definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2477 ;;"non-nil if DEFINITION is a subr."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2478 (list 'subrp definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2479
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2480 (defmacro ad-macro-p (definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2481 ;;"non-nil if DEFINITION is a macro."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2482 `(eq (car-safe ,definition) 'macro))
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-lambda-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 lambda expression."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2486 `(eq (car-safe ,definition) 'lambda))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2487
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2488 ;; see ad-make-advice for the format of advice definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2489 (defmacro ad-advice-p (definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2490 ;;"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
2491 `(eq (car-safe ,definition) 'advice))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2492
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2493 ;; Emacs/Lemacs cross-compatibility
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2494 ;; (compiled-function-p is an obsolete function in Emacs):
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2495 (if (and (not (fboundp 'byte-code-function-p))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2496 (fboundp 'compiled-function-p))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2497 (ad-safe-fset 'byte-code-function-p 'compiled-function-p))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2498
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2499 (defmacro ad-compiled-p (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2500 "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
2501 `(or (byte-code-function-p ,definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2502 (and (ad-macro-p ,definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2503 (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
2504
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2505 (defmacro ad-compiled-code (compiled-definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2506 "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
2507 `(if (ad-macro-p ,compiled-definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2508 (ad-lambdafy ,compiled-definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2509 ,compiled-definition))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2510
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2511 (defun ad-lambda-expression (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2512 "Return the lambda expression of a function/macro/advice DEFINITION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2513 (cond ((ad-lambda-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2514 definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2515 ((ad-macro-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2516 (ad-lambdafy definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2517 ((ad-advice-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2518 (cdr definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2519 (t nil)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2520
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2521 (defun ad-arglist (definition &optional name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2522 "Return the argument list of DEFINITION.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2523 If DEFINITION could be from a subr then its NAME should be
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2524 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
2525 (cond ((ad-compiled-p definition)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2526 (aref (ad-compiled-code definition) 0))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2527 ((consp definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2528 (car (cdr (ad-lambda-expression definition))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2529 ((ad-subr-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2530 (if name
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2531 (ad-subr-arglist name)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2532 ;; otherwise get it from its printed representation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2533 (setq name (format "%s" definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2534 (string-match "^#<subr \\([^>]+\\)>$" name)
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2535 (ad-subr-arglist (intern (match-string 1 name)))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2536
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2537 ;; Store subr-args as `((arg1 arg2 ...))' so I can distinguish
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2538 ;; a defined empty arglist `(nil)' from an undefined arglist:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2539 (defmacro ad-define-subr-args (subr arglist)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2540 `(put ,subr 'ad-subr-arglist (list ,arglist)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2541 (defmacro ad-undefine-subr-args (subr)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2542 `(put ,subr 'ad-subr-arglist nil))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2543 (defmacro ad-subr-args-defined-p (subr)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2544 `(get ,subr 'ad-subr-arglist))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2545 (defmacro ad-get-subr-args (subr)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2546 `(car (get ,subr 'ad-subr-arglist)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2547
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2548 (defun ad-subr-arglist (subr-name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2549 "Retrieve arglist of the subr with SUBR-NAME.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2550 Either use the one stored under the `ad-subr-arglist' property,
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2551 or try to retrieve it from the docstring and cache it under
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2552 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
2553 (if (ad-subr-args-defined-p subr-name)
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2554 (ad-get-subr-args subr-name)
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2555 ;; 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
2556 ;;((fboundp 'subr-min-args)
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2557 ;; ...)
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2558 ;; 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
2559 ;; 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
2560 ;; 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
2561 ;; 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
2562 ;; 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
2563 ;; 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
2564 ;; 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
2565 ;; 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
2566 ;; the old way of doing things.
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2567 (let ((doc (or (ad-real-documentation subr-name t) "")))
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2568 (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
2569 ;; 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
2570 ;; 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
2571 ;; (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
2572 '(&rest ad-subr-args)
54493
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2573 (ad-define-subr-args
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2574 subr-name
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2575 (cdr (car (read-from-string
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2576 (downcase (match-string 1 doc))))))
d8586f19729a (ad-subr-arglist): Simplify.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 52401
diff changeset
2577 (ad-get-subr-args subr-name)))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2578
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2579 (defun ad-docstring (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2580 "Return the unexpanded docstring of DEFINITION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2581 (let ((docstring
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2582 (if (ad-compiled-p definition)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2583 (ad-real-documentation definition t)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2584 (car (cdr (cdr (ad-lambda-expression definition)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2585 (if (or (stringp docstring)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2586 (natnump docstring))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2587 docstring)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2588
82192
5800574abbcb (ad-interactive-form): Re-introduce.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82146
diff changeset
2589 (defun ad-interactive-form (definition)
5800574abbcb (ad-interactive-form): Re-introduce.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82146
diff changeset
2590 "Return the interactive form of DEFINITION.
5800574abbcb (ad-interactive-form): Re-introduce.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82146
diff changeset
2591 Like `interactive-form', but also works on pieces of advice."
5800574abbcb (ad-interactive-form): Re-introduce.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82146
diff changeset
2592 (interactive-form
5800574abbcb (ad-interactive-form): Re-introduce.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82146
diff changeset
2593 (if (ad-advice-p definition)
5800574abbcb (ad-interactive-form): Re-introduce.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82146
diff changeset
2594 (ad-lambda-expression definition)
5800574abbcb (ad-interactive-form): Re-introduce.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82146
diff changeset
2595 definition)))
5800574abbcb (ad-interactive-form): Re-introduce.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82146
diff changeset
2596
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2597 (defun ad-body-forms (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2598 "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
2599 (cond ((ad-compiled-p definition)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2600 nil)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2601 ((consp definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2602 (nthcdr (+ (if (ad-docstring definition) 1 0)
82192
5800574abbcb (ad-interactive-form): Re-introduce.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82146
diff changeset
2603 (if (ad-interactive-form definition) 1 0))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2604 (cdr (cdr (ad-lambda-expression definition)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2605
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2606 ;; Matches the docstring of an advised definition.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2607 ;; The first group of the regexp matches the function name:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2608 (defvar ad-advised-definition-docstring-regexp "^\\$ad-doc: \\(.+\\)\\$$")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2609
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2610 (defun ad-make-advised-definition-docstring (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2611 "Make an identifying docstring for the advised definition of FUNCTION.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2612 Put function name into the documentation string so we can infer
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2613 the name of the advised function from the docstring. This is needed
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2614 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
2615 definition (also see the defadvice for `documentation')."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2616 (format "$ad-doc: %s$" (prin1-to-string function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2617
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2618 (defun ad-advised-definition-p (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2619 "Return non-nil if DEFINITION was generated from advice information."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2620 (if (or (ad-lambda-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2621 (ad-macro-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2622 (ad-compiled-p definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2623 (let ((docstring (ad-docstring definition)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2624 (and (stringp docstring)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2625 (string-match
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2626 ad-advised-definition-docstring-regexp docstring)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2627
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2628 (defun ad-definition-type (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2629 "Return symbol that describes the type of DEFINITION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2630 (if (ad-macro-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2631 'macro
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2632 (if (ad-subr-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2633 (if (ad-special-form-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2634 'special-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2635 'subr)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2636 (if (or (ad-lambda-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2637 (ad-compiled-p definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2638 'function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2639 (if (ad-advice-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2640 'advice)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2641
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2642 (defun ad-has-proper-definition (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2643 "True if FUNCTION is a symbol with a proper definition.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2644 For that it has to be fbound with a non-autoload definition."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2645 (and (symbolp function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2646 (fboundp function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2647 (not (eq (car-safe (symbol-function function)) 'autoload))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2648
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2649 ;; The following two are necessary for the sake of packages such as
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2650 ;; ange-ftp which redefine functions via fcell indirection:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2651 (defun ad-real-definition (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2652 "Find FUNCTION's definition at the end of function cell indirection."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2653 (if (ad-has-proper-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2654 (let ((definition (symbol-function function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2655 (if (symbolp definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2656 (ad-real-definition definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2657 definition))))
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-real-orig-definition (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2660 "Find FUNCTION's real original definition starting from its `origname'."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2661 (if (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2662 (ad-real-definition (ad-get-advice-info-field function 'origname))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2663
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2664 (defun ad-is-compilable (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2665 "True if FUNCTION has an interpreted definition that can be compiled."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2666 (and (ad-has-proper-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2667 (or (ad-lambda-p (symbol-function function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2668 (ad-macro-p (symbol-function function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2669 (not (ad-compiled-p (symbol-function function)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2670
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2671 (defun ad-compile-function (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2672 "Byte-compiles FUNCTION (or macro) if it is not yet compiled."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2673 (interactive "aByte-compile function: ")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2674 (if (ad-is-compilable function)
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2675 ;; Need to turn off auto-activation
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2676 ;; because `byte-compile' uses `fset':
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2677 (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
2678 (require 'bytecomp)
73cafacdf14f (ad-compile-function): Disable cl-function warnings if cl is loaded.
Richard M. Stallman <rms@gnu.org>
parents: 45019
diff changeset
2679 (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
2680 (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
2681 (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
2682 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
2683 (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
2684 (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
2685 (remq 'cl-functions byte-compile-warnings)))
41936
2fba35852455 (ad-compile-function):
Richard M. Stallman <rms@gnu.org>
parents: 41608
diff changeset
2686 (fset symbol (symbol-function function))
2fba35852455 (ad-compile-function):
Richard M. Stallman <rms@gnu.org>
parents: 41608
diff changeset
2687 (byte-compile symbol)
2fba35852455 (ad-compile-function):
Richard M. Stallman <rms@gnu.org>
parents: 41608
diff changeset
2688 (fset function (symbol-function symbol))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2689
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2690
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2691 ;; @@ Constructing advised definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2692 ;; ====================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2693 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2694 ;; Main design decisions about the form of advised definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2695 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2696 ;; A) How will original definitions be called?
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2697 ;; B) What will argument lists of advised functions look like?
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2698 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2699 ;; Ad A)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2700 ;; I chose to use function indirection for all four types of original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2701 ;; definitions (functions, macros, subrs and special forms), i.e., create
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2702 ;; 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
2703 ;; definition and call it according to type and arguments. Functions and
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2704 ;; 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
2705 ;; `(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
2706 ;; use `apply'. Macros will be called with
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2707 ;; `(macroexpand '(ad-Orig-<name> ....))', and special forms also need a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2708 ;; form like that with `eval' instead of `macroexpand'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2709 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2710 ;; Ad B)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2711 ;; Use original arguments where possible and `(&rest ad-subr-args)'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2712 ;; otherwise, even though this seems to be more complicated and less
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2713 ;; uniform than a general `(&rest args)' approach. My reason to still
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2714 ;; 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
2715 ;; efficient form for the advised function, and portability (e.g., to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2716 ;; make the same advice work regardless of whether something is a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2717 ;; function or a subr) can still be achieved with argument access macros.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2718
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2719
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2720 (defun ad-prognify (forms)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2721 (cond ((<= (length forms) 1)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2722 (car forms))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2723 (t (cons 'progn forms))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2724
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2725 ;; @@@ Accessing argument lists:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2726 ;; =============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2727
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2728 (defun ad-parse-arglist (arglist)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2729 "Parse ARGLIST into its required, optional and rest parameters.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2730 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
2731 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
2732 is the name of an optional rest parameter (or nil)."
73251
25e1db3fd0ed (ad-remove-advice, ad-parse-arglist, ad-make-mapped-call):
Juanma Barranquero <lekktu@gmail.com>
parents: 70899
diff changeset
2733 (let (required optional rest)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2734 (setq rest (car (cdr (memq '&rest arglist))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2735 (if rest (setq arglist (reverse (cdr (memq '&rest (reverse arglist))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2736 (setq optional (cdr (memq '&optional arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2737 (if optional
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2738 (setq required (reverse (cdr (memq '&optional (reverse arglist)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2739 (setq required arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2740 (list required optional rest)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2741
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2742 (defun ad-retrieve-args-form (arglist)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2743 "Generate a form which evaluates into names/values/types of ARGLIST.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2744 When the form gets evaluated within a function with that argument list
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2745 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
2746 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
2747 element is its actual current value, and the third element is either
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2748 `required', `optional' or `rest' depending on the type of the argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2749 (let* ((parsed-arglist (ad-parse-arglist arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2750 (rest (nth 2 parsed-arglist)))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2751 `(list
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2752 ,@(mapcar (function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2753 (lambda (req)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2754 `(list ',req ,req 'required)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2755 (nth 0 parsed-arglist))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2756 ,@(mapcar (function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2757 (lambda (opt)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2758 `(list ',opt ,opt 'optional)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2759 (nth 1 parsed-arglist))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2760 ,@(if rest (list `(list ',rest ,rest 'rest))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2761
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2762 (defun ad-arg-binding-field (binding field)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2763 (cond ((eq field 'name) (car binding))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2764 ((eq field 'value) (car (cdr binding)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2765 ((eq field 'type) (car (cdr (cdr binding))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2766
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2767 (defun ad-list-access (position list)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2768 (cond ((= position 0) list)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2769 ((= position 1) (list 'cdr list))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2770 (t (list 'nthcdr position list))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2771
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2772 (defun ad-element-access (position list)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2773 (cond ((= position 0) (list 'car list))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2774 ((= position 1) `(car (cdr ,list)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2775 (t (list 'nth position list))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2776
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2777 (defun ad-access-argument (arglist index)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2778 "Tell how to access ARGLIST's actual argument at position INDEX.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2779 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
2780 to be accessed, it returns a list with the index and name."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2781 (let* ((parsed-arglist (ad-parse-arglist arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2782 (reqopt-args (append (nth 0 parsed-arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2783 (nth 1 parsed-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2784 (rest-arg (nth 2 parsed-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2785 (cond ((< index (length reqopt-args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2786 (nth index reqopt-args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2787 (rest-arg
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2788 (list (- index (length reqopt-args)) rest-arg)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2789
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2790 (defun ad-get-argument (arglist index)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2791 "Return form to access ARGLIST's actual argument at position INDEX."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2792 (let ((argument-access (ad-access-argument arglist index)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2793 (cond ((consp argument-access)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2794 (ad-element-access
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2795 (car argument-access) (car (cdr argument-access))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2796 (argument-access))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2797
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2798 (defun ad-set-argument (arglist index value-form)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2799 "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
2800 (let ((argument-access (ad-access-argument arglist index)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2801 (cond ((consp argument-access)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2802 ;; 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
2803 `(setcar ,(ad-list-access
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2804 (car argument-access) (car (cdr argument-access)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2805 ,value-form))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2806 (argument-access
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2807 `(setq ,argument-access ,value-form))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2808 (t (error "ad-set-argument: No argument at position %d of `%s'"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2809 index arglist)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2810
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2811 (defun ad-get-arguments (arglist index)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2812 "Return form to access all actual arguments starting at position INDEX."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2813 (let* ((parsed-arglist (ad-parse-arglist arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2814 (reqopt-args (append (nth 0 parsed-arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2815 (nth 1 parsed-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2816 (rest-arg (nth 2 parsed-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2817 args-form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2818 (if (< index (length reqopt-args))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2819 (setq args-form `(list ,@(nthcdr index reqopt-args))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2820 (if rest-arg
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2821 (if args-form
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2822 (setq args-form `(nconc ,args-form ,rest-arg))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2823 (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
2824 rest-arg))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2825 args-form))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2826
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2827 (defun ad-set-arguments (arglist index values-form)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2828 "Make form to assign elements of VALUES-FORM as actual ARGLIST args.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2829 The assignment starts at position INDEX."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2830 (let ((values-index 0)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2831 argument-access set-forms)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2832 (while (setq argument-access (ad-access-argument arglist index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2833 (if (symbolp argument-access)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2834 (setq set-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2835 (cons (ad-set-argument
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2836 arglist index
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2837 (ad-element-access values-index 'ad-vAlUeS))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2838 set-forms))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2839 (setq set-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2840 (cons (if (= (car argument-access) 0)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2841 (list 'setq
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2842 (car (cdr argument-access))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2843 (ad-list-access values-index 'ad-vAlUeS))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2844 (list 'setcdr
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2845 (ad-list-access (1- (car argument-access))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2846 (car (cdr argument-access)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2847 (ad-list-access values-index 'ad-vAlUeS)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2848 set-forms))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2849 ;; terminate loop
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2850 (setq arglist nil))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2851 (setq index (1+ index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2852 (setq values-index (1+ values-index)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2853 (if (null set-forms)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2854 (error "ad-set-arguments: No argument at position %d of `%s'"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2855 index arglist)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2856 (if (= (length set-forms) 1)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2857 ;; 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
2858 (ad-substitute-tree
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2859 (function (lambda (form) (eq form 'ad-vAlUeS)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2860 (function (lambda (form) values-form))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2861 (car set-forms))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2862 ;; ...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
2863 `(let ((ad-vAlUeS ,values-form))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2864 ,@(reverse set-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2865 ;; work around the old backquote bug:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2866 ,'ad-vAlUeS)))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2867
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2868 (defun ad-insert-argument-access-forms (definition arglist)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2869 "Expands arg-access text macros in DEFINITION according to ARGLIST."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2870 (ad-substitute-tree
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2871 (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2872 (lambda (form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2873 (or (eq form 'ad-arg-bindings)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2874 (and (memq (car-safe form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2875 '(ad-get-arg ad-get-args ad-set-arg ad-set-args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2876 (integerp (car-safe (cdr form)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2877 (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2878 (lambda (form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2879 (if (eq form 'ad-arg-bindings)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2880 (ad-retrieve-args-form arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2881 (let ((accessor (car form))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2882 (index (car (cdr form)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2883 (val (car (cdr (ad-insert-argument-access-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2884 (cdr form) arglist)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2885 (cond ((eq accessor 'ad-get-arg)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2886 (ad-get-argument arglist index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2887 ((eq accessor 'ad-set-arg)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2888 (ad-set-argument arglist index val))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2889 ((eq accessor 'ad-get-args)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2890 (ad-get-arguments arglist index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2891 ((eq accessor 'ad-set-args)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2892 (ad-set-arguments arglist index val)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2893 definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2894
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2895 ;; @@@ Mapping argument lists:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2896 ;; ===========================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2897 ;; Here is the problem:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2898 ;; 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
2899 ;; 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
2900 ;; 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
2901 ;; 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
2902 ;; The mapping should work for any two argument lists.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2903
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2904 (defun ad-map-arglists (source-arglist target-arglist)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2905 "Make `funcall/apply' form to map SOURCE-ARGLIST to TARGET-ARGLIST.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2906 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
2907 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
2908 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
2909 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
2910 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
2911 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
2912 `(funcall function a (car args) (car (cdr args)) (nth 2 args))'."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2913 (let* ((parsed-source-arglist (ad-parse-arglist source-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2914 (source-reqopt-args (append (nth 0 parsed-source-arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2915 (nth 1 parsed-source-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2916 (source-rest-arg (nth 2 parsed-source-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2917 (parsed-target-arglist (ad-parse-arglist target-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2918 (target-reqopt-args (append (nth 0 parsed-target-arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2919 (nth 1 parsed-target-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2920 (target-rest-arg (nth 2 parsed-target-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2921 (need-apply (and source-rest-arg target-rest-arg))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2922 (target-arg-index -1))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2923 ;; This produces ``error-proof'' target function calls with the exception
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2924 ;; 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
2925 ;; 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
2926 (append (list (if need-apply 'apply 'funcall) 'function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2927 (cond (need-apply
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2928 ;; `apply' can take care of that directly:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2929 (append source-reqopt-args (list source-rest-arg)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2930 (t (mapcar (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2931 (lambda (arg)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2932 (setq target-arg-index (1+ target-arg-index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2933 (ad-get-argument
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2934 source-arglist target-arg-index)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2935 (append target-reqopt-args
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2936 (and target-rest-arg
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2937 ;; If we have a rest arg gobble up
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2938 ;; remaining source args:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2939 (nthcdr (length target-reqopt-args)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2940 source-reqopt-args)))))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2941
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2942 (defun ad-make-mapped-call (source-arglist target-arglist target-function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2943 "Make form to call TARGET-FUNCTION with args from SOURCE-ARGLIST."
73251
25e1db3fd0ed (ad-remove-advice, ad-parse-arglist, ad-make-mapped-call):
Juanma Barranquero <lekktu@gmail.com>
parents: 70899
diff changeset
2944 (let ((mapped-form (ad-map-arglists source-arglist target-arglist)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2945 (if (eq (car mapped-form) 'funcall)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2946 (cons target-function (cdr (cdr mapped-form)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2947 (prog1 mapped-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2948 (setcar (cdr mapped-form) (list 'quote target-function))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2949
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2950 ;; @@@ Making an advised documentation string:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2951 ;; ===========================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2952 ;; 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
2953 ;; at the time the advised `documentation' function is called. This has the
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2954 ;; following advantages:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2955 ;; 1) command-key substitutions will automatically be correct
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2956 ;; 2) No wasted string space due to big advised docstrings in caches or
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2957 ;; compiled files that contain preactivations
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2958 ;; The overall overhead for this should be negligible because people normally
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2959 ;; don't lookup documentation for the same function over and over again.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2960
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2961 (defun ad-make-single-advice-docstring (advice class &optional style)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2962 (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
2963 (cond ((eq style 'plain)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2964 advice-docstring)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2965 ((eq style 'freeze)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2966 (format "Permanent %s-advice `%s':%s%s"
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2967 class (ad-advice-name advice)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2968 (if advice-docstring "\n" "")
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2969 (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
2970 (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
2971 (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
2972 (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
2973 (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
2974 advice-docstring)
76f5f50e7742 (ad-make-single-advice-docstring): Treat case with no doctring specially.
Dave Love <fx@gnu.org>
parents: 24875
diff changeset
2975 (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
2976 (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
2977 (ad-advice-name advice)))))))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2978
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2979 (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
2980
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2981 (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
2982 "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
2983 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
2984 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
2985 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
2986 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
2987 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
2988 in any of these classes."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2989 (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
2990 (origtype (symbol-name (ad-definition-type origdef)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2991 (origdoc
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2992 ;; 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
2993 (ad-real-documentation origdef t))
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2994 (usage (help-split-fundoc origdoc function))
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2995 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
2996 (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
2997 (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
2998 (unless (eq style 'plain)
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2999 (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
3000 (ad-dolist (class ad-advice-classes)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3001 (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
3002 (setq advice-docstring
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3003 (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
3004 (if advice-docstring
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3005 (push advice-docstring paragraphs))))
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3006 (setq origdoc (if paragraphs
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3007 ;; separate paragraphs with blank lines:
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3008 (mapconcat 'identity (nreverse paragraphs) "\n\n")))
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3009 (help-add-fundoc-usage origdoc usage)))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3010
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3011 (defun ad-make-plain-docstring (function)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3012 (ad-make-advised-docstring function 'plain))
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3013 (defun ad-make-freeze-docstring (function)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3014 (ad-make-advised-docstring function 'freeze))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3015
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3016 ;; @@@ Accessing overriding arglists and interactive forms:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3017 ;; ========================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3018
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3019 (defun ad-advised-arglist (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3020 "Find first defined arglist in FUNCTION's redefining advices."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3021 (ad-dolist (advice (append (ad-get-enabled-advices function 'before)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3022 (ad-get-enabled-advices function 'around)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3023 (ad-get-enabled-advices function 'after)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3024 (let ((arglist (ad-arglist (ad-advice-definition advice))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3025 (if arglist
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3026 ;; We found the first one, use it:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3027 (ad-do-return arglist)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3028
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3029 (defun ad-advised-interactive-form (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3030 "Find first interactive form in FUNCTION's redefining advices."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3031 (ad-dolist (advice (append (ad-get-enabled-advices function 'before)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3032 (ad-get-enabled-advices function 'around)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3033 (ad-get-enabled-advices function 'after)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3034 (let ((interactive-form
82192
5800574abbcb (ad-interactive-form): Re-introduce.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82146
diff changeset
3035 (ad-interactive-form (ad-advice-definition advice))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3036 (if interactive-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3037 ;; We found the first one, use it:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3038 (ad-do-return interactive-form)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3039
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3040 ;; @@@ Putting it all together:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3041 ;; ============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3042
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3043 (defun ad-make-advised-definition (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3044 "Generate an advised definition of FUNCTION from its advice info."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3045 (if (and (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3046 (ad-has-redefining-advice function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3047 (let* ((origdef (ad-real-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3048 (origname (ad-get-advice-info-field function 'origname))
82146
5868631b2e87 (ad-interactive-p, ad-interactive-form): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82140
diff changeset
3049 (orig-interactive-p (commandp origdef))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3050 (orig-subr-p (ad-subr-p origdef))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3051 (orig-special-form-p (ad-special-form-p origdef))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3052 (orig-macro-p (ad-macro-p origdef))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3053 ;; Construct the individual pieces that we need for assembly:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3054 (orig-arglist (ad-arglist origdef function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3055 (advised-arglist (or (ad-advised-arglist function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3056 orig-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3057 (advised-interactive-form (ad-advised-interactive-form function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3058 (interactive-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3059 (cond (orig-macro-p nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3060 (advised-interactive-form)
82146
5868631b2e87 (ad-interactive-p, ad-interactive-form): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82140
diff changeset
3061 ((interactive-form origdef)
5868631b2e87 (ad-interactive-p, ad-interactive-form): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82140
diff changeset
3062 (interactive-form
5868631b2e87 (ad-interactive-p, ad-interactive-form): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82140
diff changeset
3063 (if (and (symbolp function) (get function 'elp-info))
5868631b2e87 (ad-interactive-p, ad-interactive-form): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82140
diff changeset
3064 (aref (get function 'elp-info) 2)
5868631b2e87 (ad-interactive-p, ad-interactive-form): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82140
diff changeset
3065 origdef)))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3066 (orig-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3067 (cond ((or orig-special-form-p orig-macro-p)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3068 ;; Special forms and macros will be advised into macros.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3069 ;; The trick is to construct an expansion for the advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3070 ;; macro that does the correct thing when it gets eval'ed.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3071 ;; For macros we'll just use the expansion of the original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3072 ;; macro and return that. This way compiled advised macros
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3073 ;; will be expanded into something useful. Note that after
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3074 ;; advices have full control over whether they want to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3075 ;; evaluate the expansion (the value of `ad-return-value')
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3076 ;; at macro expansion time or not. For special forms there
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3077 ;; is no solution that interacts reasonably with the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3078 ;; compiler, hence we just evaluate the original at macro
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3079 ;; expansion time and return the result. The moral of that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3080 ;; is that one should always deactivate advised special
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3081 ;; forms before one byte-compiles a file.
37304
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3082 `(,(if orig-macro-p 'macroexpand 'eval)
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3083 (cons ',origname
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3084 ,(ad-get-arguments advised-arglist 0))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3085 ((and orig-subr-p
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3086 orig-interactive-p
37304
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3087 (not interactive-form)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3088 (not advised-interactive-form))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3089 ;; Check whether we were called interactively
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3090 ;; 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
3091 `(if (called-interactively-p)
37304
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3092 (call-interactively ',origname)
66398
df04170ba46b (ad-make-advised-definition): Fix arg-order.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 65680
diff changeset
3093 ,(ad-make-mapped-call advised-arglist
df04170ba46b (ad-make-advised-definition): Fix arg-order.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 65680
diff changeset
3094 orig-arglist
37304
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3095 origname)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3096 ;; And now for normal functions and non-interactive subrs
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3097 ;; (or subrs whose interactive behavior was advised):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3098 (t (ad-make-mapped-call
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3099 advised-arglist orig-arglist origname)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3100
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3101 ;; Finally, build the sucker:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3102 (ad-assemble-advised-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3103 (cond (orig-macro-p 'macro)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3104 (orig-special-form-p 'special-form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3105 (t 'function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3106 advised-arglist
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3107 (ad-make-advised-definition-docstring function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3108 interactive-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3109 orig-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3110 (ad-get-enabled-advices function 'before)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3111 (ad-get-enabled-advices function 'around)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3112 (ad-get-enabled-advices function 'after)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3113
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3114 (defun ad-assemble-advised-definition
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3115 (type args docstring interactive orig &optional befores arounds afters)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3116
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3117 "Assembles an original and its advices into an advised function.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3118 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
3119 be either `macro', `function' or `special-form'. ARGS is the argument list
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3120 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
3121 definition, INTERACTIVE if non-nil is the interactive form to be used,
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3122 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
3123 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
3124 should be modified. The assembled function will be returned."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3125
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3126 (let (before-forms around-form around-form-protected after-forms definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3127 (ad-dolist (advice befores)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3128 (cond ((and (ad-advice-protected advice)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3129 before-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3130 (setq before-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3131 `((unwind-protect
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3132 ,(ad-prognify before-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3133 ,@(ad-body-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3134 (ad-advice-definition advice))))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3135 (t (setq before-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3136 (append before-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3137 (ad-body-forms (ad-advice-definition advice)))))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3138
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3139 (setq around-form `(setq ad-return-value ,orig))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3140 (ad-dolist (advice (reverse arounds))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3141 ;; 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
3142 ;; protect the complete around advice onion:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3143 (if (ad-advice-protected advice)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3144 (setq around-form-protected t))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3145 (setq around-form
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3146 (ad-substitute-tree
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3147 (function (lambda (form) (eq form 'ad-do-it)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3148 (function (lambda (form) around-form))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3149 (ad-prognify (ad-body-forms (ad-advice-definition advice))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3150
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3151 (setq after-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3152 (if (and around-form-protected before-forms)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3153 `((unwind-protect
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3154 ,(ad-prognify before-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3155 ,around-form))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3156 (append before-forms (list around-form))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3157 (ad-dolist (advice afters)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3158 (cond ((and (ad-advice-protected advice)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3159 after-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3160 (setq after-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3161 `((unwind-protect
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3162 ,(ad-prognify after-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3163 ,@(ad-body-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3164 (ad-advice-definition advice))))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3165 (t (setq after-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3166 (append after-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3167 (ad-body-forms (ad-advice-definition advice)))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3168
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3169 (setq definition
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3170 `(,@(if (memq type '(macro special-form)) '(macro))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3171 lambda
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3172 ,args
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3173 ,@(if docstring (list docstring))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3174 ,@(if interactive (list interactive))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3175 (let (ad-return-value)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3176 ,@after-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3177 ,(if (eq type 'special-form)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3178 '(list 'quote ad-return-value)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3179 'ad-return-value))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3180
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3181 (ad-insert-argument-access-forms definition args)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3182
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3183 ;; This is needed for activation/deactivation hooks:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3184 (defun ad-make-hook-form (function hook-name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3185 "Make hook-form from FUNCTION's advice bodies in class HOOK-NAME."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3186 (let ((hook-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3187 (mapcar (function (lambda (advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3188 (ad-body-forms (ad-advice-definition advice))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3189 (ad-get-enabled-advices function hook-name))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3190 (if hook-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3191 (ad-prognify (apply 'append hook-forms)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3192
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3193
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3194 ;; @@ Caching:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3195 ;; ===========
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3196 ;; Generating an advised definition of a function is moderately expensive,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3197 ;; 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
3198 ;; circumstances. Of course, it only makes sense to reuse a cached
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3199 ;; definition if the current advice and function definition state is the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3200 ;; same as it was at the time when the cached definition was generated.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3201 ;; 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
3202 ;; 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
3203 ;; makes it possible to preactivate advised functions, write the compiled
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3204 ;; advised definitions to a file and reuse them during the actual
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3205 ;; activation without having to risk that the resulting definition will be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3206 ;; incorrect, well, almost.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3207 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3208 ;; A cache id is a list with six elements:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3209 ;; 1) the list of names of enabled before advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3210 ;; 2) the list of names of enabled around advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3211 ;; 3) the list of names of enabled after advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3212 ;; 4) the type of the original function (macro, subr, etc.)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3213 ;; 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
3214 ;; arglist of the cached definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3215 ;; 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
3216 ;; interactive form of the cached definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3217 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3218 ;; Here's how a cache can get invalidated or be incorrect:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3219 ;; A) a piece of advice used in the cache gets redefined
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3220 ;; B) the current list of enabled advices is different from the ones used
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3221 ;; for the cache
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3222 ;; 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
3223 ;; macro, or a subr became a function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3224 ;; D) the arglist of the original function changed
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3225 ;; E) the interactive form of the original function changed
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3226 ;; F) a piece of advice used in the cache got redefined before the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3227 ;; defadvice with the cached definition got loaded: This is a PROBLEM!
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3228 ;;
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3229 ;; 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
3230 ;; which clears the cache in such a case, B is easily checked during
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3231 ;; verification at activation time.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3232 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3233 ;; 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
3234 ;; if one considers the case that the original function could be different
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3235 ;; from the one available at caching time (e.g., for forward advice of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3236 ;; 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
3237 ;; 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
3238 ;; 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
3239 ;; 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
3240 ;; arglist can be recovered at validation time from the cached definition),
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3241 ;; 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
3242 ;; was actually a function whose interactive form was not overridden by a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3243 ;; piece of advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3244 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3245 ;; 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
3246 ;; There is no way to avoid this without storing the complete advice definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3247 ;; in the cache-id which is not feasible.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3248 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3249 ;; 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
3250 ;; 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
3251 ;; the added efficiency. The validation itself is also pretty cheap, certainly
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3252 ;; a lot cheaper than reconstructing an advised definition.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3253
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3254 (defmacro ad-get-cache-definition (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3255 `(car (ad-get-advice-info-field ,function 'cache)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3256
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3257 (defmacro ad-get-cache-id (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3258 `(cdr (ad-get-advice-info-field ,function 'cache)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3259
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3260 (defmacro ad-set-cache (function definition id)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3261 `(ad-set-advice-info-field
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3262 ,function 'cache (cons ,definition ,id)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3263
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3264 (defun ad-clear-cache (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3265 "Clears a previously cached advised definition of FUNCTION.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3266 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
3267 advised definition from scratch."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3268 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3269 (list (ad-read-advised-function "Clear cached definition of")))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3270 (ad-set-advice-info-field function 'cache nil))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3271
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3272 (defun ad-make-cache-id (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3273 "Generate an identifying image of the current advices of FUNCTION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3274 (let ((original-definition (ad-real-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3275 (cached-definition (ad-get-cache-definition function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3276 (list (mapcar (function (lambda (advice) (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3277 (ad-get-enabled-advices function 'before))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3278 (mapcar (function (lambda (advice) (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3279 (ad-get-enabled-advices function 'around))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3280 (mapcar (function (lambda (advice) (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3281 (ad-get-enabled-advices function 'after))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3282 (ad-definition-type original-definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3283 (if (equal (ad-arglist original-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3284 (ad-arglist cached-definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3285 t
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3286 (ad-arglist original-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3287 (if (eq (ad-definition-type original-definition) 'function)
82146
5868631b2e87 (ad-interactive-p, ad-interactive-form): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82140
diff changeset
3288 (equal (interactive-form original-definition)
5868631b2e87 (ad-interactive-p, ad-interactive-form): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82140
diff changeset
3289 (interactive-form cached-definition))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3290
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3291 (defun ad-get-cache-class-id (function class)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3292 "Return the part of FUNCTION's cache id that identifies CLASS."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3293 (let ((cache-id (ad-get-cache-id function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3294 (if (eq class 'before)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3295 (car cache-id)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3296 (if (eq class 'around)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3297 (nth 1 cache-id)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3298 (nth 2 cache-id)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3299
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3300 (defun ad-verify-cache-class-id (cache-class-id advices)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3301 (ad-dolist (advice advices (null cache-class-id))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3302 (if (ad-advice-enabled advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3303 (if (eq (car cache-class-id) (ad-advice-name advice))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3304 (setq cache-class-id (cdr cache-class-id))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3305 (ad-do-return nil)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3306
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3307 ;; 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
3308 ;; 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
3309 ;; 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
3310 ;; `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
3311 ;; verification failed. Tracing `ad-verify-cache-class-id' might provide
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3312 ;; some additional useful information.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3313
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3314 (defun ad-cache-id-verification-code (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3315 (let ((cache-id (ad-get-cache-id function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3316 (code 'before-advice-mismatch))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3317 (and (ad-verify-cache-class-id
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3318 (car cache-id) (ad-get-advice-info-field function 'before))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3319 (setq code 'around-advice-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3320 (ad-verify-cache-class-id
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3321 (nth 1 cache-id) (ad-get-advice-info-field function 'around))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3322 (setq code 'after-advice-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3323 (ad-verify-cache-class-id
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3324 (nth 2 cache-id) (ad-get-advice-info-field function 'after))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3325 (setq code 'definition-type-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3326 (let ((original-definition (ad-real-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3327 (cached-definition (ad-get-cache-definition function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3328 (and (eq (nth 3 cache-id) (ad-definition-type original-definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3329 (setq code 'arglist-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3330 (equal (if (eq (nth 4 cache-id) t)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3331 (ad-arglist original-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3332 (nth 4 cache-id) )
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3333 (ad-arglist cached-definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3334 (setq code 'interactive-form-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3335 (or (null (nth 5 cache-id))
82146
5868631b2e87 (ad-interactive-p, ad-interactive-form): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82140
diff changeset
3336 (equal (interactive-form original-definition)
5868631b2e87 (ad-interactive-p, ad-interactive-form): Remove.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 82140
diff changeset
3337 (interactive-form cached-definition)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3338 (setq code 'verified))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3339 code))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3340
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3341 (defun ad-verify-cache-id (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3342 "True if FUNCTION's cache-id is compatible with its current advices."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3343 (eq (ad-cache-id-verification-code function) 'verified))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3344
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3345
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3346 ;; @@ Preactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3347 ;; =================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3348 ;; Preactivation can be used to generate compiled advised definitions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3349 ;; 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
3350 ;; of the advice mechanism. Preactivation is a special feature of `defadvice',
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3351 ;; it involves the following steps:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3352 ;; - remembering the function's current state (definition and advice-info)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3353 ;; - advising it with the defined piece of advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3354 ;; - clearing its cache
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3355 ;; - generating an interpreted advised definition by activating it, this will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3356 ;; make use of all its current active advice and its current definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3357 ;; - saving the so generated cached definition and id
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3358 ;; - resetting the function's advice and definition state to what it was
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3359 ;; before the preactivation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3360 ;; - 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
3361 ;; `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
3362 ;; at time the `defadvice' gets compiled.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3363 ;; Naturally, for preactivation to be effective it has to be applied/compiled
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3364 ;; 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
3365 ;; definition exactly reflects the state at activation time. Should that not
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3366 ;; be the case, the precompiled definition will just be discarded and a new
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3367 ;; advised definition will be generated.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3368
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3369 (defun ad-preactivate-advice (function advice class position)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3370 "Preactivate FUNCTION and returns the constructed cache."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3371 (let* ((function-defined-p (fboundp function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3372 (old-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3373 (if function-defined-p
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3374 (symbol-function function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3375 (old-advice-info (ad-copy-advice-info function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3376 (ad-advised-functions ad-advised-functions))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3377 (unwind-protect
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3378 (progn
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3379 (ad-add-advice function advice class position)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3380 (ad-enable-advice function class (ad-advice-name advice))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3381 (ad-clear-cache function)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3382 (ad-activate function -1)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3383 (if (and (ad-is-active function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3384 (ad-get-cache-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3385 (list (ad-get-cache-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3386 (ad-get-cache-id function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3387 (ad-set-advice-info function old-advice-info)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3388 ;; Don't `fset' function to nil if it was previously unbound:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3389 (if function-defined-p
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3390 (ad-safe-fset function old-definition)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3391 (fmakunbound function)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3392
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3393
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3394 ;; @@ Freezing:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3395 ;; ============
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3396 ;; 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
3397 ;; 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
3398 ;; 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
3399 ;; 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
3400 ;; 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
3401 ;; cannot be undone.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3402
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3403 ;; 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
3404 ;; 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
3405 ;; 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
3406 ;; 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
3407 ;; 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
3408 ;; 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
3409 ;; 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
3410
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3411 ;; 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
3412 ;; 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
3413 ;; 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
3414 ;; incomprehensible pretty quickly.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3415
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3416 (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
3417 (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
3418 (error
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3419 "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
3420 function))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3421 (let* ((name (ad-advice-name advice))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3422 ;; 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
3423 ;; 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
3424 (unique-origname
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3425 (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
3426 (orig-definition
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3427 ;; 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
3428 ;; 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
3429 (or (ad-get-orig-definition function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3430 (symbol-function function)))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3431 (old-advice-info
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3432 (if (ad-is-advised function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3433 (ad-copy-advice-info function)))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3434 (real-docstring-fn
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3435 (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
3436 (real-origname-fn
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3437 (symbol-function 'ad-make-origname))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3438 (frozen-definition
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3439 (unwind-protect
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3440 (progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3441 ;; Make sure we construct a proper docstring:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3442 (ad-safe-fset 'ad-make-advised-definition-docstring
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3443 'ad-make-freeze-docstring)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3444 ;; 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
3445 (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
3446 ;; 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
3447 ;; generate an advised definition that's solely determined
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3448 ;; by ADVICE and the current origdef of FUNCTION:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3449 (ad-set-advice-info function nil)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3450 (ad-add-advice function advice class position)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3451 ;; The following will provide proper real docstrings as
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3452 ;; 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
3453 (ad-set-orig-definition function orig-definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3454 (ad-make-advised-definition function))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3455 ;; Restore the old advice state:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3456 (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
3457 ;; Restore functions:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3458 (ad-safe-fset
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3459 '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
3460 (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
3461 (if frozen-definition
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3462 (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
3463 (body (cdr (if macro-p
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3464 (ad-lambdafy frozen-definition)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3465 frozen-definition))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3466 `(progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3467 (if (not (fboundp ',unique-origname))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3468 (fset ',unique-origname
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3469 ;; avoid infinite recursion in case the function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3470 ;; we want to freeze is already advised:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3471 (or (ad-get-orig-definition ',function)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3472 (symbol-function ',function))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3473 (,(if macro-p 'defmacro 'defun)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3474 ,function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3475 ,@body))))))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3476
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3477
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3478 ;; @@ Activation and definition handling:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3479 ;; ======================================
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3480
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3481 (defun ad-should-compile (function compile)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3482 "Return non-nil if the advised FUNCTION should be compiled.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3483 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
3484 If COMPILE is a negative number then it returns nil.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3485 If COMPILE is nil then the result depends on the value of
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3486 `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
3487 (if (integerp compile)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3488 (>= compile 0)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3489 (if compile
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3490 compile
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3491 (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
3492 nil)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3493 ((eq ad-default-compilation-action 'always)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3494 t)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3495 ((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
3496 (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
3497 (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
3498 ;; everything else means `maybe':
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3499 (t (featurep 'byte-compile))))))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3500
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3501 (defun ad-activate-advised-definition (function compile)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3502 "Redefine FUNCTION with its advised definition from cache or scratch.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3503 The resulting FUNCTION will be compiled if `ad-should-compile' returns t.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3504 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
3505 (let ((verified-cached-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3506 (if (ad-verify-cache-id function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3507 (ad-get-cache-definition function))))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3508 (ad-safe-fset function
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3509 (or verified-cached-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3510 (ad-make-advised-definition function)))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3511 (if (ad-should-compile function compile)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3512 (ad-compile-function function))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3513 (if verified-cached-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3514 (if (not (eq verified-cached-definition (symbol-function function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3515 ;; we must have compiled, cache the compiled definition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3516 (ad-set-cache
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3517 function (symbol-function function) (ad-get-cache-id function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3518 ;; We created a new advised definition, cache it with a proper id:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3519 (ad-clear-cache function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3520 ;; ad-make-cache-id needs the new cached definition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3521 (ad-set-cache function (symbol-function function) nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3522 (ad-set-cache
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3523 function (symbol-function function) (ad-make-cache-id function)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3524
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3525 (defun ad-handle-definition (function)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3526 "Handle re/definition of an advised FUNCTION during de/activation.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3527 If FUNCTION does not have an original definition associated with it and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3528 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
3529 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
3530 case of undefinition) nothing will be done. In the case of redefinition
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3531 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
3532 see). Redefinition occurs when FUNCTION already has an original definition
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3533 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
3534 de/activated. If you do not like the current redefinition action change
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3535 the value of `ad-redefinition-action' and de/activate again."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3536 (let ((original-definition (ad-get-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3537 (current-definition (if (ad-real-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3538 (symbol-function function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3539 (if original-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3540 (if current-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3541 (if (and (not (eq current-definition original-definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3542 ;; Redefinition with an advised definition from a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3543 ;; different function won't count as such:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3544 (not (ad-advised-definition-p current-definition)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3545 ;; we have a redefinition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3546 (if (not (memq ad-redefinition-action '(accept discard warn)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3547 (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
3548 function "invalidly redefined")
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3549 (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
3550 (ad-safe-fset function original-definition)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3551 (ad-set-orig-definition function current-definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3552 (if (eq ad-redefinition-action 'warn)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3553 (message "ad-handle-definition: `%s' got redefined"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3554 function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3555 ;; either advised def or correct original is in place:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3556 nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3557 ;; we have an undefinition, ignore it:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3558 nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3559 (if current-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3560 ;; we have a first definition, save it as original:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3561 (ad-set-orig-definition function current-definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3562 ;; we don't have anything noteworthy:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3563 nil))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3564
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3565
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3566 ;; @@ The top-level advice interface:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3567 ;; ==================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3568
70899
b920ab84fba8 (ad-enable-advice, ad-activate, ad-disable-advice): Add autoloads.
Richard M. Stallman <rms@gnu.org>
parents: 68648
diff changeset
3569 ;;;###autoload
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3570 (defun ad-activate (function &optional compile)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3571 "Activate all the advice information of an advised FUNCTION.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3572 If FUNCTION has a proper original definition then an advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3573 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
3574 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
3575 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
3576 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
3577 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
3578 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
3579 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
3580 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
3581 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
3582 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
3583 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
3584 enabled is equivalent to a call to `ad-deactivate'. The current advised
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3585 definition will always be cached for later usage."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3586 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3587 (list (ad-read-advised-function "Activate advice of")
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3588 current-prefix-arg))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3589 (if ad-activate-on-top-level
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3590 ;; 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
3591 (ad-with-auto-activation-disabled
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3592 (if (not (ad-is-advised function))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3593 (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
3594 (ad-handle-definition function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3595 ;; 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
3596 (if (ad-get-orig-definition function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3597 (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
3598 (ad-unadvise function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3599 ;; Otherwise activate the advice:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3600 (cond ((ad-has-redefining-advice function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3601 (ad-activate-advised-definition function compile)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3602 (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
3603 (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
3604 function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3605 ;; 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
3606 (t (ad-deactivate function)))))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3607
26247
f96b2bc4ef08 (ad-activate-on): Make it an alias for ad-activate.
Gerd Moellmann <gerd@gnu.org>
parents: 26217
diff changeset
3608 (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
3609
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3610 (defun ad-deactivate (function)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3611 "Deactivate the advice of an actively advised FUNCTION.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3612 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
3613 definition of FUNCTION will be replaced with it. All the advice
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3614 information will still be available so it can be activated again with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3615 a call to `ad-activate'."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3616 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3617 (list (ad-read-advised-function "Deactivate advice of" 'ad-is-active)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3618 (if (not (ad-is-advised function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3619 (error "ad-deactivate: `%s' is not advised" function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3620 (cond ((ad-is-active function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3621 (ad-handle-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3622 (if (not (ad-get-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3623 (error "ad-deactivate: `%s' has no original definition"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3624 function)
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3625 (ad-safe-fset function (ad-get-orig-definition function))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3626 (ad-set-advice-info-field function 'active nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3627 (eval (ad-make-hook-form function 'deactivation))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3628 function)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3629
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3630 (defun ad-update (function &optional compile)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3631 "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
3632 See `ad-activate' for documentation on the optional COMPILE argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3633 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3634 (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
3635 "Update advised definition of" 'ad-is-active)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3636 (if (ad-is-active function)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3637 (ad-activate function compile)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3638
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3639 (defun ad-unadvise (function)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3640 "Deactivate FUNCTION and then remove all its advice information.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3641 If FUNCTION was not advised this will be a noop."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3642 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3643 (list (ad-read-advised-function "Unadvise function")))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3644 (cond ((ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3645 (if (ad-is-active function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3646 (ad-deactivate function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3647 (ad-clear-orig-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3648 (ad-set-advice-info function nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3649 (ad-pop-advised-function 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-recover (function)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3652 "Try to recover FUNCTION's original definition, and unadvise it.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3653 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
3654 deactivation, which might run hooks and get into other trouble.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3655 Use in emergencies."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3656 ;; Use more primitive interactive behavior here: Accept any symbol that's
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3657 ;; currently defined in obarray, not necessarily with a function definition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3658 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3659 (list (intern
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3660 (completing-read "Recover advised function: " obarray nil t))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3661 (cond ((ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3662 (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
3663 (ad-safe-fset function (ad-get-orig-definition function))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3664 (ad-clear-orig-definition function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3665 (ad-set-advice-info function nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3666 (ad-pop-advised-function function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3667
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3668 (defun ad-activate-regexp (regexp &optional compile)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3669 "Activate functions with an advice name containing a REGEXP match.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3670 This activates the advice for each function
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3671 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
3672 See `ad-activate' for documentation on the optional COMPILE argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3673 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3674 (list (ad-read-regexp "Activate via advice regexp")
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3675 current-prefix-arg))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3676 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3677 (if (ad-find-some-advice function 'any regexp)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3678 (ad-activate function compile))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3679
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3680 (defun ad-deactivate-regexp (regexp)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3681 "Deactivate functions with an advice name containing REGEXP match.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3682 This deactivates the advice for each function
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3683 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
3684 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3685 (list (ad-read-regexp "Deactivate via advice regexp")))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3686 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3687 (if (ad-find-some-advice function 'any regexp)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3688 (ad-deactivate function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3689
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3690 (defun ad-update-regexp (regexp &optional compile)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3691 "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
3692 This reactivates the advice for each function
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3693 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
3694 See `ad-activate' for documentation on the optional COMPILE argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3695 (interactive
65680
ed770a0a7846 2005-09-24 Emilio C. Lopes <eclig@gmx.net>
Romain Francoise <romain@orebokech.com>
parents: 64751
diff changeset
3696 (list (ad-read-regexp "Update via advice regexp")
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3697 current-prefix-arg))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3698 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3699 (if (ad-find-some-advice function 'any regexp)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3700 (ad-update function compile))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3701
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3702 (defun ad-activate-all (&optional compile)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3703 "Activate all currently advised functions.
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3704 See `ad-activate' for documentation on the optional COMPILE argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3705 (interactive "P")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3706 (ad-do-advised-functions (function)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3707 (ad-activate function compile)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3708
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3709 (defun ad-deactivate-all ()
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3710 "Deactivate all currently advised functions."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3711 (interactive)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3712 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3713 (ad-deactivate function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3714
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3715 (defun ad-update-all (&optional compile)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3716 "Update all currently advised functions.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3717 With prefix argument, COMPILE resulting advised definitions."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3718 (interactive "P")
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 (ad-update function compile)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3721
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3722 (defun ad-unadvise-all ()
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3723 "Unadvise all currently advised functions."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3724 (interactive)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3725 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3726 (ad-unadvise function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3727
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3728 (defun ad-recover-all ()
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3729 "Recover all currently advised functions. Use in emergencies.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3730 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
3731 definition, and delete all advice.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3732 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
3733 deactivation, which might run hooks and get into other trouble."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3734 (interactive)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3735 (ad-do-advised-functions (function)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3736 (condition-case nil
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3737 (ad-recover function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3738 (error nil))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3739
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3740
60923
08f8c7042636 * emacs-lisp/advice.el: Replace `legal' with `valid'.
Werner LEMBERG <wl@gnu.org>
parents: 57879
diff changeset
3741 ;; Completion alist of valid `defadvice' flags
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3742 (defvar ad-defadvice-flags
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3743 '(("protect") ("disable") ("activate")
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3744 ("compile") ("preactivate") ("freeze")))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3745
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3746 ;;;###autoload
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3747 (defmacro defadvice (function args &rest body)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3748 "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
3749 The syntax of `defadvice' is as follows:
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3750
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3751 \(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
3752 [DOCSTRING] [INTERACTIVE-FORM]
78150
3fcbdd7761c3 (defadvice): Doc fix.
Juanma Barranquero <lekktu@gmail.com>
parents: 75346
diff changeset
3753 BODY...)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3754
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3755 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
3756 CLASS ::= `before' | `around' | `after' | `activation' | `deactivation'.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3757 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
3758 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
3759 see also `ad-add-advice'.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3760 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
3761 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
3762 before/around/after-advices will be used.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3763 FLAG ::= `protect'|`disable'|`activate'|`compile'|`preactivate'|`freeze'.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3764 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
3765 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
3766 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
3767 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
3768 BODY ::= Any s-expression.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3769
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3770 Semantics of the various flags:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3771 `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
3772 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
3773 then automatically all around-advices will be protected (the complete onion).
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3774
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3775 `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
3776 FUNCTION has been properly defined prior to this application of `defadvice'.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3777
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3778 `compile': In conjunction with `activate' specifies that the resulting
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3779 advised function should be compiled.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3780
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3781 `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
3782 during activation until somebody enables it.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3783
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3784 `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
3785 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
3786 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
3787 this if the `defadvice' gets actually compiled.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3788
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3789 `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
3790 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
3791 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
3792 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
3793 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
3794 during preloading.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3795
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3796 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
3797 (declare (doc-string 3))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3798 (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
3799 (error "defadvice: Invalid function name: %s" function))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3800 (let* ((class (car args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3801 (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
3802 (error "defadvice: Invalid advice class: %s" class)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3803 (nth 1 args)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3804 (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
3805 (error "defadvice: Invalid advice name: %s" name)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3806 (setq args (nthcdr 2 args))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3807 (if (ad-position-p (car args))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3808 (prog1 (car args)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3809 (setq args (cdr args))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3810 (arglist (if (listp (car args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3811 (prog1 (car args)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3812 (setq args (cdr args)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3813 (flags
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3814 (mapcar
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3815 (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3816 (lambda (flag)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3817 (let ((completion
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3818 (try-completion (symbol-name flag) ad-defadvice-flags)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3819 (cond ((eq completion t) flag)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3820 ((assoc completion ad-defadvice-flags)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3821 (intern completion))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3822 (t (error "defadvice: Invalid or ambiguous flag: %s"
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3823 flag))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3824 args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3825 (advice (ad-make-advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3826 name (memq 'protect flags)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3827 (not (memq 'disable flags))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3828 `(advice lambda ,arglist ,@body)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3829 (preactivation (if (memq 'preactivate flags)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3830 (ad-preactivate-advice
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3831 function advice class position))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3832 ;; 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
3833 (if (memq 'freeze flags)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3834 ;; 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
3835 ;; 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
3836 (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
3837 ;; the normal case:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3838 `(progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3839 (ad-add-advice ',function ',advice ',class ',position)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3840 ,@(if preactivation
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3841 `((ad-set-cache
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3842 ',function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3843 ;; the function will get compiled:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3844 ,(cond ((ad-macro-p (car preactivation))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3845 `(ad-macrofy
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3846 (function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3847 ,(ad-lambdafy
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3848 (car preactivation)))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3849 (t `(function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3850 ,(car preactivation))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3851 ',(car (cdr preactivation)))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3852 ,@(if (memq 'activate flags)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3853 `((ad-activate ',function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3854 ,(if (memq 'compile flags) t))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3855 ',function))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3856
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3857
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3858 ;; @@ Tools:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3859 ;; =========
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3860
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3861 (defmacro ad-with-originals (functions &rest body)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3862 "Binds FUNCTIONS to their original definitions and execute BODY.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3863 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
3864 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
3865 undone on exit of this macro."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3866 (let* ((index -1)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3867 ;; Make let-variables to store current definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3868 (current-bindings
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3869 (mapcar (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3870 (lambda (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3871 (setq index (1+ index))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3872 (list (intern (format "ad-oRiGdEf-%d" index))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3873 `(symbol-function ',function))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3874 functions)))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3875 `(let ,current-bindings
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3876 (unwind-protect
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3877 (progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3878 ,@(progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3879 ;; Make forms to redefine functions to their
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3880 ;; original definitions if they are advised:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3881 (setq index -1)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3882 (mapcar
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3883 (function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3884 (lambda (function)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3885 (setq index (1+ index))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3886 `(ad-safe-fset
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3887 ',function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3888 (or (ad-get-orig-definition ',function)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3889 ,(car (nth index current-bindings))))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3890 functions))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3891 ,@body)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3892 ,@(progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3893 ;; 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
3894 ;; they had outside this macro call:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3895 (setq index -1)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3896 (mapcar
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3897 (function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3898 (lambda (function)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3899 (setq index (1+ index))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3900 `(ad-safe-fset
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3901 ',function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3902 ,(car (nth index current-bindings)))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3903 functions))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3904
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3905 (if (not (get 'ad-with-originals 'lisp-indent-hook))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3906 (put 'ad-with-originals 'lisp-indent-hook 1))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3907
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3908
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3909 ;; @@ Advising `documentation':
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3910 ;; ============================
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3911 ;; 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
3912 ;; generate proper documentation strings for advised definitions:
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3913
45019
c726a3eeeb0f (documentation): Add ad-define-subr-args call.
Richard M. Stallman <rms@gnu.org>
parents: 41936
diff changeset
3914 ;; 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
3915 ;; during bootstrapping.
c726a3eeeb0f (documentation): Add ad-define-subr-args call.
Richard M. Stallman <rms@gnu.org>
parents: 41936
diff changeset
3916 (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
3917
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3918 (defadvice documentation (after ad-advised-docstring first disable preact)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3919 "Builds an advised docstring if FUNCTION is advised."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3920 ;; Because we get the function name from the advised docstring
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3921 ;; this will work for function names as well as for definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3922 (if (and (stringp ad-return-value)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3923 (string-match
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3924 ad-advised-definition-docstring-regexp ad-return-value))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3925 (let ((function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3926 (car (read-from-string
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3927 ad-return-value (match-beginning 1) (match-end 1)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3928 (cond ((ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3929 (setq ad-return-value (ad-make-advised-docstring function))
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3930 ;; Handle optional `raw' argument:
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3931 (if (not (ad-get-arg 1))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3932 (setq ad-return-value
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3933 (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
3934
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3935
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3936 ;; @@ Starting, stopping and recovering from the advice package magic:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3937 ;; ===================================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3938
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3939 (defun ad-start-advice ()
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3940 "Start the automatic advice handling magic."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3941 (interactive)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3942 ;; Advising `ad-activate-internal' means death!!
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3943 (ad-set-advice-info 'ad-activate-internal nil)
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3944 (ad-safe-fset 'ad-activate-internal 'ad-activate)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3945 (ad-enable-advice 'documentation 'after 'ad-advised-docstring)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3946 (ad-activate 'documentation 'compile))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3947
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3948 (defun ad-stop-advice ()
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3949 "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
3950 You should only need this in case of Advice-related emergencies."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3951 (interactive)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3952 ;; Advising `ad-activate-internal' means death!!
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3953 (ad-set-advice-info 'ad-activate-internal nil)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3954 (ad-disable-advice 'documentation 'after 'ad-advised-docstring)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3955 (ad-update 'documentation)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3956 (ad-safe-fset 'ad-activate-internal 'ad-activate-internal-off))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3957
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3958 (defun ad-recover-normality ()
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3959 "Undo all advice related redefinitions and unadvises everything.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3960 Use only in REAL emergencies."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3961 (interactive)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3962 ;; Advising `ad-activate-internal' means death!!
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3963 (ad-set-advice-info 'ad-activate-internal nil)
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3964 (ad-safe-fset 'ad-activate-internal 'ad-activate-internal-off)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3965 (ad-recover-all)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3966 (setq ad-advised-functions nil))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3967
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3968 (ad-start-advice)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3969
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3970 (provide 'advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3971
66398
df04170ba46b (ad-make-advised-definition): Fix arg-order.
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 65680
diff changeset
3972 ;; arch-tag: 29f8c9a1-8c88-471f-95d7-e28541c6b7c0
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3973 ;;; advice.el ends here