annotate lisp/emacs-lisp/advice.el @ 53879:e3771c262410

New file. Move original fringe related declarations and code from dispextern.h and xdisp.c here. Rework code to support user defined fringe bitmaps, redefining standard bitmaps, ability to overlay user defined bitmap with overlay arrow bitmap, and add faces to bitmaps. (Voverflow_newline_into_fringe): Declare here. (enum fringe_bitmap_align): New enum. (..._bits): All bitmaps are now defined without bitswapping; that is now done in init_fringe_once (if necessary). (standard_bitmaps): New array with specifications for the standard fringe bitmaps. (fringe_faces): New array. (valid_fringe_bitmap_id_p): New function. (draw_fringe_bitmap_1): Rename from draw_fringe_bitmap. (draw_fringe_bitmap): New function which draws fringe bitmap, possibly overlaying bitmap with cursor in right fringe or the overlay arrow in the left fringe. (update_window_fringes): Do not handle overlay arrow here. Compare and copy fringe bitmap faces. (init_fringe_bitmap): New function. (Fdefine_fringe_bitmap, Fdestroy_fringe_bitmap): New DEFUNs to define and destroy user defined fringe bitmaps. (Fset_fringe_bitmap_face): New DEFUN to set face for a fringe bitmap. (Ffringe_bitmaps_at_pos): New DEFUN to read current fringe bitmaps. (syms_of_fringe): New function. Defsubr new DEFUNs. DEFVAR_LISP Voverflow_newline_into_fringe. (init_fringe_once, init_fringe): New functions. (w32_init_fringe, w32_reset_fringes) [WINDOWS_NT]: New functions.
author Kim F. Storm <storm@cua.dk>
date Sun, 08 Feb 2004 23:18:16 +0000
parents 695cf19ef79e
children d8586f19729a 375f2633d815
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
37056
543952c0704a (ad-make-advised-definition): Call
Gerd Moellmann <gerd@gnu.org>
parents: 33665
diff changeset
3 ;; Copyright (C) 1993,1994,2000, 2001 Free Software Foundation, Inc.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
4
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
5 ;; Author: Hans Chalupsky <hans@cs.buffalo.edu>
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
6 ;; Maintainer: FSF
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
7 ;; Created: 12 Dec 1992
5140
9cde7d7fea1f Comment change.
Richard M. Stallman <rms@gnu.org>
parents: 5138
diff changeset
8 ;; Keywords: extensions, lisp, tools
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
9
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
10 ;; This file is part of GNU Emacs.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
11
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
12 ;; GNU Emacs is free software; you can redistribute it and/or modify
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
13 ;; it under the terms of the GNU General Public License as published by
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
14 ;; the Free Software Foundation; either version 2, or (at your option)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
15 ;; any later version.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
16
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
17 ;; GNU Emacs is distributed in the hope that it will be useful,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
20 ;; GNU General Public License for more details.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
21
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
22 ;; 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
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
83f275dcd93a Update FSF's address.
Erik Naggum <erik@naggum.no>
parents: 11035
diff changeset
24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
83f275dcd93a Update FSF's address.
Erik Naggum <erik@naggum.no>
parents: 11035
diff changeset
25 ;; Boston, MA 02111-1307, USA.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
26
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
27 ;; LCD Archive Entry:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
28 ;; 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
29 ;; 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
30 ;; 1994/08/05 03:42:04|2.14|~/packages/advice.el.Z|
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
31
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
32
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
33 ;;; Commentary:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
34
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
35 ;; 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
36 ;; 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
37 ;; supported by this version of Advice.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
38
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
39 ;; 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
40
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
41 ;; @ Introduction:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
42 ;; ===============
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
43 ;; This package implements a full-fledged Lisp-style advice mechanism
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
44 ;; 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
45 ;; behavior of Emacs Lisp functions without having to keep personal
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
46 ;; modified copies of such functions around. A great number of such
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
47 ;; modifications can be achieved by treating the original function as a
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
48 ;; black box and specifying a different execution environment for it
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
49 ;; 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
50 ;; hook that you can attach to any function/macro/subr.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
51
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
52 ;; @ Highlights:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
53 ;; =============
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
54 ;; - Clean definition of multiple, named before/around/after advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
55 ;; for functions, macros, subrs and special forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
56 ;; - Full control over the arguments an advised function will receive,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
57 ;; the binding environment in which it will be executed, as well as the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
58 ;; value it will return.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
59 ;; - Allows re/definition of interactive behavior for functions and subrs
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
60 ;; - Every piece of advice can have its documentation string which will be
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
61 ;; combined with the original documentation of the advised function at
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
62 ;; call-time of `documentation' for proper command-key substitution.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
63 ;; - The execution of every piece of advice can be protected against error
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
64 ;; and non-local exits in preceding code or advices.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
65 ;; - Simple argument access either by name, or, more portable but as
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
66 ;; efficient, via access macros
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
67 ;; - Allows the specification of a different argument list for the advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
68 ;; version of a function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
69 ;; - Advised functions can be byte-compiled either at file-compile time
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
70 ;; (see preactivation) or activation time.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
71 ;; - 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
72 ;; - Forward advice is possible, that is
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
73 ;; 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
74 ;; preload the file in which they are defined.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
75 ;; - Forward redefinition is possible because around advice can be used to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
76 ;; completely redefine a function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
77 ;; - A caching mechanism for advised definition provides for cheap deactivation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
78 ;; and reactivation of advised functions.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
79 ;; - Preactivation allows efficient construction and compilation of advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
80 ;; definitions at file compile time without giving up the flexibility of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
81 ;; the advice mechanism.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
82 ;; - En/disablement mechanism allows the use of different "views" of advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
83 ;; functions depending on what pieces of advice are currently en/disabled
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
84 ;; - Provides manipulation mechanisms for sets of advised functions via
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
85 ;; regular expressions that match advice names
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
86
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
87 ;; @ How to get Advice for Emacs-18:
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
88 ;; =================================
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
89 ;; `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
90 ;; 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
91 ;; 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
92 ;; 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
93
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
94 ;; @ Overview, or how to read this file:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
95 ;; =====================================
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
96 ;; 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
97 ;; 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
98 ;; 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
99 ;; 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
100 ;; 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
101 ;; this documentation (set `outline-regexp' to `";; @+"').
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
102 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
103 ;; The four major sections of this file are:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
104 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
105 ;; @ This initial information ...installation, customization etc.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
106 ;; @ Advice documentation: ...general documentation
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
107 ;; @ Foo games: An advice tutorial ...teaches about Advice by example
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
108 ;; @ Advice implementation: ...actual code, yeah!!
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
109 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
110 ;; 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
111 ;; directly in case `outline-mode' doesn't work for you.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
112
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
113 ;; @ Restrictions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
114 ;; ===============
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
115 ;; - 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
116 ;; 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
117 ;; yet available in Lucid Emacs, hence, it won't work there.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
118 ;; - Advised functions/macros/subrs will only exhibit their advised behavior
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
119 ;; when they are invoked via their function cell. This means that advice will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
120 ;; not work for the following:
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
121 ;; + advised subrs that are called directly from other subrs or C-code
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
122 ;; + advised subrs that got replaced with their byte-code during
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
123 ;; byte-compilation (e.g., car)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
124 ;; + advised macros which were expanded during byte-compilation before
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
125 ;; their advice was activated.
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
126
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
127 ;; @ Credits:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
128 ;; ==========
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
129 ;; This package is an extension and generalization of packages such as
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
130 ;; insert-hooks.el written by Noah S. Friedman, and advise.el written by
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
131 ;; Raul J. Acevedo. Some ideas used in here come from these packages,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
132 ;; others come from the various Lisp advice mechanisms I've come across
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
133 ;; so far, and a few are simply mine.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
134
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
135 ;; @ Comments, suggestions, bug reports:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
136 ;; =====================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
137 ;; If you find any bugs, have suggestions for new advice features, find the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
138 ;; 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
139 ;; have any questions about Advice, or have otherwise enlightening
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
140 ;; comments feel free to send me email at <hans@cs.buffalo.edu>.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
141
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
142 ;; @ Safety Rules and Emergency Exits:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
143 ;; ===================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
144 ;; Before we begin: CAUTION!!
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
145 ;; 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
146 ;; 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
147 ;; 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
148 ;; (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
149 ;; 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
150 ;; 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
151 ;; 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
152 ;;
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
153 ;; 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
154 ;; Advice or to some ill-advised function do one of the following:
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
155
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
156 ;; - M-x ad-deactivate FUNCTION (if you have a definite suspicion what
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
157 ;; function gives you problems)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
158 ;; - 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
159 ;; - 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
160 ;; advised functions used by Advice itself)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
161 ;; - 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
162 ;; - 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
163 ;; terminal, kill your Emacs process and send me some hate mail.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
164
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
165 ;; The first three measures have restarts, i.e., once you've figured out
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
166 ;; the problem you can reactivate advised functions with either `ad-activate',
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
167 ;; `ad-activate-all', or `ad-start-advice'. `ad-recover-normality' unadvises
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
168 ;; 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
169 ;; have to stick with their standard incarnations for the rest of the session.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
170
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
171 ;; IMPORTANT: With Advice loaded always do `M-x ad-deactivate-all' before
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
172 ;; you byte-compile a file, because advised special forms and macros can lead
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
173 ;; to unwanted compilation results. When you are done compiling use
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
174 ;; `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
175 ;; advised functions.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
176
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
177 ;; 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
178 ;; 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
179 ;; time. Just wanted you to be warned.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
180
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
181 ;; @ Customization:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
182 ;; ================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
183
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
184 ;; Look at the documentation of `ad-redefinition-action' for possible values
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
185 ;; of this variable. Its default value is `warn' which will print a warning
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
186 ;; message when an already defined advised function gets redefined with a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
187 ;; new original definition and de/activated.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
188
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
189 ;; 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
190 ;; 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
191 ;; 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
192 ;; 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
193
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
194 ;; @ Motivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
195 ;; =============
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
196 ;; Before I go on explaining how advice works, here are four simple examples
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
197 ;; 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
198 ;; is just a joke:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
199
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
200 ;;(defadvice switch-to-buffer (before existing-buffers-only activate)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
201 ;; "When called interactively switch to existing buffers only, unless
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
202 ;;when called with a prefix argument."
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
203 ;; (interactive
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
204 ;; (list (read-buffer "Switch to buffer: " (other-buffer)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
205 ;; (null current-prefix-arg)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
206 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
207 ;;(defadvice switch-to-buffer (around confirm-non-existing-buffers activate)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
208 ;; "Switch to non-existing buffers only upon confirmation."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
209 ;; (interactive "BSwitch to buffer: ")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
210 ;; (if (or (get-buffer (ad-get-arg 0))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
211 ;; (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
212 ;; ad-do-it))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
213 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
214 ;;(defadvice find-file (before existing-files-only activate)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
215 ;; "Find existing files only"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
216 ;; (interactive "fFind file: "))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
217 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
218 ;;(defadvice car (around interactive activate)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
219 ;; "Make `car' an interactive function."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
220 ;; (interactive "xCar of list: ")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
221 ;; ad-do-it
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
222 ;; (if (interactive-p)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
223 ;; (message "%s" ad-return-value)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
224
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
225
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
226 ;; @ Advice documentation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
227 ;; =======================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
228 ;; Below is general documentation of the various features of advice. For more
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
229 ;; concrete examples check the corresponding sections in the tutorial part.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
230
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
231 ;; @@ Terminology:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
232 ;; ===============
24875
7177532e6e8b Comment fix.
Karl Heuer <kwzh@gnu.org>
parents: 23946
diff changeset
233 ;; - Emacs, Emacs-19: Emacs as released by the GNU Project
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
234 ;; - Lemacs: Lucid's version of Emacs with major version 19
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
235 ;; - 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
236 ;; (such as Epoch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
237 ;; - v19: Any Emacs with major version 19
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
238 ;; - jwz: Jamie Zawinski - former keeper of Lemacs and creator of the optimizing
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
239 ;; byte-compiler used in v19s.
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
240 ;; - Advice: The name of this package.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
241 ;; - advices: Short for "pieces of advice".
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
242
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
243 ;; @@ Defining a piece of advice with `defadvice':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
244 ;; ===============================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
245 ;; The main means of defining a piece of advice is the macro `defadvice',
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
246 ;; 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
247 ;; `defadvice' has the following syntax which is similar to the syntax of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
248 ;; `defun/defmacro':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
249 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
250 ;; (defadvice <function> (<class> <name> [<position>] [<arglist>] {<flags>}*)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
251 ;; [ [<documentation-string>] [<interactive-form>] ]
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
252 ;; {<body-form>}* )
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
253
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
254 ;; <function> is the name of the function/macro/subr to be advised.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
255
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
256 ;; <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
257 ;; `around', `after', `activation' or `deactivation' (the last two allow
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
258 ;; definition of special act/deactivation hooks).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
259
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
260 ;; <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
261 ;; Names uniquely identify a piece of advice in a certain advice class,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
262 ;; hence, advices can be redefined by defining an advice with the same class
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
263 ;; and name. Advice names are global symbols, hence, the same name space
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
264 ;; conventions used for function names should be applied.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
265
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
266 ;; An optional <position> specifies where in the current list of advices of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
267 ;; the specified <class> this new advice will be placed. <position> has to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
268 ;; be either `first', `last' or a number that specifies a zero-based
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
269 ;; position (`first' is equivalent to 0). If no position is specified
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
270 ;; `first' will be used as a default. If this call to `defadvice' redefines
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
271 ;; an already existing advice (see above) then the position argument will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
272 ;; be ignored and the position of the already existing advice will be used.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
273
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
274 ;; 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
275 ;; argument list of the advised function. This argument list should of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
276 ;; course be compatible with the argument list of the original function,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
277 ;; otherwise functions that call the advised function with the original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
278 ;; argument list in mind will break. If more than one advice specify an
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
279 ;; argument list then the first one (the one with the smallest position)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
280 ;; found in the list of before/around/after advices will be used.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
281
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
282 ;; <flags> is a list of symbols that specify further information about the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
283 ;; advice. All flags can be specified with unambiguous initial substrings.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
284 ;; `activate': Specifies that the advice information of the advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
285 ;; function should be activated right after this advice has been
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
286 ;; defined. In forward advices `activate' will be ignored.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
287 ;; `protect': Specifies that this advice should be protected against
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
288 ;; non-local exits and errors in preceding code/advices.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
289 ;; `compile': Specifies that the advised function should be byte-compiled.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
290 ;; This flag will be ignored unless `activate' is also specified.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
291 ;; `disable': Specifies that the defined advice should be disabled, hence,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
292 ;; it will not be used in an activation until somebody enables it.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
293 ;; `preactivate': Specifies that the advised function should get preactivated
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
294 ;; at macro-expansion/compile time of this `defadvice'. This
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
295 ;; generates a compiled advised definition according to the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
296 ;; current advice state which will be used during activation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
297 ;; if appropriate. Only use this if the `defadvice' gets
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
298 ;; actually compiled (with a v18 byte-compiler put the `defadvice'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
299 ;; into the body of a `defun' to accomplish proper compilation).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
300
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
301 ;; An optional <documentation-string> can be supplied to document the advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
302 ;; On call of the `documentation' function it will be combined with the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
303 ;; documentation strings of the original function and other advices.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
304
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
305 ;; An optional <interactive-form> form can be supplied to change/add
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
306 ;; interactive behavior of the original function. If more than one advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
307 ;; has an `(interactive ...)' specification then the first one (the one
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
308 ;; with the smallest position) found in the list of before/around/after
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
309 ;; advices will be used.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
310
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
311 ;; 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
312 ;; 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
313 ;; the return value, the binding environment, and can have all sorts of
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
314 ;; other side effects.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
315
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
316 ;; @@ Assembling advised definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
317 ;; ==================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
318 ;; Suppose a function/macro/subr/special-form has N pieces of before advice,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
319 ;; 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
320 ;; the advices is protected, its advised definition will look like this
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
321 ;; (body-form indices correspond to the position of the respective advice in
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
322 ;; that advice class):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
323
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
324 ;; ([macro] lambda <arglist>
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
325 ;; [ [<advised-docstring>] [(interactive ...)] ]
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
326 ;; (let (ad-return-value)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
327 ;; {<before-0-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
328 ;; ....
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
329 ;; {<before-N-1-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
330 ;; {<around-0-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
331 ;; {<around-1-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
332 ;; ....
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
333 ;; {<around-M-1-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
334 ;; (setq ad-return-value
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
335 ;; <apply original definition to <arglist>>)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
336 ;; {<other-around-M-1-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
337 ;; ....
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
338 ;; {<other-around-1-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
339 ;; {<other-around-0-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
340 ;; {<after-0-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
341 ;; ....
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
342 ;; {<after-K-1-body-form>}*
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
343 ;; ad-return-value))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
344
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
345 ;; Macros and special forms will be redefined as macros, hence the optional
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
346 ;; [macro] in the beginning of the definition.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
347
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
348 ;; <arglist> is either the argument list of the original function or the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
349 ;; first argument list defined in the list of before/around/after advices.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
350 ;; The values of <arglist> variables can be accessed/changed in the body of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
351 ;; an advice by simply referring to them by their original name, however,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
352 ;; more portable argument access macros are also provided (see below). For
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
353 ;; subrs/special-forms for which neither explicit argument list definitions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
354 ;; are available, nor their documentation strings contain such definitions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
355 ;; (as they do v19s), `(&rest ad-subr-args)' will be used.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
356
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
357 ;; <advised-docstring> is an optional, special documentation string which will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
358 ;; be expanded into a proper documentation string upon call of `documentation'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
359
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
360 ;; (interactive ...) is an optional interactive form either taken from the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
361 ;; original function or from a before/around/after advice. For advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
362 ;; interactive subrs that do not have an interactive form specified in any
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
363 ;; advice we have to use (interactive) and then call the subr interactively
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
364 ;; if the advised function was called interactively, because the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
365 ;; interactive specification of subrs is not accessible. This is the only
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
366 ;; case where changing the values of arguments will not have an affect
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
367 ;; because they will be reset by the interactive specification of the subr.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
368 ;; 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
369 ;; before/around/after advice to gain control over argument values that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
370 ;; were supplied interactively.
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
371 ;;
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
372 ;; 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
373 ;; 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
374 ;; 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
375 ;; the forms of the wrapped or surrounded forms should go with the special
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
376 ;; keyword `ad-do-it', which will be substituted with a `progn' containing the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
377 ;; forms of the surrounded code.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
378
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
379 ;; The innermost part of the around advice onion is
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
380 ;; <apply original definition to <arglist>>
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
381 ;; whose form depends on the type of the original function. The variable
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
382 ;; `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
383 ;; 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
384 ;;
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
385 ;; The semantic structure of advised functions that contain protected pieces
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
386 ;; of advice is the same. The only difference is that `unwind-protect' forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
387 ;; make sure that the protected advice gets executed even if some previous
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
388 ;; 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
389 ;; protected then the whole around advice onion will be protected.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
390
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
391 ;; @@ Argument access in advised functions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
392 ;; ========================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
393 ;; As already mentioned, the simplest way to access the arguments of an
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
394 ;; 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
395 ;; do that, the advice programmer needs to know either the names of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
396 ;; argument variables of the original function, or the names used in the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
397 ;; argument list redefinition given in a piece of advice. While this simple
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
398 ;; method might be sufficient in many cases, it has the disadvantage that it
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
399 ;; is not very portable because it hardcodes the argument names into the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
400 ;; advice. If the definition of the original function changes the advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
401 ;; might break even though the code might still be correct. Situations like
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
402 ;; that arise, for example, if one advises a subr like `eval-region' which
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
403 ;; gets redefined in a non-advice style into a function by the edebug
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
404 ;; 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
405 ;; once edebug is loaded. Similar situations arise when one wants to use the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
406 ;; same piece of advice across different versions of Emacs. Some subrs in a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
407 ;; 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
408 ;; semantics remain the same, hence, the same piece of advice might be usable
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
409 ;; in both Emacs versions.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
410
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
411 ;; As a solution to that advice provides argument list access macros that get
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
412 ;; translated into the proper access forms at activation time, i.e., when the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
413 ;; advised definition gets constructed. Access macros access actual arguments
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
414 ;; by position regardless of how these actual argument get distributed onto
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
415 ;; the argument variables of a function. The rational behind this is that in
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
416 ;; Emacs Lisp the semantics of an argument is strictly determined by its
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
417 ;; position (there are no keyword arguments).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
418
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
419 ;; Suppose the function `foo' is defined as
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
420 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
421 ;; (defun foo (x y &optional z &rest r) ....)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
422 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
423 ;; and is then called with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
424 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
425 ;; (foo 0 1 2 3 4 5 6)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
426
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
427 ;; 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
428 ;; the semantics of an actual argument is determined by its position. It is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
429 ;; 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
430 ;; can access these arguments in a piece of advice with some of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
431 ;; following macros (the arrows indicate what value they will return):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
432
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
433 ;; (ad-get-arg 0) -> 0
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
434 ;; (ad-get-arg 1) -> 1
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
435 ;; (ad-get-arg 2) -> 2
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
436 ;; (ad-get-arg 3) -> 3
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
437 ;; (ad-get-args 2) -> (2 3 4 5 6)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
438 ;; (ad-get-args 4) -> (4 5 6)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
439
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
440 ;; `(ad-get-arg <position>)' will return the actual argument that was supplied
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
441 ;; at <position>, `(ad-get-args <position>)' will return the list of actual
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
442 ;; arguments supplied starting at <position>. Note that these macros can be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
443 ;; used without any knowledge about the form of the actual argument list of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
444 ;; the original function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
445
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
446 ;; Similarly, `(ad-set-arg <position> <value-form>)' can be used to set the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
447 ;; value of the actual argument at <position> to <value-form>. For example,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
448 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
449 ;; (ad-set-arg 5 "five")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
450 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
451 ;; 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
452 ;; called. `(ad-set-args <position> <value-list-form>)' can be used to set
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
453 ;; the list of actual arguments starting at <position> to <value-list-form>.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
454 ;; For example,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
455 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
456 ;; (ad-set-args 0 '(5 4 3 2 1 0))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
457 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
458 ;; 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
459 ;; function is called.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
460
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
461 ;; All these access macros are text macros rather than real Lisp macros. When
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
462 ;; the advised definition gets constructed they get replaced with actual access
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
463 ;; forms depending on the argument list of the advised function, i.e., after
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
464 ;; that argument access is in most cases as efficient as using the argument
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
465 ;; variable names directly.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
466
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
467 ;; @@@ Accessing argument bindings of arbitrary functions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
468 ;; =======================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
469 ;; Some functions (such as `trace-function' defined in trace.el) need a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
470 ;; method of accessing the names and bindings of the arguments of an
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
471 ;; arbitrary advised function. To do that within an advice one can use the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
472 ;; special keyword `ad-arg-bindings' which is a text macro that will be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
473 ;; substituted with a form that will evaluate to a list of binding
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
474 ;; specifications, one for every argument variable. These binding
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
475 ;; specifications can then be examined in the body of the advice. For
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
476 ;; example, somewhere in an advice we could do this:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
477 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
478 ;; (let* ((bindings ad-arg-bindings)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
479 ;; (firstarg (car bindings))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
480 ;; (secondarg (car (cdr bindings))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
481 ;; ;; Print info about first argument
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
482 ;; (print (format "%s=%s (%s)"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
483 ;; (ad-arg-binding-field firstarg 'name)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
484 ;; (ad-arg-binding-field firstarg 'value)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
485 ;; (ad-arg-binding-field firstarg 'type)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
486 ;; ....)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
487 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
488 ;; The `type' of an argument is either `required', `optional' or `rest'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
489 ;; Wherever `ad-arg-bindings' appears a form will be inserted that evaluates
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
490 ;; to the list of bindings, hence, in order to avoid multiple unnecessary
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
491 ;; evaluations one should always bind it to some variable.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
492
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
493 ;; @@@ Argument list mapping:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
494 ;; ==========================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
495 ;; Because `defadvice' allows the specification of the argument list of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
496 ;; advised function we need a mapping mechanism that maps this argument list
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
497 ;; onto that of the original function. For example, somebody might specify
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
498 ;; `(sym newdef)' as the argument list of `fset', while advice might use
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
499 ;; `(&rest ad-subr-args)' as the argument list of the original function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
500 ;; (depending on what Emacs version is used). Hence SYM and NEWDEF have to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
501 ;; 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
502 ;; called. Advice automatically takes care of that mapping, hence, the advice
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
503 ;; programmer can specify an argument list without having to know about the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
504 ;; exact structure of the original argument list as long as the new argument
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
505 ;; list takes a compatible number/magnitude of actual arguments.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
506
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
507 ;; @@@ Definition of subr argument lists:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
508 ;; ======================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
509 ;; When advice constructs the advised definition of a function it has to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
510 ;; know the argument list of the original function. For functions and macros
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
511 ;; the argument list can be determined from the actual definition, however,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
512 ;; 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
513 ;; 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
514 ;; its documentation string, in a v18 Emacs even that is not possible. If
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
515 ;; advice cannot at all determine the argument list of a subr it uses
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
516 ;; `(&rest ad-subr-args)' which will always work but is inefficient because
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
517 ;; 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
518 ;; the advice programmer to explicitly tell advice about the argument list
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
519 ;; of a certain subr, for example,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
520 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
521 ;; (ad-define-subr-args 'fset '(sym newdef))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
522 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
523 ;; 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
524 ;; The following can be used to undo such a definition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
525 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
526 ;; (ad-undefine-subr-args 'fset)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
527 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
528 ;; The argument list definition is stored on the property list of the subr
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
529 ;; name symbol. When an argument list could be determined from the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
530 ;; documentation string it will be cached under that property. The general
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
531 ;; mechanism for looking up the argument list of a subr is the following:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
532 ;; 1) look for a definition stored on the property list
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
533 ;; 2) if that failed try to infer it from the documentation string and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
534 ;; if successful cache it on the property list
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
535 ;; 3) otherwise use `(&rest ad-subr-args)'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
536
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
537 ;; @@ Activation and deactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
538 ;; ===============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
539 ;; The definition of an advised function does not change until all its advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
540 ;; gets actually activated. Activation can either happen with the `activate'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
541 ;; flag specified in the `defadvice', with an explicit call or interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
542 ;; invocation of `ad-activate', or if forward advice is enabled (i.e., the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
543 ;; 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
544 ;; function gets defined.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
545
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
546 ;; When a function gets first activated its original definition gets saved,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
547 ;; all defined and enabled pieces of advice will get combined with the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
548 ;; original definition, the resulting definition might get compiled depending
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
549 ;; on some conditions described below, and then the function will get
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
550 ;; redefined with the advised definition. This also means that undefined
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
551 ;; functions cannot get activated even though they might be already advised.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
552
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
553 ;; The advised definition will get compiled either if `ad-activate' was called
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
554 ;; 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
555 ;; 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
556 ;; to the current system state. If the advised definition was
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
557 ;; constructed during "preactivation" (see below) then that definition will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
558 ;; be already compiled because it was constructed during byte-compilation of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
559 ;; the file that contained the `defadvice' with the `preactivate' flag.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
560
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
561 ;; `ad-deactivate' can be used to back-define an advised function to its
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
562 ;; original definition. It can be called interactively or directly. Because
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
563 ;; `ad-activate' caches the advised definition the function can be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
564 ;; reactivated via `ad-activate' with only minor overhead (it is checked
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
565 ;; whether the current advice state is consistent with the cached
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
566 ;; definition, see the section on caching below).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
567
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
568 ;; `ad-activate-regexp' and `ad-deactivate-regexp' can be used to de/activate
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
569 ;; 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
570 ;; contains a match for a regular expression. These functions can be used to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
571 ;; de/activate sets of functions depending on certain advice naming
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
572 ;; conventions.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
573
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
574 ;; Finally, `ad-activate-all' and `ad-deactivate-all' can be used to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
575 ;; de/activate all currently advised functions. These are useful to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
576 ;; (temporarily) return to an un/advised state.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
577
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
578 ;; @@@ Reasons for the separation of advice definition and activation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
579 ;; ===================================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
580 ;; As already mentioned, advising happens in two stages:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
581
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
582 ;; 1) definition of various pieces of advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
583 ;; 2) activation of all advice currently defined and enabled
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
584
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
585 ;; The advantage of this is that various pieces of advice can be defined
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
586 ;; before they get combined into an advised definition which avoids
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
587 ;; unnecessary constructions of intermediate advised definitions. The more
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
588 ;; important advantage is that it allows the implementation of forward advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
589 ;; Advice information for a certain function accumulates as the value of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
590 ;; `advice-info' property of the function symbol. This accumulation is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
591 ;; completely independent of the fact that that function might not yet be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
592 ;; defined. The special forms `defun' and `defmacro' have been advised to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
593 ;; check whether the function/macro they defined had advice information
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
594 ;; associated with it. If so and forward advice is enabled, the original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
595 ;; definition will be saved, and then the advice will be activated. When a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
596 ;; 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
597 ;; defined with calls to `defun/defmacro'. Hence, we can forward advise
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
598 ;; functions/macros which will be defined later during a load/autoload of some
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
599 ;; 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
600 ;; this is slightly more complicated but the basic idea is the same).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
601
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
602 ;; @@ Enabling/disabling pieces or sets of advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
603 ;; ===============================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
604 ;; A major motivation for the development of this advice package was to bring
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
605 ;; a little bit more structure into the function overloading chaos in Emacs
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
606 ;; Lisp. Many packages achieve some of their functionality by adding a little
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
607 ;; bit (or a lot) to the standard functionality of some Emacs Lisp function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
608 ;; ange-ftp is a very popular package that achieves its magic by overloading
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
609 ;; most Emacs Lisp functions that deal with files. A popular function that's
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
610 ;; overloaded by many packages is `expand-file-name'. The situation that one
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
611 ;; function is multiply overloaded can arise easily.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
612
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
613 ;; 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
614 ;; overloads of a particular package while keeping all the rest. Ideally -
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
615 ;; at least in my opinion - these overloads would all be done with advice,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
616 ;; 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
617 ;; mechanism of advice could be used to achieve just that.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
618
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
619 ;; Every piece of advice is associated with an enablement flag. When the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
620 ;; advised definition of a particular function gets constructed (e.g., during
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
621 ;; activation) only the currently enabled pieces of advice will be considered.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
622 ;; This mechanism allows one to have different "views" of an advised function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
623 ;; dependent on what pieces of advice are currently enabled.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
624
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
625 ;; Another motivation for this mechanism is that it allows one to define a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
626 ;; piece of advice for some function yet keep it dormant until a certain
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
627 ;; condition is met. Until then activation of the function will not make use
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
628 ;; 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
629 ;; enabled and a reactivation of the function will add its functionality as
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
630 ;; part of the new advised definition. For example, the advices of `defun'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
631 ;; etc. used by advice itself will stay disabled until `ad-start-advice' is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
632 ;; called and some variables have the proper values. Hence, if somebody
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
633 ;; else advised these functions too and activates them the advices defined
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
634 ;; by advice will get used only if they are intended to be used.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
635
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
636 ;; The main interface to this mechanism are the interactive functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
637 ;; `ad-enable-advice' and `ad-disable-advice'. For example, the following
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
638 ;; would disable a particular advice of the function `foo':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
639 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
640 ;; (ad-disable-advice 'foo 'before 'my-advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
641 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
642 ;; 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
643 ;; the advised definition too one has to activate `foo' with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
644 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
645 ;; (ad-activate 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
646 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
647 ;; or interactively. To disable whole sets of advices one can use a regular
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
648 ;; expression mechanism. For example, let us assume that ange-ftp actually
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
649 ;; used advice to overload all its functions, and that it used the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
650 ;; "ange-ftp-" prefix for all its advice names, then we could temporarily
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
651 ;; disable all its advices with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
652 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
653 ;; (ad-disable-regexp "^ange-ftp-")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
654 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
655 ;; and the following call would put that actually into effect:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
656 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
657 ;; (ad-activate-regexp "^ange-ftp-")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
658 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
659 ;; A saver way would have been to use
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
660 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
661 ;; (ad-update-regexp "^ange-ftp-")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
662 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
663 ;; instead which would have only reactivated currently actively advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
664 ;; functions, but not functions that were currently deactivated. All these
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
665 ;; functions can also be called interactively.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
666
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
667 ;; 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
668 ;; match for the regular expression. To enable ange-ftp again we would use
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
669 ;; `ad-enable-regexp' and then activate or update again.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
670
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
671 ;; @@ Forward advice, automatic advice activation:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
672 ;; ===============================================
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
673 ;; Because most Emacs Lisp packages are loaded on demand via an autoload
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
674 ;; mechanism it is essential to be able to "forward advise" functions.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
675 ;; Otherwise, proper advice definition and activation would make it necessary
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
676 ;; to preload every file that defines a certain function before it can be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
677 ;; advised, which would partly defeat the purpose of the advice mechanism.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
678
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
679 ;; In the following, "forward advice" always implies its automatic activation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
680 ;; once a function gets defined, and not just the accumulation of advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
681 ;; information for a possibly undefined function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
682
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
683 ;; Advice implements forward advice mainly via the following: 1) Separation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
684 ;; of advice definition and activation that makes it possible to accumulate
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
685 ;; 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
686 ;; 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
687 ;; 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
688 ;; 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
689 ;; the function gets defined.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
690
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
691 ;; Automatic advice activation means, that whenever a function gets defined
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
692 ;; with either `defun', `defmacro', `fset' or by loading a byte-compiled
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
693 ;; file, and the function has some advice-info stored with it then that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
694 ;; advice will get activated right away.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
695
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
696 ;; @@@ Enabling automatic advice activation:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
697 ;; =========================================
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
698 ;; 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
699 ;; 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
700
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
701 ;; @@ Caching of advised definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
702 ;; ==================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
703 ;; After an advised definition got constructed it gets cached as part of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
704 ;; 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
705 ;; intermediate deactivation. Because the advice-info of a function might
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
706 ;; change between the time of caching and reuse a cached definition gets
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
707 ;; 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
708 ;; definition is still valid (the main application of this is preactivation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
709 ;; - see below).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
710
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
711 ;; When an advised function gets activated and a verifiable cached definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
712 ;; is available, then that definition will be used instead of creating a new
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
713 ;; advised definition from scratch. If you want to make sure that a new
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
714 ;; definition gets constructed then you should use `ad-clear-cache' before you
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
715 ;; activate the advised function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
716
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
717 ;; @@ Preactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
718 ;; =================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
719 ;; Constructing an advised definition is moderately expensive. In a situation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
720 ;; where one package defines a lot of advised functions it might be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
721 ;; prohibitively expensive to do all the advised definition construction at
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
722 ;; runtime. Preactivation is a mechanism that allows compile-time construction
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
723 ;; of compiled advised definitions that can be activated cheaply during
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
724 ;; runtime. Preactivation uses the caching mechanism to do that. Here's how it
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
725 ;; works:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
726
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
727 ;; When the byte-compiler compiles a `defadvice' that has the `preactivate'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
728 ;; flag specified, it uses the current original definition of the advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
729 ;; function plus the advice specified in this `defadvice' (even if it is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
730 ;; specified as disabled) and all other currently enabled pieces of advice to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
731 ;; construct an advised definition and an identifying cache-id and makes them
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
732 ;; part of the `defadvice' expansion which will then be compiled by the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
733 ;; 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
734 ;; `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
735 ;; that compiled `defun' in order to actually execute the `defadvice'). When
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
736 ;; the file with the compiled, preactivating `defadvice' gets loaded the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
737 ;; precompiled advised definition will be cached on the advised function's
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
738 ;; advice-info. When it gets activated (can be immediately on execution of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
739 ;; `defadvice' or any time later) the cache-id gets checked against the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
740 ;; current state of advice and if it is verified the precompiled definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
741 ;; 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
742 ;; verified a new advised definition for that function will be built from
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
743 ;; scratch, hence, the efficiency added by the preactivation mechanism does
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
744 ;; not at all impair the flexibility of the advice mechanism.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
745
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
746 ;; MORAL: In order get all the efficiency out of preactivation the advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
747 ;; state of an advised function at the time the file with the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
748 ;; preactivating `defadvice' gets byte-compiled should be exactly
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
749 ;; the same as it will be when the advice of that function gets
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
750 ;; actually activated. If it is not there is a high chance that the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
751 ;; cache-id will not match and hence a new advised definition will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
752 ;; have to be constructed at runtime.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
753
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
754 ;; Preactivation and forward advice do not contradict each other. It is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
755 ;; perfectly ok to load a file with a preactivating `defadvice' before the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
756 ;; original definition of the advised function is available. The constructed
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
757 ;; advised definition will be used once the original function gets defined and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
758 ;; its advice gets activated. The only constraint is that at the time the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
759 ;; file with the preactivating `defadvice' got compiled the original function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
760 ;; definition was available.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
761
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
762 ;; TIPS: Here are some indications that a preactivation did not work the way
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
763 ;; you intended it to work:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
764 ;; - Activation of the advised function takes longer than usual/expected
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
765 ;; - The byte-compiler gets loaded while an advised function gets
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
766 ;; activated
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
767 ;; - `byte-compile' is part of the `features' variable even though you
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
768 ;; did not use the byte-compiler
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
769 ;; Right now advice does not provide an elegant way to find out whether
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
770 ;; and why a preactivation failed. What you can do is to trace the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
771 ;; function `ad-cache-id-verification-code' (with the function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
772 ;; `trace-function-background' defined in my trace.el package) before
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
773 ;; any of your advised functions get activated. After they got
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
774 ;; activated check whether all calls to `ad-cache-id-verification-code'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
775 ;; returned `verified' as a result. Other values indicate why the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
776 ;; verification failed which should give you enough information to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
777 ;; fix your preactivation/compile/load/activation sequence.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
778
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
779 ;; 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
780 ;; preactivation fail, i.e., a preconstructed advised definition that does
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
781 ;; NOT match the current state of advice gets used nevertheless. That case
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
782 ;; 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
783 ;; during preactivation, and another package incompatibly redefines that
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
784 ;; 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
785 ;; that is available when the preconstructed definition gets activated, and
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
786 ;; 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
787 ;; catches advice redefinitions and clears the cache in such a case).
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
788 ;; Catching that would make the cache verification too expensive.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
789
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
790 ;; MORAL-II: Redefining somebody else's advice is BAAAAD (to speak with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
791 ;; George Walker Bush), and why would you redefine your own advice anyway?
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
792 ;; 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
793 ;; redefinition (wait until I write Meta-Advice :-). If you really have
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
794 ;; to undo somebody else's advice try to write a "neutralizing" advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
795
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
796 ;; @@ Advising macros and special forms and other dangerous things:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
797 ;; ================================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
798 ;; Look at the corresponding tutorial sections for more information on
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
799 ;; these topics. Here it suffices to point out that the special treatment
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
800 ;; of macros and special forms by the byte-compiler can lead to problems
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
801 ;; when they get advised. Macros can create problems because they get
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
802 ;; expanded at compile time, hence, they might not have all the necessary
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
803 ;; runtime support and such advice cannot be de/activated or changed as
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
804 ;; it is possible for functions. Special forms create problems because they
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
805 ;; 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
806 ;; implemented as a macro, hence, in most cases the byte-compiler will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
807 ;; 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
808 ;; results.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
809 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
810 ;; MORAL: - Only advise macros or special forms when you are absolutely sure
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
811 ;; what you are doing.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
812 ;; - As a safety measure, always do `ad-deactivate-all' before you
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
813 ;; byte-compile a file to make sure that even if some inconsiderate
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
814 ;; person advised some special forms you'll get proper compilation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
815 ;; results. After compilation do `ad-activate-all' to get back to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
816 ;; the previous state.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
817
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
818 ;; @@ Adding a piece of advice with `ad-add-advice':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
819 ;; =================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
820 ;; 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
821 ;; advice to some function without using `defadvice'. This is useful if advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
822 ;; 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
823
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
824 ;; @@ Activation/deactivation advices, file load hooks:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
825 ;; ====================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
826 ;; There are two special classes of advice called `activation' and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
827 ;; `deactivation'. The body forms of these advices are not included into the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
828 ;; advised definition of a function, rather they are assembled into a hook
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
829 ;; form which will be evaluated whenever the advice-info of the advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
830 ;; function gets activated or deactivated. One application of this mechanism
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
831 ;; 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
832 ;; (v19s already come with a general file-load-hook mechanism, v18s don't).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
833 ;; For example, suppose you want to print a message whenever `file-x' gets
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
834 ;; loaded, and suppose the last function defined in `file-x' is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
835 ;; `file-x-last-fn'. Then we can define the following advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
836 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
837 ;; (defadvice file-x-last-fn (activation file-x-load-hook)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
838 ;; "Executed whenever file-x is loaded"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
839 ;; (if load-in-progress (message "Loaded file-x")))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
840 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
841 ;; This will constitute a forward advice for function `file-x-last-fn' which
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
842 ;; will get activated when `file-x' is loaded (only if forward advice is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
843 ;; enabled of course). Because there are no "real" pieces of advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
844 ;; available for it, its definition will not be changed, but the activation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
845 ;; advice will be run during its activation which is equivalent to having a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
846 ;; file load hook for `file-x'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
847
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
848 ;; @@ Summary of main advice concepts:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
849 ;; ===================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
850 ;; - Definition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
851 ;; A piece of advice gets defined with `defadvice' and added to the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
852 ;; `advice-info' property of a function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
853 ;; - Enablement:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
854 ;; Every piece of advice has an enablement flag associated with it. Only
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
855 ;; enabled advices are considered during construction of an advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
856 ;; definition.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
857 ;; - Activation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
858 ;; Redefine an advised function with its advised definition. Constructs
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
859 ;; an advised definition from scratch if no verifiable cached advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
860 ;; definition is available and caches it.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
861 ;; - Deactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
862 ;; Back-define an advised function to its original definition.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
863 ;; - Update:
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
864 ;; Reactivate an advised function but only if its advice is currently
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
865 ;; active. This can be used to bring all currently advised function up
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
866 ;; to date with the current state of advice without also activating
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
867 ;; currently deactivated functions.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
868 ;; - Caching:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
869 ;; Is the saving of an advised definition and an identifying cache-id so
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
870 ;; it can be reused, for example, for activation after deactivation.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
871 ;; - Preactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
872 ;; Is the construction of an advised definition according to the current
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
873 ;; state of advice during byte-compilation of a file with a preactivating
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
874 ;; `defadvice'. That advised definition can then rather cheaply be used
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
875 ;; during activation without having to construct an advised definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
876 ;; from scratch at runtime.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
877
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
878 ;; @@ Summary of interactive advice manipulation functions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
879 ;; ========================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
880 ;; The following interactive functions can be used to manipulate the state
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
881 ;; of advised functions (all of them support completion on function names,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
882 ;; advice classes and advice names):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
883
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
884 ;; - ad-activate to activate the advice of a FUNCTION
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
885 ;; - ad-deactivate to deactivate the advice of a FUNCTION
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
886 ;; - ad-update to activate the advice of a FUNCTION unless it was not
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
887 ;; yet activated or is currently deactivated.
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
888 ;; - ad-unadvise deactivates a FUNCTION and removes all of its advice
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
889 ;; information, hence, it cannot be activated again
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
890 ;; - ad-recover tries to redefine a FUNCTION to its original definition and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
891 ;; discards all advice information (a low-level `ad-unadvise').
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
892 ;; Use only in emergencies.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
893
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
894 ;; - ad-remove-advice removes a particular piece of advice of a FUNCTION.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
895 ;; You still have to do call `ad-activate' or `ad-update' to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
896 ;; activate the new state of advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
897 ;; - ad-enable-advice enables a particular piece of advice of a FUNCTION.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
898 ;; - ad-disable-advice disables a particular piece of advice of a FUNCTION.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
899 ;; - ad-enable-regexp maps over all currently advised functions and enables
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
900 ;; every advice whose name contains a match for a regular
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
901 ;; expression.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
902 ;; - ad-disable-regexp disables matching advices.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
903
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
904 ;; - ad-activate-regexp activates all advised function with a matching advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
905 ;; - ad-deactivate-regexp deactivates all advised function with matching advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
906 ;; - ad-update-regexp updates all advised function with a matching advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
907 ;; - ad-activate-all activates all advised functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
908 ;; - ad-deactivate-all deactivates all advised functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
909 ;; - ad-update-all updates all advised functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
910 ;; - ad-unadvise-all unadvises all advised functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
911 ;; - ad-recover-all recovers all advised functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
912
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
913 ;; - ad-compile byte-compiles a function/macro if it is compilable.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
914
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
915 ;; @@ Summary of forms with special meanings when used within an advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
916 ;; =====================================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
917 ;; ad-return-value name of the return value variable (get/settable)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
918 ;; ad-subr-args name of &rest argument variable used for advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
919 ;; subrs whose actual argument list cannot be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
920 ;; determined (get/settable)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
921 ;; (ad-get-arg <pos>), (ad-get-args <pos>),
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
922 ;; (ad-set-arg <pos> <value>), (ad-set-args <pos> <value-list>)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
923 ;; argument access text macros to get/set the values of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
924 ;; actual arguments at a certain position
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
925 ;; ad-arg-bindings text macro that returns the actual names, values
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
926 ;; and types of the arguments as a list of bindings. The
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
927 ;; order of the bindings corresponds to the order of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
928 ;; arguments. The individual fields of every binding (name,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
929 ;; value and type) can be accessed with the function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
930 ;; `ad-arg-binding-field' (see example above).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
931 ;; ad-do-it text macro that identifies the place where the original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
932 ;; or wrapped definition should go in an around advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
933
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
934
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
935 ;; @ Foo games: An advice tutorial
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
936 ;; ===============================
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
937 ;; The following tutorial was created in Emacs 18.59. Left-justified
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
938 ;; s-expressions are input forms followed by one or more result forms.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
939 ;; First we have to start the advice magic:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
940 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
941 ;; (ad-start-advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
942 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
943 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
944 ;; We start by defining an innocent looking function `foo' that simply
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
945 ;; adds 1 to its argument X:
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
946 ;;
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
947 ;; (defun foo (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
948 ;; "Add 1 to X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
949 ;; (1+ x))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
950 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
951 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
952 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
953 ;; 4
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
954 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
955 ;; @@ Defining a simple piece of advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
956 ;; =====================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
957 ;; 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
958 ;; use the macro `defadvice' which takes a function name, a list of advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
959 ;; specifiers and a list of body forms as arguments. The first element of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
960 ;; 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
961 ;; 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
962 ;; first advice is `before', its name is `fg-add2', its position among the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
963 ;; currently defined before advices (none so far) is `first', and the advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
964 ;; will be `activate'ed immediately. Advice names are global symbols, hence,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
965 ;; the name space conventions used for function names should be applied. All
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
966 ;; advice names in this tutorial will be prefixed with `fg' for `Foo Games'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
967 ;; (because everybody has the right to be inconsistent all the function names
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
968 ;; used in this tutorial do NOT follow this convention).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
969 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
970 ;; 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
971 ;; 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
972 ;; `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
973 ;; have one body form for simplicity, but there is no restriction to that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
974 ;; extent. Every piece of advice can have a documentation string which will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
975 ;; be combined with the documentation of the original function.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
976 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
977 ;; (defadvice foo (before fg-add2 first activate)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
978 ;; "Add 2 to X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
979 ;; (setq x (1+ x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
980 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
981 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
982 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
983 ;; 5
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
984 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
985 ;; @@ Specifying the position of an advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
986 ;; ========================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
987 ;; Now we define the second before advice which will cancel the effect of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
988 ;; the previous advice. This time we specify the position as 0 which is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
989 ;; equivalent to `first'. A number can be used to specify the zero-based
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
990 ;; 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
991 ;; time we already have one before advice hence the position specification
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
992 ;; actually has an effect. So, after the following definition the position
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
993 ;; 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
994 ;; above, the reason for this is that the position argument is relative to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
995 ;; the currently defined pieces of advice which by now has changed.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
996 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
997 ;; (defadvice foo (before fg-cancel-add2 0 activate)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
998 ;; "Again only add 1 to X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
999 ;; (setq x (1- x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1000 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1001 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1002 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1003 ;; 4
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1004 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1005 ;; @@ Redefining a piece of advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1006 ;; ================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1007 ;; 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
1008 ;; different position. Defining an advice in a class in which an advice with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1009 ;; that name already exists is interpreted as a redefinition of that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1010 ;; particular advice, in which case the position argument will be ignored
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1011 ;; and the previous position of the redefined piece of advice is used.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1012 ;; Advice flags can be specified with non-ambiguous initial substrings, hence,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1013 ;; from now on we'll use `act' instead of the verbose `activate'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1014 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1015 ;; (defadvice foo (before fg-cancel-add2 last act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1016 ;; "Again only add 1 to X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1017 ;; (setq x (1- x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1018 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1019 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1020 ;; @@ Assembly of advised documentation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1021 ;; =====================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1022 ;; The documentation strings of the various pieces of advice are assembled
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1023 ;; in order which shows that advice `fg-cancel-add2' is still the first
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1024 ;; `before' advice even though we specified position `last' above:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1025 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1026 ;; (documentation 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1027 ;; "Add 1 to X.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1028 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1029 ;; This function is advised with the following advice(s):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1030 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1031 ;; fg-cancel-add2 (before):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1032 ;; Again only add 1 to X.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1033 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1034 ;; fg-add2 (before):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1035 ;; Add 2 to X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1036 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1037 ;; @@ Advising interactive behavior:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1038 ;; =================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1039 ;; We can make a function interactive (or change its interactive behavior)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1040 ;; by specifying an interactive form in one of the before or around
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1041 ;; advices (there could also be body forms in this advice). The particular
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1042 ;; 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
1043 ;; result when we call foo interactively:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1044 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1045 ;; (defadvice foo (before fg-inter last act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1046 ;; "Use 5 as argument when called interactively."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1047 ;; (interactive (list 5)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1048 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1049 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1050 ;; (call-interactively 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1051 ;; 6
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1052 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1053 ;; If more than one advice have an interactive declaration, then the one of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1054 ;; the advice with the smallest position will be used (before advices go
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1055 ;; before around and after advices), hence, the declaration below does
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1056 ;; not have any effect:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1057 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1058 ;; (defadvice foo (before fg-inter2 last act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1059 ;; (interactive (list 6)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1060 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1061 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1062 ;; (call-interactively 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1063 ;; 6
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1064 ;;
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1065 ;; 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
1066 ;; (indentation added by hand for legibility):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1067 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1068 ;; (symbol-function 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1069 ;; (lambda (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1070 ;; "$ad-doc: foo$"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1071 ;; (interactive (list 5))
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1072 ;; (let (ad-return-value)
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1073 ;; (setq x (1- x))
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 ad-return-value (ad-Orig-foo x))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1076 ;; ad-return-value))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1077 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1078 ;; @@ Around advices:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1079 ;; ==================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1080 ;; 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
1081 ;; the original definition. It can shadow or establish bindings for the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1082 ;; original definition, and it can look at and manipulate the value returned
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1083 ;; by the original function. The position of the special keyword `ad-do-it'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1084 ;; specifies where the code of the original function will be executed. The
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1085 ;; keyword can appear multiple times which will result in multiple calls of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1086 ;; 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
1087 ;; specify a position argument (i.e., `first', `last' or a number), then
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1088 ;; `first' (or 0) is the default):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1089 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1090 ;; (defadvice foo (around fg-times-2 act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1091 ;; "First double X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1092 ;; (let ((x (* x 2)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1093 ;; ad-do-it))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1094 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1095 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1096 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1097 ;; 7
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1098 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1099 ;; Around advices are assembled like onion skins where the around advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1100 ;; 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
1101 ;; is the innermost skin which is directly wrapped around the call of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1102 ;; original definition of the function. Hence, after the next `defadvice' we
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1103 ;; 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
1104 ;; definition (i.e., add 1 again):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1105 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1106 ;; (defadvice foo (around fg-add-1 last act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1107 ;; "Add 1 to X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1108 ;; (let ((x (1+ x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1109 ;; ad-do-it))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1110 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1111 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1112 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1113 ;; 8
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1114 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1115 ;; Again, let's see what the definition of `foo' looks like so far:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1116 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1117 ;; (symbol-function 'foo)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1118 ;; (lambda (x)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1119 ;; "$ad-doc: foo$"
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1120 ;; (interactive (list 5))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1121 ;; (let (ad-return-value)
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1122 ;; (setq x (1- x))
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 ;; (let ((x (* x 2)))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1125 ;; (let ((x (1+ x)))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1126 ;; (setq ad-return-value (ad-Orig-foo x))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1127 ;; ad-return-value))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1128 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1129 ;; @@ Controlling advice activation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1130 ;; =================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1131 ;; In every `defadvice' so far we have used the flag `activate' to activate
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1132 ;; the advice immediately after its definition, and that's what we want in
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1133 ;; most cases. However, if we define multiple pieces of advice for a single
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1134 ;; function then activating every advice immediately is inefficient. A
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1135 ;; better way to do this is to only activate the last defined advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1136 ;; For example:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1137 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1138 ;; (defadvice foo (after fg-times-x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1139 ;; "Multiply the result with X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1140 ;; (setq ad-return-value (* ad-return-value x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1141 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1142 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1143 ;; This still yields the same result as before:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1144 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1145 ;; 8
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1146 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1147 ;; Now we define another advice and activate which will also activate the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1148 ;; previous advice `fg-times-x'. Note the use of the special variable
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1149 ;; `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
1150 ;; the original function. If we change its value then the value returned by
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1151 ;; the advised function will be changed accordingly:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1152 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1153 ;; (defadvice foo (after fg-times-x-again act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1154 ;; "Again multiply the result with X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1155 ;; (setq ad-return-value (* ad-return-value x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1156 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1157 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1158 ;; Now the advices have an effect:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1159 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1160 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1161 ;; 72
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1162 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1163 ;; @@ Protecting advice execution:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1164 ;; ===============================
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1165 ;; 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
1166 ;; for example:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1167 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1168 ;; (defadvice foo (after fg-cleanup last act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1169 ;; "Do some cleanup."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1170 ;; (print "Let's clean up now!"))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1171 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1172 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1173 ;; However, in case of an error the cleanup won't be performed:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1174 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1175 ;; (condition-case error
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1176 ;; (foo t)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1177 ;; (error 'error-in-foo))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1178 ;; error-in-foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1179 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1180 ;; 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
1181 ;; 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
1182 ;; the `protect' keyword. (if any of the around advices is protected then the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1183 ;; whole around advice onion will be protected):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1184 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1185 ;; (defadvice foo (after fg-cleanup prot act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1186 ;; "Do some protected cleanup."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1187 ;; (print "Let's clean up now!"))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1188 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1189 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1190 ;; Now the cleanup form will be executed even in case of an error:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1191 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1192 ;; (condition-case error
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1193 ;; (foo t)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1194 ;; (error 'error-in-foo))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1195 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1196 ;; error-in-foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1197 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1198 ;; Again, let's see what `foo' looks like:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1199 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1200 ;; (symbol-function 'foo)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1201 ;; (lambda (x)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1202 ;; "$ad-doc: foo$"
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1203 ;; (interactive (list 5))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1204 ;; (let (ad-return-value)
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1205 ;; (unwind-protect
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1206 ;; (progn (setq x (1- x))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1207 ;; (setq x (1+ x))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1208 ;; (let ((x (* x 2)))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1209 ;; (let ((x (1+ x)))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1210 ;; (setq ad-return-value (ad-Orig-foo x))))
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1211 ;; (setq ad-return-value (* ad-return-value 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 ;; (print "Let's clean up now!"))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1214 ;; ad-return-value))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1215 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1216 ;; @@ Compilation of advised definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1217 ;; ======================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1218 ;; Finally, we can specify the `compile' keyword in a `defadvice' to say
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1219 ;; that we want the resulting advised function to be byte-compiled
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1220 ;; (`compile' will be ignored unless we also specified `activate'):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1221 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1222 ;; (defadvice foo (after fg-cleanup prot act comp)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1223 ;; "Do some protected cleanup."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1224 ;; (print "Let's clean up now!"))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1225 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1226 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1227 ;; Now `foo' is byte-compiled:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1228 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1229 ;; (symbol-function 'foo)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1230 ;; (lambda (x)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1231 ;; "$ad-doc: foo$"
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1232 ;; (interactive (byte-code "....." [5] 1))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1233 ;; (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
1234 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1235 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1236 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1237 ;; 72
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1238 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1239 ;; @@ Enabling and disabling pieces of advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1240 ;; ===========================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1241 ;; 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
1242 ;; so that it won't be considered during activation, for example, if two
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1243 ;; different packages advise the same function and one wants to temporarily
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1244 ;; neutralize the effect of the advice of one of the packages.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1245 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1246 ;; The following disables the after advice `fg-times-x' in the function `foo'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1247 ;; 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
1248 ;; other information defining it will be left unchanged (e.g., its relative
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1249 ;; position in this advice class, etc.).
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1250 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1251 ;; (ad-disable-advice 'foo 'after 'fg-times-x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1252 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1253 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1254 ;; For this to have an effect we have to activate `foo':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1255 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1256 ;; (ad-activate 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1257 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1258 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1259 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1260 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1261 ;; 24
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1262 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1263 ;; 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
1264 ;; regular expression that matches the names of such advices. Actually, any
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1265 ;; advice name that contains a match for the regular expression will be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1266 ;; called a match. A special advice class `any' can be used to consider
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1267 ;; all advice classes:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1268 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1269 ;; (ad-disable-advice 'foo 'any "^fg-.*times")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1270 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1271 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1272 ;; (ad-activate 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1273 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1274 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1275 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1276 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1277 ;; 5
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1278 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1279 ;; To enable the disabled advice we could use either `ad-enable-advice'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1280 ;; similar to `ad-disable-advice', or as an alternative `ad-enable-regexp'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1281 ;; which will enable matching advices in ALL currently advised functions.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1282 ;; Hence, this can be used to dis/enable advices made by a particular
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1283 ;; package to a set of functions as long as that package obeys standard
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1284 ;; advice name conventions. We prefixed all advice names with `fg-', hence
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1285 ;; the following will do the trick (`ad-enable-regexp' returns the number
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1286 ;; of matched advices):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1287 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1288 ;; (ad-enable-regexp "^fg-")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1289 ;; 9
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1290 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1291 ;; The following will activate all currently active advised functions that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1292 ;; contain some advice matched by the regular expression. This is a save
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1293 ;; way to update the activation of advised functions whose advice changed
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1294 ;; in some way or other without accidentally also activating currently
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1295 ;; deactivated functions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1296 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1297 ;; (ad-update-regexp "^fg-")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1298 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1299 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1300 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1301 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1302 ;; 72
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1303 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1304 ;; 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
1305 ;; and keep it "dormant" until a particular condition is satisfied, i.e., until
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1306 ;; then the advice will not be used during activation. The `disable' flag lets
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1307 ;; one do that with `defadvice':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1308 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1309 ;; (defadvice foo (before fg-1-more dis)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1310 ;; "Add yet 1 more."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1311 ;; (setq x (1+ x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1312 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1313 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1314 ;; (ad-activate 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1315 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1316 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1317 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1318 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1319 ;; 72
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1320 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1321 ;; (ad-enable-advice 'foo 'before 'fg-1-more)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1322 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1323 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1324 ;; (ad-activate 'foo)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1325 ;; foo
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1326 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1327 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1328 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1329 ;; 160
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1330 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1331 ;; @@ Caching:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1332 ;; ===========
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1333 ;; Advised definitions get cached to allow efficient activation/deactivation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1334 ;; without having to reconstruct them if nothing in the advice-info of a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1335 ;; function has changed. The following idiom can be used to temporarily
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1336 ;; deactivate functions that have a piece of advice defined by a certain
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1337 ;; package (we save the old definition to check out caching):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1338 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1339 ;; (setq old-definition (symbol-function 'foo))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1340 ;; (lambda (x) ....)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1341 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1342 ;; (ad-deactivate-regexp "^fg-")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1343 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1344 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1345 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1346 ;; 4
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1347 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1348 ;; (ad-activate-regexp "^fg-")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1349 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1350 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1351 ;; (eq old-definition (symbol-function 'foo))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1352 ;; t
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1353 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1354 ;; (foo 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1355 ;; "Let's clean up now!"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1356 ;; 160
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1357 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1358 ;; @@ Forward advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1359 ;; ==================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1360 ;; To enable automatic activation of forward advice we first have to set
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1361 ;; `ad-activate-on-definition' to t and restart advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1362 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1363 ;; (setq ad-activate-on-definition t)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1364 ;; t
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1365 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1366 ;; (ad-start-advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1367 ;; (ad-activate-defined-function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1368 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1369 ;; Let's define a piece of advice for an undefined function:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1370 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1371 ;; (defadvice bar (before fg-sub-1-more act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1372 ;; "Subtract one more from X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1373 ;; (setq x (1- x)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1374 ;; bar
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1375 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1376 ;; `bar' is not yet defined:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1377 ;; (fboundp 'bar)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1378 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1379 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1380 ;; Now we define it and the forward advice will get activated (only because
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1381 ;; `ad-activate-on-definition' was t when we started advice above with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1382 ;; `ad-start-advice'):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1383 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1384 ;; (defun bar (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1385 ;; "Subtract 1 from X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1386 ;; (1- x))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1387 ;; bar
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1388 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1389 ;; (bar 4)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1390 ;; 2
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1391 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1392 ;; Redefinition will activate any available advice if the value of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1393 ;; `ad-redefinition-action' is either `warn', `accept' or `discard':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1394 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1395 ;; (defun bar (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1396 ;; "Subtract 2 from X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1397 ;; (- x 2))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1398 ;; bar
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1399 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1400 ;; (bar 4)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1401 ;; 1
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1402 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1403 ;; @@ Preactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1404 ;; =================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1405 ;; Constructing advised definitions is moderately expensive, hence, it is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1406 ;; desirable to have a way to construct them at byte-compile time.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1407 ;; Preactivation is a mechanism that allows one to do that.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1408 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1409 ;; (defun fie (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1410 ;; "Multiply X by 2."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1411 ;; (* x 2))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1412 ;; fie
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1413 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1414 ;; (defadvice fie (before fg-times-4 preact)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1415 ;; "Multiply X by 4."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1416 ;; (setq x (* x 2)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1417 ;; fie
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1418 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1419 ;; This advice did not affect `fie'...
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1420 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1421 ;; (fie 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1422 ;; 4
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1423 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1424 ;; ...but it constructed a cached definition that will be used once `fie' gets
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1425 ;; 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
1426 ;; preactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1427 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1428 ;; (setq cached-definition (ad-get-cache-definition 'fie))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1429 ;; (lambda (x) ....)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1430 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1431 ;; (ad-activate 'fie)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1432 ;; fie
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1433 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1434 ;; (eq cached-definition (symbol-function 'fie))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1435 ;; t
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1436 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1437 ;; (fie 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1438 ;; 8
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1439 ;;
11035
97da4cb32d03 Comment change.
Richard M. Stallman <rms@gnu.org>
parents: 8458
diff changeset
1440 ;; 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
1441 ;; compiled then the constructed advised definition will get compiled by
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1442 ;; 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
1443 ;; `defadvice' inside a `defun' because the v18 compiler does not compile
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1444 ;; top-level forms other than `defun' or `defmacro', for example,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1445 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1446 ;; (defun fg-defadvice-fum ()
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1447 ;; (defadvice fum (before fg-times-4 preact act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1448 ;; "Multiply X by 4."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1449 ;; (setq x (* x 2))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1450 ;; fg-defadvice-fum
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1451 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1452 ;; So far, no `defadvice' for `fum' got executed, but when we compile
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1453 ;; `fg-defadvice-fum' the `defadvice' will be expanded by the byte compiler.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1454 ;; In order for preactivation to be effective we have to have a proper
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1455 ;; definition of `fum' around at preactivation time, hence, we define it now:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1456 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1457 ;; (defun fum (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1458 ;; "Multiply X by 2."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1459 ;; (* x 2))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1460 ;; fum
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1461 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1462 ;; Now we compile the defining function which will construct an advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1463 ;; definition during expansion of the `defadvice', compile it and store it
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1464 ;; as part of the compiled `fg-defadvice-fum':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1465 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1466 ;; (ad-compile-function 'fg-defadvice-fum)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1467 ;; (lambda nil (byte-code ...))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1468 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1469 ;; `fum' is still completely unaffected:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1470 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1471 ;; (fum 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1472 ;; 4
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1473 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1474 ;; (ad-get-advice-info 'fum)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1475 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1476 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1477 ;; (fg-defadvice-fum)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1478 ;; fum
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1479 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1480 ;; Now the advised version of `fum' is compiled because the compiled definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1481 ;; constructed during preactivation was used, even though we did not specify
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1482 ;; the `compile' flag:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1483 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1484 ;; (symbol-function 'fum)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1485 ;; (lambda (x)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1486 ;; "$ad-doc: fum$"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1487 ;; (byte-code "....." [ad-return-value x nil * 2 ad-Orig-fum] 4))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1488 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1489 ;; (fum 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1490 ;; 8
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1491 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1492 ;; A preactivated definition will only be used if it matches the current
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1493 ;; function definition and advice information. If it does not match it
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1494 ;; will simply be discarded and a new advised definition will be constructed
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1495 ;; from scratch. For example, let's first remove all advice-info for `fum':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1496 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1497 ;; (ad-unadvise 'fum)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1498 ;; (("fie") ("bar") ("foo") ...)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1499 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1500 ;; And now define a new piece of advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1501 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1502 ;; (defadvice fum (before fg-interactive act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1503 ;; "Make fum interactive."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1504 ;; (interactive "nEnter x: "))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1505 ;; fum
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1506 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1507 ;; 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
1508 ;; current advice state is different from the one at preactivation time. This
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1509 ;; is no tragedy, everything will work as expected just not as efficient,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1510 ;; because a new advised definition has to be constructed from scratch:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1511 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1512 ;; (fg-defadvice-fum)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1513 ;; fum
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1514 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1515 ;; A new uncompiled advised definition got constructed:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1516 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1517 ;; (ad-compiled-p (symbol-function 'fum))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1518 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1519 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1520 ;; (fum 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1521 ;; 8
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1522 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1523 ;; MORAL: To get all the efficiency out of preactivation the function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1524 ;; definition and advice state at preactivation time must be the same as the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1525 ;; state at activation time. Preactivation does work with forward advice, all
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1526 ;; that's necessary is that the definition of the forward advised function is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1527 ;; available when the `defadvice' with the preactivation gets compiled.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1528 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1529 ;; @@ Portable argument access:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1530 ;; ============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1531 ;; So far, we always used the actual argument variable names to access an
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1532 ;; argument in a piece of advice. For many advice applications this is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1533 ;; perfectly ok and keeps advices simple. However, it decreases portability
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1534 ;; of advices because it assumes specific argument variable names. For example,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1535 ;; 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
1536 ;; some package (e.g., edebug) into a function with different argument names,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1537 ;; then a piece of advice written for `eval-region' that was written with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1538 ;; the subr arguments in mind will break. Similar situations arise when one
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1539 ;; switches between major Emacs versions, e.g., certain subrs in v18 are
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1540 ;; functions in v19 and vice versa. Also, in v19s subr argument lists
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1541 ;; are available and will be used, while they are not available in v18.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1542 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1543 ;; Argument access text macros allow one to access arguments of an advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1544 ;; function in a portable way without having to worry about all these
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1545 ;; possibilities. These macros will be translated into the proper access forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1546 ;; at activation time, hence, argument access will be as efficient as if
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1547 ;; the arguments had been used directly in the definition of the advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1548 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1549 ;; (defun fuu (x y z)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1550 ;; "Add 3 numbers."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1551 ;; (+ x y z))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1552 ;; fuu
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1553 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1554 ;; (fuu 1 1 1)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1555 ;; 3
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1556 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1557 ;; Argument access macros specify actual arguments at a certain position.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1558 ;; Position 0 access the first actual argument, position 1 the second etc.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1559 ;; For example, the following advice adds 1 to each of the 3 arguments:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1560 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1561 ;; (defadvice fuu (before fg-add-1-to-all act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1562 ;; "Adds 1 to all arguments."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1563 ;; (ad-set-arg 0 (1+ (ad-get-arg 0)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1564 ;; (ad-set-arg 1 (1+ (ad-get-arg 1)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1565 ;; (ad-set-arg 2 (1+ (ad-get-arg 2))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1566 ;; fuu
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1567 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1568 ;; (fuu 1 1 1)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1569 ;; 6
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1570 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1571 ;; Now suppose somebody redefines `fuu' with a rest argument. Our advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1572 ;; will still work because we used access macros (note, that automatic
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1573 ;; advice activation is still in effect, hence, the redefinition of `fuu'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1574 ;; will automatically activate all its advice):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1575 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1576 ;; (defun fuu (&rest numbers)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1577 ;; "Add NUMBERS."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1578 ;; (apply '+ numbers))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1579 ;; fuu
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1580 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1581 ;; (fuu 1 1 1)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1582 ;; 6
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1583 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1584 ;; (fuu 1 1 1 1 1 1)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1585 ;; 9
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1586 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1587 ;; What's important to notice is that argument access macros access actual
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1588 ;; arguments regardless of how they got distributed onto argument variables.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1589 ;; In Emacs Lisp the semantics of an actual argument is determined purely
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1590 ;; by position, hence, as long as nobody changes the semantics of what a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1591 ;; certain actual argument at a certain position means the access macros
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1592 ;; will do the right thing.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1593 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1594 ;; Because of &rest arguments we need a second kind of access macro that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1595 ;; can access all actual arguments starting from a certain position:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1596 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1597 ;; (defadvice fuu (before fg-print-args act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1598 ;; "Print all arguments."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1599 ;; (print (ad-get-args 0)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1600 ;; fuu
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1601 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1602 ;; (fuu 1 2 3 4 5)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1603 ;; (1 2 3 4 5)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1604 ;; 18
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1605 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1606 ;; (defadvice fuu (before fg-set-args act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1607 ;; "Swaps 2nd and 3rd arg and discards all the rest."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1608 ;; (ad-set-args 1 (list (ad-get-arg 2) (ad-get-arg 1))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1609 ;; fuu
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1610 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1611 ;; (fuu 1 2 3 4 4 4 4 4 4)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1612 ;; (1 3 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1613 ;; 9
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1614 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1615 ;; (defun fuu (x y z)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1616 ;; "Add 3 numbers."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1617 ;; (+ x y z))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1618 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1619 ;; (fuu 1 2 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1620 ;; (1 3 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1621 ;; 9
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1622 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1623 ;; @@ Defining the argument list of an advised function:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1624 ;; =====================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1625 ;; 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
1626 ;; give it an extra argument that controls the advised code, for example, one
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1627 ;; might want to make an interactive function sensitive to a prefix argument.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1628 ;; For such cases `defadvice' allows the specification of an argument list
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1629 ;; for the advised function. Similar to the redefinition of interactive
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1630 ;; behavior, the first argument list specification found in the list of before/
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1631 ;; around/after advices will be used. Of course, the specified argument list
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1632 ;; should be downward compatible with the original argument list, otherwise
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1633 ;; functions that call the advised function with the original argument list
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1634 ;; in mind will break.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1635 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1636 ;; (defun fii (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1637 ;; "Add 1 to X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1638 ;; (1+ x))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1639 ;; fii
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1640 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1641 ;; Now we advise `fii' to use an optional second argument that controls the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1642 ;; amount of incrementation. A list following the (optional) position
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1643 ;; argument of the advice will be interpreted as an argument list
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1644 ;; specification. This means you cannot specify an empty argument list, and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1645 ;; why would you want to anyway?
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1646 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1647 ;; (defadvice fii (before fg-inc-x (x &optional incr) act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1648 ;; "Increment X by INCR (default is 1)."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1649 ;; (setq x (+ x (1- (or incr 1)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1650 ;; fii
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1651 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1652 ;; (fii 3)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1653 ;; 4
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1654 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1655 ;; (fii 3 2)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1656 ;; 5
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1657 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1658 ;; @@ Specifying argument lists of subrs:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1659 ;; ======================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1660 ;; 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
1661 ;; 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
1662 ;; argument list of the advised subr which is not very efficient. In Lemacs
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1663 ;; 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
1664 ;; 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
1665 ;; 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
1666 ;; v18 Emacs) Advice comes with a specification mechanism that allows the
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1667 ;; advice programmer to tell advice what the argument list of a certain subr
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1668 ;; really is.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1669 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1670 ;; In a v18 Emacs the following will return the &rest idiom:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1671 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1672 ;; (ad-arglist (symbol-function 'car))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1673 ;; (&rest ad-subr-args)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1674 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1675 ;; To tell advice what the argument list of `car' really is we
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1676 ;; can do the following:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1677 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1678 ;; (ad-define-subr-args 'car '(list))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1679 ;; ((list))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1680 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1681 ;; Now `ad-arglist' will return the proper argument list (this method is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1682 ;; actually used by advice itself for the advised definition of `fset'):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1683 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1684 ;; (ad-arglist (symbol-function 'car))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1685 ;; (list)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1686 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1687 ;; The defined argument list will be stored on the property list of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1688 ;; subr name symbol. When advice looks for a subr argument list it first
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1689 ;; checks for a definition on the property list, if that fails it tries
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1690 ;; to infer it from the documentation string and caches it on the property
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1691 ;; list if it was successful, otherwise `(&rest ad-subr-args)' will be used.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1692 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1693 ;; @@ Advising interactive subrs:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1694 ;; ==============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1695 ;; For the most part there is no difference between advising functions and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1696 ;; advising subrs. There is one situation though where one might have to write
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1697 ;; slightly different advice code for subrs than for functions. This case
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1698 ;; arises when one wants to access subr arguments in a before/around advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1699 ;; when the arguments were determined by an interactive call to the subr.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1700 ;; Advice cannot determine what `interactive' form determines the interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1701 ;; behavior of the subr, hence, when it calls the original definition in an
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1702 ;; interactive subr invocation it has to use `call-interactively' to generate
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1703 ;; the proper interactive behavior. Thus up to that call the arguments of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1704 ;; interactive subr will be nil. For example, the following advice for
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1705 ;; `kill-buffer' will not work in an interactive invocation...
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1706 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1707 ;; (defadvice kill-buffer (before fg-kill-buffer-hook first act preact comp)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1708 ;; (my-before-kill-buffer-hook (ad-get-arg 0)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1709 ;; kill-buffer
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1710 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1711 ;; ...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
1712 ;; this dilemma is to provide an `interactive' specification that mirrors
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1713 ;; the interactive behavior of the unadvised subr, for example, the following
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1714 ;; will do the right thing even when `kill-buffer' is called interactively:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1715 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1716 ;; (defadvice kill-buffer (before fg-kill-buffer-hook first act preact comp)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1717 ;; (interactive "bKill buffer: ")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1718 ;; (my-before-kill-buffer-hook (ad-get-arg 0)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1719 ;; kill-buffer
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1720 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1721 ;; @@ Advising macros:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1722 ;; ===================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1723 ;; Advising macros is slightly different because there are two significant
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1724 ;; time points in the invocation of a macro: Expansion and evaluation time.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1725 ;; For an advised macro instead of evaluating the original definition we
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1726 ;; use `macroexpand', that is, changing argument values and binding
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1727 ;; environments by pieces of advice has an affect during macro expansion
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1728 ;; but not necessarily during evaluation. In particular, any side effects
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1729 ;; of pieces of advice will occur during macro expansion. To also affect
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1730 ;; the behavior during evaluation time one has to change the value of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1731 ;; `ad-return-value' in a piece of after advice. For example:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1732 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1733 ;; (defmacro foom (x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1734 ;; (` (list (, x))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1735 ;; foom
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1736 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1737 ;; (foom '(a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1738 ;; ((a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1739 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1740 ;; (defadvice foom (before fg-print-x act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1741 ;; "Print the value of X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1742 ;; (print x))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1743 ;; foom
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1744 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1745 ;; The following works as expected because evaluation immediately follows
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1746 ;; macro expansion:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1747 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1748 ;; (foom '(a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1749 ;; (quote (a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1750 ;; ((a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1751 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1752 ;; However, the printing happens during expansion (or byte-compile) time:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1753 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1754 ;; (macroexpand '(foom '(a)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1755 ;; (quote (a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1756 ;; (list (quote (a)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1757 ;;
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1758 ;; 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
1759 ;; following (first remove the old advice):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1760 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1761 ;; (ad-remove-advice 'foom 'before 'fg-print-x)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1762 ;; nil
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1763 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1764 ;; (defadvice foom (after fg-print-x act)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1765 ;; "Print the value of X."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1766 ;; (setq ad-return-value
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1767 ;; (` (progn (print (, x))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1768 ;; (, ad-return-value)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1769 ;; foom
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1770 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1771 ;; (macroexpand '(foom '(a)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1772 ;; (progn (print (quote (a))) (list (quote (a))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1773 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1774 ;; (foom '(a))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1775 ;; (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 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1778 ;; While this method might seem somewhat cumbersome, it is very general
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1779 ;; because it allows one to influence macro expansion as well as evaluation.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1780 ;; In general, advising macros should be a rather rare activity anyway, in
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1781 ;; particular, because compile-time macro expansion takes away a lot of the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1782 ;; flexibility and effectiveness of the advice mechanism. Macros that were
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1783 ;; compile-time expanded before the advice was activated will of course never
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1784 ;; exhibit the advised behavior.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1785 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1786 ;; @@ Advising special forms:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1787 ;; ==========================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1788 ;; Now for something that should be even more rare than advising macros:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1789 ;; Advising special forms. Because special forms are irregular in their
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1790 ;; argument evaluation behavior (e.g., `setq' evaluates the second but not
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1791 ;; the first argument) they have to be advised into macros. A dangerous
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1792 ;; consequence of this is that the byte-compiler will not recognize them
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1793 ;; as special forms anymore (well, in most cases) and use their expansion
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1794 ;; rather than the proper byte-code. Also, because the original definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1795 ;; 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
1796 ;; which is less efficient.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1797 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1798 ;; MORAL: Do not advise special forms unless you are completely sure about
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1799 ;; what you are doing (some of the forward advice behavior is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1800 ;; implemented via advice of the special forms `defun' and `defmacro').
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1801 ;; As a safety measure one should always do `ad-deactivate-all' before
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1802 ;; one byte-compiles a file to avoid any interference of advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1803 ;; special forms.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1804 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1805 ;; Apart from the safety concerns advising special forms is not any different
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1806 ;; from advising plain functions or subrs.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1807
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1808
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1809 ;;; Code:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1810
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1811 ;; @ Advice implementation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1812 ;; ========================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1813
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1814 ;; @@ Compilation idiosyncrasies:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1815 ;; ==============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1816
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1817 ;; `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
1818 ;; 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
1819 ;; interference of bogus compiled files I always preload the source file:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1820 (provide 'advice-preload)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1821 ;; During a normal load this is a noop:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1822 (require 'advice-preload "advice.el")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1823
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1824
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
1825 ;; @@ Variable definitions:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
1826 ;; ========================
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
1827
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1828 (defgroup advice nil
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1829 "An overloading mechanism for Emacs Lisp functions."
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1830 :prefix "ad-"
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1831 :link '(custom-manual "(elisp)Advising Functions")
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1832 :group 'lisp)
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1833
8458
a95ca44cec95 (ad-subr-arglist): Adapted to new DOC file format.
Richard M. Stallman <rms@gnu.org>
parents: 8445
diff changeset
1834 (defconst ad-version "2.14")
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1835
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1836 ;;;###autoload
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1837 (defcustom ad-redefinition-action 'warn
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
1838 "*Defines what to do with redefinitions during Advice de/activation.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1839 Redefinition occurs if a previously activated function that already has an
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1840 original definition associated with it gets redefined and then de/activated.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1841 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
1842 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
1843 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
1844 `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
1845 it additionally prints a warning message. All other values will be
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1846 interpreted as `error'."
22577
c129b4c40a0c (ad-redefinition-action,
Andreas Schwab <schwab@suse.de>
parents: 22061
diff changeset
1847 :type '(choice (const accept) (const discard) (const warn)
c129b4c40a0c (ad-redefinition-action,
Andreas Schwab <schwab@suse.de>
parents: 22061
diff changeset
1848 (other :tag "error" error))
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1849 :group 'advice)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1850
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1851 ;;;###autoload
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1852 (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
1853 "*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
1854 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
1855 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
1856 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
1857 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
1858 be interpreted as `maybe'. This variable will only be considered if the
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1859 COMPILE argument of `ad-activate' was supplied as nil."
22577
c129b4c40a0c (ad-redefinition-action,
Andreas Schwab <schwab@suse.de>
parents: 22061
diff changeset
1860 :type '(choice (const always) (const never) (const like-original)
c129b4c40a0c (ad-redefinition-action,
Andreas Schwab <schwab@suse.de>
parents: 22061
diff changeset
1861 (other :tag "maybe" maybe))
21365
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1862 :group 'advice)
db005054f15d Customized.
Stephen Eglen <stephen@gnu.org>
parents: 14169
diff changeset
1863
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1864
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1865
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1866 ;; @@ Some utilities:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1867 ;; ==================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1868
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1869 ;; We don't want the local arguments to interfere with anything
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1870 ;; referenced in the supplied functions => the cryptic casing:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1871 (defun ad-substitute-tree (sUbTrEe-TeSt fUnCtIoN tReE)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1872 "Substitute qualifying subTREEs with result of FUNCTION(subTREE).
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1873 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
1874 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
1875 allowed too. Once a qualifying subtree has been found its subtrees will
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1876 not be considered anymore. (ad-substitute-tree 'atom 'identity tree)
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1877 generates a copy of TREE."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1878 (cond ((consp tReE)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1879 (cons (if (funcall sUbTrEe-TeSt (car tReE))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1880 (funcall fUnCtIoN (car tReE))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1881 (if (consp (car tReE))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1882 (ad-substitute-tree sUbTrEe-TeSt fUnCtIoN (car tReE))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1883 (car tReE)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1884 (ad-substitute-tree sUbTrEe-TeSt fUnCtIoN (cdr tReE))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1885 ((funcall sUbTrEe-TeSt tReE)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1886 (funcall fUnCtIoN tReE))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1887 (t tReE)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1888
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1889 ;; this is just faster than `ad-substitute-tree':
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1890 (defun ad-copy-tree (tree)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1891 "Return a copy of the list structure of TREE."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1892 (cond ((consp tree)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1893 (cons (ad-copy-tree (car tree))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1894 (ad-copy-tree (cdr tree))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1895 (t tree)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1896
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1897 (defmacro ad-dolist (varform &rest body)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1898 "A Common-Lisp-style dolist iterator with the following syntax:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1899
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1900 (ad-dolist (VAR INIT-FORM [RESULT-FORM])
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1901 BODY-FORM...)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1902
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1903 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
1904 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
1905 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
1906 exited prematurely with `(ad-do-return [VALUE])'."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1907 (let ((expansion
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1908 `(let ((ad-dO-vAr ,(car (cdr varform)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1909 ,(car varform))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1910 (while ad-dO-vAr
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1911 (setq ,(car varform) (car ad-dO-vAr))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1912 ,@body
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1913 ;;work around a backquote bug:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1914 ;;(` ((,@ '(foo)) (bar))) => (append '(foo) '(((bar)))) wrong
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1915 ;;(` ((,@ '(foo)) (, '(bar)))) => (append '(foo) (list '(bar)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1916 ,'(setq ad-dO-vAr (cdr ad-dO-vAr)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1917 ,(car (cdr (cdr varform))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1918 ;;ok, this wastes some cons cells but only during compilation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1919 (if (catch 'contains-return
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1920 (ad-substitute-tree
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1921 (function (lambda (subtree)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1922 (cond ((eq (car-safe subtree) 'ad-dolist))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1923 ((eq (car-safe subtree) 'ad-do-return)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1924 (throw 'contains-return t)))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1925 'identity body)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1926 nil)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1927 `(catch 'ad-dO-eXiT ,expansion)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1928 expansion)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1929
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1930 (defmacro ad-do-return (value)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1931 `(throw 'ad-dO-eXiT ,value))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1932
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1933 (if (not (get 'ad-dolist 'lisp-indent-hook))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1934 (put 'ad-dolist 'lisp-indent-hook 1))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1935
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1936
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1937 ;; @@ 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
1938 ;; =================================================
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1939 ;; 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
1940 ;; 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
1941 ;; 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
1942
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1943 (defmacro ad-save-real-definition (function)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1944 (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
1945 ;; 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
1946 (require 'byte-compile "bytecomp")
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1947 `(if (not (fboundp ',saved-function))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1948 (progn (fset ',saved-function (symbol-function ',function))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1949 ;; Copy byte-compiler properties:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1950 ,@(if (get function 'byte-compile)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1951 `((put ',saved-function 'byte-compile
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1952 ',(get function 'byte-compile))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1953 ,@(if (get function 'byte-opcode)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1954 `((put ',saved-function 'byte-opcode
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1955 ',(get function 'byte-opcode))))))))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1956
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1957 (defun ad-save-real-definitions ()
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1958 ;; 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
1959 ;; 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
1960 ;; 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
1961 (ad-save-real-definition fset)
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
1962 (ad-save-real-definition documentation))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1963
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1964 (ad-save-real-definitions)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1965
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
1966
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1967 ;; @@ Advice info access fns:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1968 ;; ==========================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1969
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1970 ;; 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
1971 ;; advice-info property of the function symbol. It is stored as an
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1972 ;; alist of the following format:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1973 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1974 ;; ((active . t/nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1975 ;; (before adv1 adv2 ...)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1976 ;; (around adv1 adv2 ...)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1977 ;; (after adv1 adv2 ...)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1978 ;; (activation adv1 adv2 ...)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1979 ;; (deactivation adv1 adv2 ...)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1980 ;; (origname . <symbol fbound to origdef>)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1981 ;; (cache . (<advised-definition> . <id>)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1982
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1983 ;; List of currently advised though not necessarily activated functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1984 ;; (this list is maintained as a completion table):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1985 (defvar ad-advised-functions nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1986
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1987 (defmacro ad-pushnew-advised-function (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1988 "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
1989 `(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
1990 (setq ad-advised-functions
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1991 (cons (list (symbol-name ,function))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1992 ad-advised-functions))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1993
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1994 (defmacro ad-pop-advised-function (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
1995 "Remove FUNCTION from `ad-advised-functions'."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1996 `(setq ad-advised-functions
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1997 (delq (assoc (symbol-name ,function) ad-advised-functions)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
1998 ad-advised-functions)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
1999
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2000 (defmacro ad-do-advised-functions (varform &rest body)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2001 "`ad-dolist'-style iterator that maps over `ad-advised-functions'.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2002 \(ad-do-advised-functions (VAR [RESULT-FORM])
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2003 BODY-FORM...)
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2004 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
2005 \(a symbol)."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2006 `(ad-dolist (,(car varform)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2007 ad-advised-functions
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2008 ,(car (cdr varform)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2009 (setq ,(car varform) (intern (car ,(car varform))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2010 ,@body))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2011
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2012 (if (not (get 'ad-do-advised-functions 'lisp-indent-hook))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2013 (put 'ad-do-advised-functions 'lisp-indent-hook 1))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2014
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2015 (defmacro ad-get-advice-info (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2016 `(get ,function 'ad-advice-info))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2017
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2018 (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
2019 `(put ,function 'ad-advice-info ,advice-info))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2020
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2021 (defmacro ad-copy-advice-info (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2022 `(ad-copy-tree (get ,function 'ad-advice-info)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2023
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2024 (defmacro ad-is-advised (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2025 "Return non-nil if FUNCTION has any advice info associated with it.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2026 This does not mean that the advice is also active."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2027 (list 'ad-get-advice-info function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2028
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2029 (defun ad-initialize-advice-info (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2030 "Initialize the advice info for FUNCTION.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2031 Assumes that FUNCTION has not yet been advised."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2032 (ad-pushnew-advised-function function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2033 (ad-set-advice-info function (list (cons 'active nil))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2034
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2035 (defmacro ad-get-advice-info-field (function field)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2036 "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
2037 `(cdr (assq ,field (ad-get-advice-info ,function))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2038
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2039 (defun ad-set-advice-info-field (function field value)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2040 "Destructively modify VALUE of the advice info FIELD of FUNCTION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2041 (and (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2042 (cond ((assq field (ad-get-advice-info function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2043 ;; A field with that name is already present:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2044 (rplacd (assq field (ad-get-advice-info function)) value))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2045 (t;; otherwise, create a new field with that name:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2046 (nconc (ad-get-advice-info function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2047 (list (cons field value)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2048
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2049 ;; 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
2050 (defun ad-is-active (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2051 "Return non-nil if FUNCTION is advised and activated."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2052 (ad-get-advice-info-field function 'active))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2053
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2054
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2055 ;; @@ Access fns for single pieces of advice and related predicates:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2056 ;; =================================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2057
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2058 (defun ad-make-advice (name protect enable definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2059 "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
2060 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
2061 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
2062 `(advice lambda ARGLIST [DOCSTRING] [INTERACTIVE-FORM] BODY...)'."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2063 (list name protect enable definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2064
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2065 ;; ad-find-advice uses the alist structure directly ->
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2066 ;; change if this data structure changes!!
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2067 (defmacro ad-advice-name (advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2068 (list 'car advice))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2069 (defmacro ad-advice-protected (advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2070 (list 'nth 1 advice))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2071 (defmacro ad-advice-enabled (advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2072 (list 'nth 2 advice))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2073 (defmacro ad-advice-definition (advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2074 (list 'nth 3 advice))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2075
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2076 (defun ad-advice-set-enabled (advice flag)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2077 (rplaca (cdr (cdr advice)) flag))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2078
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2079 (defun ad-class-p (thing)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2080 (memq thing ad-advice-classes))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2081 (defun ad-name-p (thing)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2082 (and thing (symbolp thing)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2083 (defun ad-position-p (thing)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2084 (or (natnump thing)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2085 (memq thing '(first last))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2086
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2087
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2088 ;; @@ Advice access functions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2089 ;; ===========================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2090
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2091 ;; List of defined advice classes:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2092 (defvar ad-advice-classes '(before around after activation deactivation))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2093
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2094 (defun ad-has-enabled-advice (function class)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2095 "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
2096 (ad-dolist (advice (ad-get-advice-info-field function class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2097 (if (ad-advice-enabled advice) (ad-do-return t))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2098
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2099 (defun ad-has-redefining-advice (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2100 "True if FUNCTION's advice info defines at least 1 redefining advice.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2101 Redefining advices affect the construction of an advised definition."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2102 (and (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2103 (or (ad-has-enabled-advice function 'before)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2104 (ad-has-enabled-advice function 'around)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2105 (ad-has-enabled-advice function 'after))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2106
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2107 (defun ad-has-any-advice (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2108 "True if the advice info of FUNCTION defines at least one advice."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2109 (and (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2110 (ad-dolist (class ad-advice-classes nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2111 (if (ad-get-advice-info-field function class)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2112 (ad-do-return t)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2113
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2114 (defun ad-get-enabled-advices (function class)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2115 "Return the list of enabled advices of FUNCTION in CLASS."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2116 (let (enabled-advices)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2117 (ad-dolist (advice (ad-get-advice-info-field function class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2118 (if (ad-advice-enabled advice)
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2119 (push advice enabled-advices)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2120 (reverse enabled-advices)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2121
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2122
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2123 ;; @@ 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
2124 ;; ================================================================
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 ;; 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
2127 ;; 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
2128 ;; 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
2129
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2130 ;; 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
2131 ;;
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2132 ;; fset(sym,newdef)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2133 ;; assign NEWDEF to SYM
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2134 ;; if (get SYM 'ad-advice-info)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
2135 ;; ad-activate-internal(SYM, nil)
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2136 ;; return (symbol-function SYM)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2137 ;;
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2138 ;; 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
2139 ;; 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
2140
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
2141 ;; 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
2142 ;; 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
2143 ;; 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
2144 ;; 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
2145 ;; `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
2146 ;; 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
2147 ;; 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
2148
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
2149 ;; 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
2150 (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
2151 "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
2152 nil)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2153
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2154 ;; This is just a copy of the above:
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
2155 (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
2156 "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
2157 nil)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2158
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
2159 ;; 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
2160 (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
2161
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2162 (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
2163 `(let ((ad-activate-on-top-level nil))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2164 ,@body))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2165
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2166 (defun ad-safe-fset (symbol definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2167 "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
2168 (ad-with-auto-activation-disabled
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2169 (ad-real-fset symbol definition)))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2170
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2171
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2172 ;; @@ Access functions for original definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2173 ;; ============================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2174 ;; The advice-info of an advised function contains its `origname' which is
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2175 ;; a symbol that is fbound to the original definition available at the first
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2176 ;; proper activation of the function after a legal re/definition. If the
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2177 ;; 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
2178 ;; 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
2179 ;; we need to use `ad-real-orig-definition'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2180
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2181 (defun ad-make-origname (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2182 "Make name to be used to call the original FUNCTION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2183 (intern (format "ad-Orig-%s" function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2184
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2185 (defmacro ad-get-orig-definition (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2186 `(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
2187 (if (fboundp origname)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2188 (symbol-function origname))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2189
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2190 (defmacro ad-set-orig-definition (function definition)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2191 `(ad-safe-fset
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2192 (ad-get-advice-info-field function 'origname) ,definition))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2193
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2194 (defmacro ad-clear-orig-definition (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2195 `(fmakunbound (ad-get-advice-info-field ,function 'origname)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2196
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2197
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2198 ;; @@ Interactive input functions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2199 ;; ===============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2200
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2201 (defun ad-read-advised-function (&optional prompt predicate default)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2202 "Read name of advised function with completion from the minibuffer.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2203 An optional PROMPT will be used to prompt for the function. PREDICATE
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2204 plays the same role as for `try-completion' (which see). DEFAULT will
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2205 be returned on empty input (defaults to the first advised function for
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2206 which PREDICATE returns non-nil)."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2207 (if (null ad-advised-functions)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2208 (error "ad-read-advised-function: There are no advised functions"))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2209 (setq default
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2210 (or default
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2211 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2212 (if (or (null predicate)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2213 (funcall predicate function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2214 (ad-do-return function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2215 (error "ad-read-advised-function: %s"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2216 "There are no qualifying advised functions")))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2217 (let* ((ad-pReDiCaTe predicate)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2218 (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2219 (completing-read
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2220 (format "%s(default %s) " (or prompt "Function: ") default)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2221 ad-advised-functions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2222 (if predicate
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2223 (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2224 (lambda (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2225 ;; Oops, no closures - the joys of dynamic scoping:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2226 ;; `predicate' clashed with the `predicate' argument
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2227 ;; of Lemacs' `completing-read'.....
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2228 (funcall ad-pReDiCaTe (intern (car function))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2229 t)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2230 (if (equal function "")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2231 (if (ad-is-advised default)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2232 default
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2233 (error "ad-read-advised-function: `%s' is not advised" default))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2234 (intern function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2235
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2236 (defvar ad-advice-class-completion-table
29579
05016ef95d0f (ad-advice-class-completion-table)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 26627
diff changeset
2237 (mapcar (lambda (class) (list (symbol-name class)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2238 ad-advice-classes))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2239
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2240 (defun ad-read-advice-class (function &optional prompt default)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2241 "Read a legal advice class with completion from the minibuffer.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2242 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
2243 be returned on empty input (defaults to the first non-empty advice
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2244 class of FUNCTION)."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2245 (setq default
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2246 (or default
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2247 (ad-dolist (class ad-advice-classes)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2248 (if (ad-get-advice-info-field function class)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2249 (ad-do-return class)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2250 (error "ad-read-advice-class: `%s' has no advices" function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2251 (let ((class (completing-read
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2252 (format "%s(default %s) " (or prompt "Class: ") default)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2253 ad-advice-class-completion-table nil t)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2254 (if (equal class "")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2255 default
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2256 (intern class))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2257
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2258 (defun ad-read-advice-name (function class &optional prompt)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2259 "Read name of existing advice of CLASS for FUNCTION with completion.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2260 An optional PROMPT is used to prompt for the name."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2261 (let* ((name-completion-table
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2262 (mapcar (function (lambda (advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2263 (list (symbol-name (ad-advice-name advice)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2264 (ad-get-advice-info-field function class)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2265 (default
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2266 (if (null name-completion-table)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2267 (error "ad-read-advice-name: `%s' has no %s advice"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2268 function class)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2269 (car (car name-completion-table))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2270 (prompt (format "%s(default %s) " (or prompt "Name: ") default))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2271 (name (completing-read prompt name-completion-table nil t)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2272 (if (equal name "")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2273 (intern default)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2274 (intern name))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2275
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2276 (defun ad-read-advice-specification (&optional prompt)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2277 "Read a complete function/class/name specification from minibuffer.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2278 The list of read symbols will be returned. The optional PROMPT will
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2279 be used to prompt for the function."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2280 (let* ((function (ad-read-advised-function prompt))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2281 (class (ad-read-advice-class function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2282 (name (ad-read-advice-name function class)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2283 (list function class name)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2284
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2285 ;; Use previous regexp as a default:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2286 (defvar ad-last-regexp "")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2287
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2288 (defun ad-read-regexp (&optional prompt)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2289 "Read a regular expression from the minibuffer."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2290 (let ((regexp (read-from-minibuffer
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2291 (concat (or prompt "Regular expression: ")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2292 (if (equal ad-last-regexp "") ""
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2293 (format "(default \"%s\") " ad-last-regexp))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2294 (setq ad-last-regexp
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2295 (if (equal regexp "") ad-last-regexp regexp))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2296
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2297
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2298 ;; @@ Finding, enabling, adding and removing pieces of advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2299 ;; ===========================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2300
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2301 (defmacro ad-find-advice (function class name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2302 "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
2303 `(assq ,name (ad-get-advice-info-field ,function ,class)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2304
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2305 (defun ad-advice-position (function class name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2306 "Return position of first advice of FUNCTION in CLASS with NAME."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2307 (let* ((found-advice (ad-find-advice function class name))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2308 (advices (ad-get-advice-info-field function class)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2309 (if found-advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2310 (- (length advices) (length (memq found-advice advices))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2311
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2312 (defun ad-find-some-advice (function class name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2313 "Find the first of FUNCTION's advices in CLASS matching NAME.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2314 NAME can be a symbol or a regular expression matching part of an advice name.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2315 If CLASS is `any' all legal advice classes will be checked."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2316 (if (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2317 (let (found-advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2318 (ad-dolist (advice-class ad-advice-classes)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2319 (if (or (eq class 'any) (eq advice-class class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2320 (setq found-advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2321 (ad-dolist (advice (ad-get-advice-info-field
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2322 function advice-class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2323 (if (or (and (stringp name)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2324 (string-match
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2325 name (symbol-name
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2326 (ad-advice-name advice))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2327 (eq name (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2328 (ad-do-return advice)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2329 (if found-advice (ad-do-return found-advice))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2330
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2331 (defun ad-enable-advice-internal (function class name flag)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2332 "Set enable FLAG of FUNCTION's advices in CLASS matching NAME.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2333 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
2334 expression and all advices whose name contain a match for it will be
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2335 affected. If CLASS is `any' advices in all legal advice classes will be
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2336 considered. The number of changed advices will be returned (or nil if
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2337 FUNCTION was not advised)."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2338 (if (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2339 (let ((matched-advices 0))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2340 (ad-dolist (advice-class ad-advice-classes)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2341 (if (or (eq class 'any) (eq advice-class class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2342 (ad-dolist (advice (ad-get-advice-info-field
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2343 function advice-class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2344 (cond ((or (and (stringp name)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2345 (string-match
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2346 name (symbol-name (ad-advice-name advice))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2347 (eq name (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2348 (setq matched-advices (1+ matched-advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2349 (ad-advice-set-enabled advice flag))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2350 matched-advices)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2351
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2352 (defun ad-enable-advice (function class name)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2353 "Enables the advice of FUNCTION with CLASS and NAME."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2354 (interactive (ad-read-advice-specification "Enable advice of: "))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2355 (if (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2356 (if (eq (ad-enable-advice-internal function class name t) 0)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2357 (error "ad-enable-advice: `%s' has no %s advice matching `%s'"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2358 function class name))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2359 (error "ad-enable-advice: `%s' is not advised" function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2360
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2361 (defun ad-disable-advice (function class name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2362 "Disable the advice of FUNCTION with CLASS and NAME."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2363 (interactive (ad-read-advice-specification "Disable advice of: "))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2364 (if (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2365 (if (eq (ad-enable-advice-internal function class name nil) 0)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2366 (error "ad-disable-advice: `%s' has no %s advice matching `%s'"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2367 function class name))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2368 (error "ad-disable-advice: `%s' is not advised" function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2369
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2370 (defun ad-enable-regexp-internal (regexp class flag)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2371 "Set enable FLAGs of all CLASS advices whose name contains a REGEXP match.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2372 If CLASS is `any' all legal advice classes are considered. The number of
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2373 affected advices will be returned."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2374 (let ((matched-advices 0))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2375 (ad-do-advised-functions (advised-function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2376 (setq matched-advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2377 (+ matched-advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2378 (or (ad-enable-advice-internal
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2379 advised-function class regexp flag)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2380 0))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2381 matched-advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2382
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2383 (defun ad-enable-regexp (regexp)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2384 "Enables all advices with names that contain a match for REGEXP.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2385 All currently advised functions will be considered."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2386 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2387 (list (ad-read-regexp "Enable advices via regexp: ")))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2388 (let ((matched-advices (ad-enable-regexp-internal regexp 'any t)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2389 (if (interactive-p)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2390 (message "%d matching advices enabled" matched-advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2391 matched-advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2392
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2393 (defun ad-disable-regexp (regexp)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2394 "Disable all advices with names that contain a match for REGEXP.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2395 All currently advised functions will be considered."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2396 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2397 (list (ad-read-regexp "Disable advices via regexp: ")))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2398 (let ((matched-advices (ad-enable-regexp-internal regexp 'any nil)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2399 (if (interactive-p)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2400 (message "%d matching advices disabled" matched-advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2401 matched-advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2402
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2403 (defun ad-remove-advice (function class name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2404 "Remove FUNCTION's advice with NAME from its advices in CLASS.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2405 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
2406 in that CLASS."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2407 (interactive (ad-read-advice-specification "Remove advice of: "))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2408 (if (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2409 (let* ((advice-to-remove (ad-find-advice function class name)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2410 (if advice-to-remove
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2411 (ad-set-advice-info-field
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2412 function class
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2413 (delq advice-to-remove (ad-get-advice-info-field function class)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2414 (error "ad-remove-advice: `%s' has no %s advice `%s'"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2415 function class name)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2416 (error "ad-remove-advice: `%s' is not advised" function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2417
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2418 ;;;###autoload
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2419 (defun ad-add-advice (function advice class position)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2420 "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
2421 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
2422 CLASS then POSITION determines where the new piece will go. The value
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2423 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
2424 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
2425 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
2426 name, then the position argument will be ignored and the old advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2427 will be overwritten with the new one.
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2428 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
2429 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
2430 will clear the cache."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2431 (cond ((not (ad-is-advised function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2432 (ad-initialize-advice-info function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2433 (ad-set-advice-info-field
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2434 function 'origname (ad-make-origname function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2435 (let* ((previous-position
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2436 (ad-advice-position function class (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2437 (advices (ad-get-advice-info-field function class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2438 ;; Determine a numerical position for the new advice:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2439 (position (cond (previous-position)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2440 ((eq position 'first) 0)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2441 ((eq position 'last) (length advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2442 ((numberp position)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2443 (max 0 (min position (length advices))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2444 (t 0))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2445 ;; Check whether we have to clear the cache:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2446 (if (memq (ad-advice-name advice) (ad-get-cache-class-id function class))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2447 (ad-clear-cache function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2448 (if previous-position
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2449 (setcar (nthcdr position advices) advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2450 (if (= position 0)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2451 (ad-set-advice-info-field function class (cons advice advices))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2452 (setcdr (nthcdr (1- position) advices)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2453 (cons advice (nthcdr position advices)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2454
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2455
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2456 ;; @@ Accessing and manipulating function definitions:
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 (defmacro ad-macrofy (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2460 "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
2461 `(cons 'macro ,definition))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2462
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2463 (defmacro ad-lambdafy (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2464 "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
2465 `(cdr ,definition))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2466
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2467 ;; There is no way to determine whether some subr is a special form or not,
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2468 ;; hence we need this list (which is probably out of date):
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2469 (defvar ad-special-forms
25260
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2470 (let ((tem '(and catch cond condition-case defconst defmacro
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2471 defun defvar function if interactive let let*
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2472 or prog1 prog2 progn quote save-current-buffer
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2473 save-excursion save-restriction save-window-excursion
33665
b51b000b2c50 (ad-special-forms): Correct the conditional inclusion of `track-mouse'.
Miles Bader <miles@gnu.org>
parents: 29579
diff changeset
2474 setq setq-default unwind-protect while
25260
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2475 with-output-to-temp-buffer)))
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2476 ;; track-mouse could be void in some configurations.
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2477 (if (fboundp 'track-mouse)
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2478 (push 'track-mouse tem))
25260
0c8c07d1d12f (ad-special-forms): Use track-mouse iff bound.
Karl Heuer <kwzh@gnu.org>
parents: 25208
diff changeset
2479 (mapcar 'symbol-function tem)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2480
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2481 (defmacro ad-special-form-p (definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2482 ;;"non-nil if DEFINITION is a special form."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2483 (list 'memq definition 'ad-special-forms))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2484
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2485 (defmacro ad-interactive-p (definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2486 ;;"non-nil if DEFINITION can be called interactively."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2487 (list 'commandp definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2488
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2489 (defmacro ad-subr-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 subr."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2491 (list 'subrp definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2492
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2493 (defmacro ad-macro-p (definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2494 ;;"non-nil if DEFINITION is a macro."
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2495 `(eq (car-safe ,definition) 'macro))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2496
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2497 (defmacro ad-lambda-p (definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2498 ;;"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
2499 `(eq (car-safe ,definition) 'lambda))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2500
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2501 ;; see ad-make-advice for the format of advice definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2502 (defmacro ad-advice-p (definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2503 ;;"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
2504 `(eq (car-safe ,definition) 'advice))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2505
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2506 ;; Emacs/Lemacs cross-compatibility
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2507 ;; (compiled-function-p is an obsolete function in Emacs):
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2508 (if (and (not (fboundp 'byte-code-function-p))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2509 (fboundp 'compiled-function-p))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2510 (ad-safe-fset 'byte-code-function-p 'compiled-function-p))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2511
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2512 (defmacro ad-compiled-p (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2513 "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
2514 `(or (byte-code-function-p ,definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2515 (and (ad-macro-p ,definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2516 (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
2517
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2518 (defmacro ad-compiled-code (compiled-definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2519 "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
2520 `(if (ad-macro-p ,compiled-definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2521 (ad-lambdafy ,compiled-definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2522 ,compiled-definition))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2523
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2524 (defun ad-lambda-expression (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2525 "Return the lambda expression of a function/macro/advice DEFINITION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2526 (cond ((ad-lambda-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2527 definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2528 ((ad-macro-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2529 (ad-lambdafy definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2530 ((ad-advice-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2531 (cdr definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2532 (t nil)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2533
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2534 (defun ad-arglist (definition &optional name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2535 "Return the argument list of DEFINITION.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2536 If DEFINITION could be from a subr then its NAME should be
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2537 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
2538 (cond ((ad-compiled-p definition)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2539 (aref (ad-compiled-code definition) 0))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2540 ((consp definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2541 (car (cdr (ad-lambda-expression definition))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2542 ((ad-subr-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2543 (if name
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2544 (ad-subr-arglist name)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2545 ;; otherwise get it from its printed representation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2546 (setq name (format "%s" definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2547 (string-match "^#<subr \\([^>]+\\)>$" name)
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2548 (ad-subr-arglist (intern (match-string 1 name)))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2549
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2550 ;; Store subr-args as `((arg1 arg2 ...))' so I can distinguish
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2551 ;; a defined empty arglist `(nil)' from an undefined arglist:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2552 (defmacro ad-define-subr-args (subr arglist)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2553 `(put ,subr 'ad-subr-arglist (list ,arglist)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2554 (defmacro ad-undefine-subr-args (subr)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2555 `(put ,subr 'ad-subr-arglist nil))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2556 (defmacro ad-subr-args-defined-p (subr)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2557 `(get ,subr 'ad-subr-arglist))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2558 (defmacro ad-get-subr-args (subr)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2559 `(car (get ,subr 'ad-subr-arglist)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2560
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2561 (defun ad-subr-arglist (subr-name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2562 "Retrieve arglist of the subr with SUBR-NAME.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2563 Either use the one stored under the `ad-subr-arglist' property,
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2564 or try to retrieve it from the docstring and cache it under
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2565 that property, or otherwise use `(&rest ad-subr-args)'."
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2566 (cond ((ad-subr-args-defined-p subr-name)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2567 (ad-get-subr-args subr-name))
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2568 ;; says jwz: Should use this for Lemacs 19.8 and above:
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2569 ;;((fboundp 'subr-min-args)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2570 ;; ...)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2571 ;; says hans: I guess what Jamie means is that I should use the values
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2572 ;; of `subr-min-args' and `subr-max-args' to construct the subr arglist
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2573 ;; without having to look it up via parsing the docstring, e.g.,
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2574 ;; values 1 and 2 would suggest `(arg1 &optional arg2)' as an
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2575 ;; argument list. However, that won't work because there is no
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2576 ;; way to distinguish a subr with args `(a &optional b &rest c)' from
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2577 ;; one with args `(a &rest c)' using that mechanism. Also, the argument
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2578 ;; names from the docstring are more meaningful. Hence, I'll stick with
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2579 ;; the old way of doing things.
8458
a95ca44cec95 (ad-subr-arglist): Adapted to new DOC file format.
Richard M. Stallman <rms@gnu.org>
parents: 8445
diff changeset
2580 (t (let ((doc (or (ad-real-documentation subr-name t) "")))
a95ca44cec95 (ad-subr-arglist): Adapted to new DOC file format.
Richard M. Stallman <rms@gnu.org>
parents: 8445
diff changeset
2581 (cond ((string-match "^\\(([^\)]+)\\)\n?\\'" doc)
a95ca44cec95 (ad-subr-arglist): Adapted to new DOC file format.
Richard M. Stallman <rms@gnu.org>
parents: 8445
diff changeset
2582 (ad-define-subr-args
a95ca44cec95 (ad-subr-arglist): Adapted to new DOC file format.
Richard M. Stallman <rms@gnu.org>
parents: 8445
diff changeset
2583 subr-name
a95ca44cec95 (ad-subr-arglist): Adapted to new DOC file format.
Richard M. Stallman <rms@gnu.org>
parents: 8445
diff changeset
2584 (cdr (car (read-from-string
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2585 (downcase (match-string 1 doc))))))
8458
a95ca44cec95 (ad-subr-arglist): Adapted to new DOC file format.
Richard M. Stallman <rms@gnu.org>
parents: 8445
diff changeset
2586 (ad-get-subr-args subr-name))
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2587 ;; This is actually an error.
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2588 (t '(&rest ad-subr-args)))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2589
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2590 (defun ad-docstring (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2591 "Return the unexpanded docstring of DEFINITION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2592 (let ((docstring
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2593 (if (ad-compiled-p definition)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2594 (ad-real-documentation definition t)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2595 (car (cdr (cdr (ad-lambda-expression definition)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2596 (if (or (stringp docstring)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2597 (natnump docstring))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2598 docstring)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2599
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2600 (defun ad-interactive-form (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2601 "Return the interactive form of DEFINITION."
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2602 (cond ((ad-compiled-p definition)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2603 (and (commandp definition)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2604 (list 'interactive (aref (ad-compiled-code definition) 5))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2605 ((or (ad-advice-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2606 (ad-lambda-p definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2607 (commandp (ad-lambda-expression definition)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2608
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2609 (defun ad-body-forms (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2610 "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
2611 (cond ((ad-compiled-p definition)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2612 nil)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2613 ((consp definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2614 (nthcdr (+ (if (ad-docstring definition) 1 0)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2615 (if (ad-interactive-form definition) 1 0))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2616 (cdr (cdr (ad-lambda-expression definition)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2617
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2618 ;; Matches the docstring of an advised definition.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2619 ;; The first group of the regexp matches the function name:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2620 (defvar ad-advised-definition-docstring-regexp "^\\$ad-doc: \\(.+\\)\\$$")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2621
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2622 (defun ad-make-advised-definition-docstring (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2623 "Make an identifying docstring for the advised definition of FUNCTION.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2624 Put function name into the documentation string so we can infer
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2625 the name of the advised function from the docstring. This is needed
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2626 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
2627 definition (also see the defadvice for `documentation')."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2628 (format "$ad-doc: %s$" (prin1-to-string function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2629
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2630 (defun ad-advised-definition-p (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2631 "Return non-nil if DEFINITION was generated from advice information."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2632 (if (or (ad-lambda-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2633 (ad-macro-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2634 (ad-compiled-p definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2635 (let ((docstring (ad-docstring definition)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2636 (and (stringp docstring)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2637 (string-match
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2638 ad-advised-definition-docstring-regexp docstring)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2639
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2640 (defun ad-definition-type (definition)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2641 "Return symbol that describes the type of DEFINITION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2642 (if (ad-macro-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2643 'macro
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2644 (if (ad-subr-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2645 (if (ad-special-form-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2646 'special-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2647 'subr)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2648 (if (or (ad-lambda-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2649 (ad-compiled-p definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2650 'function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2651 (if (ad-advice-p definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2652 'advice)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2653
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2654 (defun ad-has-proper-definition (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2655 "True if FUNCTION is a symbol with a proper definition.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2656 For that it has to be fbound with a non-autoload definition."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2657 (and (symbolp function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2658 (fboundp function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2659 (not (eq (car-safe (symbol-function function)) 'autoload))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2660
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2661 ;; The following two are necessary for the sake of packages such as
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2662 ;; ange-ftp which redefine functions via fcell indirection:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2663 (defun ad-real-definition (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2664 "Find FUNCTION's definition at the end of function cell indirection."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2665 (if (ad-has-proper-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2666 (let ((definition (symbol-function function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2667 (if (symbolp definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2668 (ad-real-definition definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2669 definition))))
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-real-orig-definition (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2672 "Find FUNCTION's real original definition starting from its `origname'."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2673 (if (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2674 (ad-real-definition (ad-get-advice-info-field function 'origname))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2675
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2676 (defun ad-is-compilable (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2677 "True if FUNCTION has an interpreted definition that can be compiled."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2678 (and (ad-has-proper-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2679 (or (ad-lambda-p (symbol-function function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2680 (ad-macro-p (symbol-function function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2681 (not (ad-compiled-p (symbol-function function)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2682
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2683 (defun ad-compile-function (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2684 "Byte-compiles FUNCTION (or macro) if it is not yet compiled."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2685 (interactive "aByte-compile function: ")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2686 (if (ad-is-compilable function)
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2687 ;; Need to turn off auto-activation
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2688 ;; because `byte-compile' uses `fset':
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
2689 (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
2690 (require 'bytecomp)
73cafacdf14f (ad-compile-function): Disable cl-function warnings if cl is loaded.
Richard M. Stallman <rms@gnu.org>
parents: 45019
diff changeset
2691 (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
2692 (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
2693 (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
2694 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
2695 (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
2696 (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
2697 (remq 'cl-functions byte-compile-warnings)))
41936
2fba35852455 (ad-compile-function):
Richard M. Stallman <rms@gnu.org>
parents: 41608
diff changeset
2698 (fset symbol (symbol-function function))
2fba35852455 (ad-compile-function):
Richard M. Stallman <rms@gnu.org>
parents: 41608
diff changeset
2699 (byte-compile symbol)
2fba35852455 (ad-compile-function):
Richard M. Stallman <rms@gnu.org>
parents: 41608
diff changeset
2700 (fset function (symbol-function symbol))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2701
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2702
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2703 ;; @@ Constructing advised definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2704 ;; ====================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2705 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2706 ;; Main design decisions about the form of advised definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2707 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2708 ;; A) How will original definitions be called?
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2709 ;; B) What will argument lists of advised functions look like?
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2710 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2711 ;; Ad A)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2712 ;; I chose to use function indirection for all four types of original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2713 ;; definitions (functions, macros, subrs and special forms), i.e., create
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2714 ;; 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
2715 ;; definition and call it according to type and arguments. Functions and
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2716 ;; 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
2717 ;; `(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
2718 ;; use `apply'. Macros will be called with
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2719 ;; `(macroexpand '(ad-Orig-<name> ....))', and special forms also need a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2720 ;; form like that with `eval' instead of `macroexpand'.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2721 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2722 ;; Ad B)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2723 ;; Use original arguments where possible and `(&rest ad-subr-args)'
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2724 ;; otherwise, even though this seems to be more complicated and less
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2725 ;; uniform than a general `(&rest args)' approach. My reason to still
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2726 ;; 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
2727 ;; efficient form for the advised function, and portability (e.g., to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2728 ;; make the same advice work regardless of whether something is a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2729 ;; function or a subr) can still be achieved with argument access macros.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2730
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2731
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2732 (defun ad-prognify (forms)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2733 (cond ((<= (length forms) 1)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2734 (car forms))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2735 (t (cons 'progn forms))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2736
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2737 ;; @@@ Accessing argument lists:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2738 ;; =============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2739
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2740 (defun ad-parse-arglist (arglist)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2741 "Parse ARGLIST into its required, optional and rest parameters.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2742 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
2743 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
2744 is the name of an optional rest parameter (or nil)."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2745 (let* (required optional rest)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2746 (setq rest (car (cdr (memq '&rest arglist))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2747 (if rest (setq arglist (reverse (cdr (memq '&rest (reverse arglist))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2748 (setq optional (cdr (memq '&optional arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2749 (if optional
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2750 (setq required (reverse (cdr (memq '&optional (reverse arglist)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2751 (setq required arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2752 (list required optional rest)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2753
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2754 (defun ad-retrieve-args-form (arglist)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2755 "Generate a form which evaluates into names/values/types of ARGLIST.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2756 When the form gets evaluated within a function with that argument list
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2757 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
2758 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
2759 element is its actual current value, and the third element is either
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2760 `required', `optional' or `rest' depending on the type of the argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2761 (let* ((parsed-arglist (ad-parse-arglist arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2762 (rest (nth 2 parsed-arglist)))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2763 `(list
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2764 ,@(mapcar (function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2765 (lambda (req)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2766 `(list ',req ,req 'required)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2767 (nth 0 parsed-arglist))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2768 ,@(mapcar (function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2769 (lambda (opt)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2770 `(list ',opt ,opt 'optional)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2771 (nth 1 parsed-arglist))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2772 ,@(if rest (list `(list ',rest ,rest 'rest))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2773
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2774 (defun ad-arg-binding-field (binding field)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2775 (cond ((eq field 'name) (car binding))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2776 ((eq field 'value) (car (cdr binding)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2777 ((eq field 'type) (car (cdr (cdr binding))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2778
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2779 (defun ad-list-access (position list)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2780 (cond ((= position 0) list)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2781 ((= position 1) (list 'cdr list))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2782 (t (list 'nthcdr position list))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2783
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2784 (defun ad-element-access (position list)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2785 (cond ((= position 0) (list 'car list))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2786 ((= position 1) `(car (cdr ,list)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2787 (t (list 'nth position list))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2788
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2789 (defun ad-access-argument (arglist index)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2790 "Tell how to access ARGLIST's actual argument at position INDEX.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2791 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
2792 to be accessed, it returns a list with the index and name."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2793 (let* ((parsed-arglist (ad-parse-arglist arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2794 (reqopt-args (append (nth 0 parsed-arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2795 (nth 1 parsed-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2796 (rest-arg (nth 2 parsed-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2797 (cond ((< index (length reqopt-args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2798 (nth index reqopt-args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2799 (rest-arg
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2800 (list (- index (length reqopt-args)) rest-arg)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2801
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2802 (defun ad-get-argument (arglist index)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2803 "Return form to access ARGLIST's actual argument at position INDEX."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2804 (let ((argument-access (ad-access-argument arglist index)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2805 (cond ((consp argument-access)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2806 (ad-element-access
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2807 (car argument-access) (car (cdr argument-access))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2808 (argument-access))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2809
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2810 (defun ad-set-argument (arglist index value-form)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2811 "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
2812 (let ((argument-access (ad-access-argument arglist index)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2813 (cond ((consp argument-access)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2814 ;; 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
2815 `(setcar ,(ad-list-access
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2816 (car argument-access) (car (cdr argument-access)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2817 ,value-form))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2818 (argument-access
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2819 `(setq ,argument-access ,value-form))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2820 (t (error "ad-set-argument: No argument at position %d of `%s'"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2821 index arglist)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2822
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2823 (defun ad-get-arguments (arglist index)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2824 "Return form to access all actual arguments starting at position INDEX."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2825 (let* ((parsed-arglist (ad-parse-arglist arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2826 (reqopt-args (append (nth 0 parsed-arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2827 (nth 1 parsed-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2828 (rest-arg (nth 2 parsed-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2829 args-form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2830 (if (< index (length reqopt-args))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2831 (setq args-form `(list ,@(nthcdr index reqopt-args))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2832 (if rest-arg
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2833 (if args-form
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2834 (setq args-form `(nconc ,args-form ,rest-arg))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2835 (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
2836 rest-arg))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2837 args-form))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2838
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2839 (defun ad-set-arguments (arglist index values-form)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2840 "Make form to assign elements of VALUES-FORM as actual ARGLIST args.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2841 The assignment starts at position INDEX."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2842 (let ((values-index 0)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2843 argument-access set-forms)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2844 (while (setq argument-access (ad-access-argument arglist index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2845 (if (symbolp argument-access)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2846 (setq set-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2847 (cons (ad-set-argument
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2848 arglist index
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2849 (ad-element-access values-index 'ad-vAlUeS))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2850 set-forms))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2851 (setq set-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2852 (cons (if (= (car argument-access) 0)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2853 (list 'setq
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2854 (car (cdr argument-access))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2855 (ad-list-access values-index 'ad-vAlUeS))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2856 (list 'setcdr
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2857 (ad-list-access (1- (car argument-access))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2858 (car (cdr argument-access)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2859 (ad-list-access values-index 'ad-vAlUeS)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2860 set-forms))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2861 ;; terminate loop
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2862 (setq arglist nil))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2863 (setq index (1+ index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2864 (setq values-index (1+ values-index)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2865 (if (null set-forms)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2866 (error "ad-set-arguments: No argument at position %d of `%s'"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2867 index arglist)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2868 (if (= (length set-forms) 1)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2869 ;; 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
2870 (ad-substitute-tree
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2871 (function (lambda (form) (eq form 'ad-vAlUeS)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2872 (function (lambda (form) values-form))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2873 (car set-forms))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2874 ;; ...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
2875 `(let ((ad-vAlUeS ,values-form))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2876 ,@(reverse set-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2877 ;; work around the old backquote bug:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
2878 ,'ad-vAlUeS)))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2879
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2880 (defun ad-insert-argument-access-forms (definition arglist)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2881 "Expands arg-access text macros in DEFINITION according to ARGLIST."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2882 (ad-substitute-tree
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2883 (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2884 (lambda (form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2885 (or (eq form 'ad-arg-bindings)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2886 (and (memq (car-safe form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2887 '(ad-get-arg ad-get-args ad-set-arg ad-set-args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2888 (integerp (car-safe (cdr form)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2889 (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2890 (lambda (form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2891 (if (eq form 'ad-arg-bindings)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2892 (ad-retrieve-args-form arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2893 (let ((accessor (car form))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2894 (index (car (cdr form)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2895 (val (car (cdr (ad-insert-argument-access-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2896 (cdr form) arglist)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2897 (cond ((eq accessor 'ad-get-arg)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2898 (ad-get-argument arglist index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2899 ((eq accessor 'ad-set-arg)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2900 (ad-set-argument arglist index val))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2901 ((eq accessor 'ad-get-args)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2902 (ad-get-arguments arglist index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2903 ((eq accessor 'ad-set-args)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2904 (ad-set-arguments arglist index val)))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2905 definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2906
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2907 ;; @@@ Mapping argument lists:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2908 ;; ===========================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2909 ;; Here is the problem:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2910 ;; 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
2911 ;; 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
2912 ;; 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
2913 ;; 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
2914 ;; The mapping should work for any two argument lists.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2915
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2916 (defun ad-map-arglists (source-arglist target-arglist)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2917 "Make `funcall/apply' form to map SOURCE-ARGLIST to TARGET-ARGLIST.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2918 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
2919 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
2920 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
2921 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
2922 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
2923 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
2924 `(funcall function a (car args) (car (cdr args)) (nth 2 args))'."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2925 (let* ((parsed-source-arglist (ad-parse-arglist source-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2926 (source-reqopt-args (append (nth 0 parsed-source-arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2927 (nth 1 parsed-source-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2928 (source-rest-arg (nth 2 parsed-source-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2929 (parsed-target-arglist (ad-parse-arglist target-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2930 (target-reqopt-args (append (nth 0 parsed-target-arglist)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2931 (nth 1 parsed-target-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2932 (target-rest-arg (nth 2 parsed-target-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2933 (need-apply (and source-rest-arg target-rest-arg))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2934 (target-arg-index -1))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2935 ;; This produces ``error-proof'' target function calls with the exception
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2936 ;; 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
2937 ;; 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
2938 (append (list (if need-apply 'apply 'funcall) 'function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2939 (cond (need-apply
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2940 ;; `apply' can take care of that directly:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2941 (append source-reqopt-args (list source-rest-arg)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2942 (t (mapcar (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2943 (lambda (arg)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2944 (setq target-arg-index (1+ target-arg-index))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2945 (ad-get-argument
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2946 source-arglist target-arg-index)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2947 (append target-reqopt-args
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2948 (and target-rest-arg
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2949 ;; If we have a rest arg gobble up
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2950 ;; remaining source args:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2951 (nthcdr (length target-reqopt-args)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2952 source-reqopt-args)))))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2953
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2954 (defun ad-make-mapped-call (source-arglist target-arglist target-function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
2955 "Make form to call TARGET-FUNCTION with args from SOURCE-ARGLIST."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2956 (let* ((mapped-form (ad-map-arglists source-arglist target-arglist)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2957 (if (eq (car mapped-form) 'funcall)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2958 (cons target-function (cdr (cdr mapped-form)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2959 (prog1 mapped-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2960 (setcar (cdr mapped-form) (list 'quote target-function))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2961
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2962 ;; @@@ Making an advised documentation string:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2963 ;; ===========================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2964 ;; 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
2965 ;; at the time the advised `documentation' function is called. This has the
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2966 ;; following advantages:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2967 ;; 1) command-key substitutions will automatically be correct
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2968 ;; 2) No wasted string space due to big advised docstrings in caches or
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2969 ;; compiled files that contain preactivations
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2970 ;; The overall overhead for this should be negligible because people normally
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2971 ;; don't lookup documentation for the same function over and over again.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2972
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2973 (defun ad-make-single-advice-docstring (advice class &optional style)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
2974 (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
2975 (cond ((eq style 'plain)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2976 advice-docstring)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2977 ((eq style 'freeze)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2978 (format "Permanent %s-advice `%s':%s%s"
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2979 class (ad-advice-name advice)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2980 (if advice-docstring "\n" "")
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2981 (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
2982 (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
2983 (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
2984 (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
2985 (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
2986 advice-docstring)
76f5f50e7742 (ad-make-single-advice-docstring): Treat case with no doctring specially.
Dave Love <fx@gnu.org>
parents: 24875
diff changeset
2987 (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
2988 (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
2989 (ad-advice-name advice)))))))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2990
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
2991 (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
2992
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
2993 (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
2994 "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
2995 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
2996 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
2997 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
2998 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
2999 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
3000 in any of these classes."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3001 (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
3002 (origtype (symbol-name (ad-definition-type origdef)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3003 (origdoc
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3004 ;; 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
3005 (ad-real-documentation origdef t))
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3006 (usage (help-split-fundoc origdoc function))
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3007 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
3008 (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
3009 (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
3010 (unless (eq style 'plain)
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3011 (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
3012 (ad-dolist (class ad-advice-classes)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3013 (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
3014 (setq advice-docstring
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3015 (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
3016 (if advice-docstring
50800
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3017 (push advice-docstring paragraphs))))
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3018 (setq origdoc (if paragraphs
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3019 ;; separate paragraphs with blank lines:
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3020 (mapconcat 'identity (nreverse paragraphs) "\n\n")))
7fe53d25e220 (ad-get-enabled-advices, ad-special-forms)
Stefan Monnier <monnier@iro.umontreal.ca>
parents: 46196
diff changeset
3021 (help-add-fundoc-usage origdoc usage)))
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3022
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3023 (defun ad-make-plain-docstring (function)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3024 (ad-make-advised-docstring function 'plain))
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3025 (defun ad-make-freeze-docstring (function)
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3026 (ad-make-advised-docstring function 'freeze))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3027
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3028 ;; @@@ Accessing overriding arglists and interactive forms:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3029 ;; ========================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3030
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3031 (defun ad-advised-arglist (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3032 "Find first defined arglist in FUNCTION's redefining advices."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3033 (ad-dolist (advice (append (ad-get-enabled-advices function 'before)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3034 (ad-get-enabled-advices function 'around)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3035 (ad-get-enabled-advices function 'after)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3036 (let ((arglist (ad-arglist (ad-advice-definition advice))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3037 (if arglist
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3038 ;; We found the first one, use it:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3039 (ad-do-return arglist)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3040
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3041 (defun ad-advised-interactive-form (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3042 "Find first interactive form in FUNCTION's redefining advices."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3043 (ad-dolist (advice (append (ad-get-enabled-advices function 'before)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3044 (ad-get-enabled-advices function 'around)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3045 (ad-get-enabled-advices function 'after)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3046 (let ((interactive-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3047 (ad-interactive-form (ad-advice-definition advice))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3048 (if interactive-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3049 ;; We found the first one, use it:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3050 (ad-do-return interactive-form)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3051
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3052 ;; @@@ Putting it all together:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3053 ;; ============================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3054
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3055 (defun ad-make-advised-definition (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3056 "Generate an advised definition of FUNCTION from its advice info."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3057 (if (and (ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3058 (ad-has-redefining-advice function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3059 (let* ((origdef (ad-real-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3060 (origname (ad-get-advice-info-field function 'origname))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3061 (orig-interactive-p (ad-interactive-p origdef))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3062 (orig-subr-p (ad-subr-p origdef))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3063 (orig-special-form-p (ad-special-form-p origdef))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3064 (orig-macro-p (ad-macro-p origdef))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3065 ;; Construct the individual pieces that we need for assembly:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3066 (orig-arglist (ad-arglist origdef function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3067 (advised-arglist (or (ad-advised-arglist function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3068 orig-arglist))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3069 (advised-interactive-form (ad-advised-interactive-form function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3070 (interactive-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3071 (cond (orig-macro-p nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3072 (advised-interactive-form)
38336
d5f3a4fa3bc5 (ad-make-advised-definition): If the
Gerd Moellmann <gerd@gnu.org>
parents: 37304
diff changeset
3073 ((ad-interactive-form origdef)
d5f3a4fa3bc5 (ad-make-advised-definition): If the
Gerd Moellmann <gerd@gnu.org>
parents: 37304
diff changeset
3074 (if (and (symbolp function) (get function 'elp-info))
d5f3a4fa3bc5 (ad-make-advised-definition): If the
Gerd Moellmann <gerd@gnu.org>
parents: 37304
diff changeset
3075 (interactive-form (aref (get function 'elp-info) 2))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3076 (ad-interactive-form origdef)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3077 ;; Otherwise we must have a subr: make it interactive if
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3078 ;; we have to and initialize required arguments in case
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3079 ;; it is called interactively:
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3080 (orig-interactive-p
38336
d5f3a4fa3bc5 (ad-make-advised-definition): If the
Gerd Moellmann <gerd@gnu.org>
parents: 37304
diff changeset
3081 (interactive-form origdef))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3082 (orig-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3083 (cond ((or orig-special-form-p orig-macro-p)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3084 ;; Special forms and macros will be advised into macros.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3085 ;; The trick is to construct an expansion for the advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3086 ;; macro that does the correct thing when it gets eval'ed.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3087 ;; For macros we'll just use the expansion of the original
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3088 ;; macro and return that. This way compiled advised macros
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3089 ;; will be expanded into something useful. Note that after
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3090 ;; advices have full control over whether they want to
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3091 ;; evaluate the expansion (the value of `ad-return-value')
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3092 ;; at macro expansion time or not. For special forms there
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3093 ;; is no solution that interacts reasonably with the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3094 ;; compiler, hence we just evaluate the original at macro
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3095 ;; expansion time and return the result. The moral of that
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3096 ;; is that one should always deactivate advised special
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3097 ;; forms before one byte-compiles a file.
37304
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3098 `(,(if orig-macro-p 'macroexpand 'eval)
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3099 (cons ',origname
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3100 ,(ad-get-arguments advised-arglist 0))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3101 ((and orig-subr-p
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3102 orig-interactive-p
37304
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3103 (not interactive-form)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3104 (not advised-interactive-form))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3105 ;; Check whether we were called interactively
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3106 ;; in order to do proper prompting:
37304
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3107 `(if (interactive-p)
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3108 (call-interactively ',origname)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3109 ,(ad-make-mapped-call orig-arglist
37304
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3110 advised-arglist
9ca19dfc32fb (ad-make-advised-definition): Construct
Gerd Moellmann <gerd@gnu.org>
parents: 37056
diff changeset
3111 origname)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3112 ;; And now for normal functions and non-interactive subrs
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3113 ;; (or subrs whose interactive behavior was advised):
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3114 (t (ad-make-mapped-call
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3115 advised-arglist orig-arglist origname)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3116
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3117 ;; Finally, build the sucker:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3118 (ad-assemble-advised-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3119 (cond (orig-macro-p 'macro)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3120 (orig-special-form-p 'special-form)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3121 (t 'function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3122 advised-arglist
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3123 (ad-make-advised-definition-docstring function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3124 interactive-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3125 orig-form
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3126 (ad-get-enabled-advices function 'before)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3127 (ad-get-enabled-advices function 'around)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3128 (ad-get-enabled-advices function 'after)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3129
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3130 (defun ad-assemble-advised-definition
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3131 (type args docstring interactive orig &optional befores arounds afters)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3132
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3133 "Assembles an original and its advices into an advised function.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3134 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
3135 be either `macro', `function' or `special-form'. ARGS is the argument list
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3136 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
3137 definition, INTERACTIVE if non-nil is the interactive form to be used,
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3138 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
3139 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
3140 should be modified. The assembled function will be returned."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3141
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3142 (let (before-forms around-form around-form-protected after-forms definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3143 (ad-dolist (advice befores)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3144 (cond ((and (ad-advice-protected advice)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3145 before-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3146 (setq before-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3147 `((unwind-protect
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3148 ,(ad-prognify before-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3149 ,@(ad-body-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3150 (ad-advice-definition advice))))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3151 (t (setq before-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3152 (append before-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3153 (ad-body-forms (ad-advice-definition advice)))))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3154
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3155 (setq around-form `(setq ad-return-value ,orig))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3156 (ad-dolist (advice (reverse arounds))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3157 ;; 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
3158 ;; protect the complete around advice onion:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3159 (if (ad-advice-protected advice)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3160 (setq around-form-protected t))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3161 (setq around-form
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3162 (ad-substitute-tree
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3163 (function (lambda (form) (eq form 'ad-do-it)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3164 (function (lambda (form) around-form))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3165 (ad-prognify (ad-body-forms (ad-advice-definition advice))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3166
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3167 (setq after-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3168 (if (and around-form-protected before-forms)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3169 `((unwind-protect
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3170 ,(ad-prognify before-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3171 ,around-form))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3172 (append before-forms (list around-form))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3173 (ad-dolist (advice afters)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3174 (cond ((and (ad-advice-protected advice)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3175 after-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3176 (setq after-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3177 `((unwind-protect
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3178 ,(ad-prognify after-forms)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3179 ,@(ad-body-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3180 (ad-advice-definition advice))))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3181 (t (setq after-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3182 (append after-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3183 (ad-body-forms (ad-advice-definition advice)))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3184
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3185 (setq definition
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3186 `(,@(if (memq type '(macro special-form)) '(macro))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3187 lambda
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3188 ,args
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3189 ,@(if docstring (list docstring))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3190 ,@(if interactive (list interactive))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3191 (let (ad-return-value)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3192 ,@after-forms
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3193 ,(if (eq type 'special-form)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3194 '(list 'quote ad-return-value)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3195 'ad-return-value))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3196
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3197 (ad-insert-argument-access-forms definition args)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3198
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3199 ;; This is needed for activation/deactivation hooks:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3200 (defun ad-make-hook-form (function hook-name)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3201 "Make hook-form from FUNCTION's advice bodies in class HOOK-NAME."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3202 (let ((hook-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3203 (mapcar (function (lambda (advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3204 (ad-body-forms (ad-advice-definition advice))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3205 (ad-get-enabled-advices function hook-name))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3206 (if hook-forms
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3207 (ad-prognify (apply 'append hook-forms)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3208
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3209
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3210 ;; @@ Caching:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3211 ;; ===========
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3212 ;; Generating an advised definition of a function is moderately expensive,
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3213 ;; 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
3214 ;; circumstances. Of course, it only makes sense to reuse a cached
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3215 ;; definition if the current advice and function definition state is the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3216 ;; same as it was at the time when the cached definition was generated.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3217 ;; 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
3218 ;; 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
3219 ;; makes it possible to preactivate advised functions, write the compiled
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3220 ;; advised definitions to a file and reuse them during the actual
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3221 ;; activation without having to risk that the resulting definition will be
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3222 ;; incorrect, well, almost.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3223 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3224 ;; A cache id is a list with six elements:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3225 ;; 1) the list of names of enabled before advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3226 ;; 2) the list of names of enabled around advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3227 ;; 3) the list of names of enabled after advices
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3228 ;; 4) the type of the original function (macro, subr, etc.)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3229 ;; 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
3230 ;; arglist of the cached definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3231 ;; 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
3232 ;; interactive form of the cached definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3233 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3234 ;; Here's how a cache can get invalidated or be incorrect:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3235 ;; A) a piece of advice used in the cache gets redefined
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3236 ;; B) the current list of enabled advices is different from the ones used
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3237 ;; for the cache
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3238 ;; 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
3239 ;; macro, or a subr became a function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3240 ;; D) the arglist of the original function changed
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3241 ;; E) the interactive form of the original function changed
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3242 ;; F) a piece of advice used in the cache got redefined before the
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3243 ;; defadvice with the cached definition got loaded: This is a PROBLEM!
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3244 ;;
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3245 ;; 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
3246 ;; which clears the cache in such a case, B is easily checked during
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3247 ;; verification at activation time.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3248 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3249 ;; 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
3250 ;; if one considers the case that the original function could be different
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3251 ;; from the one available at caching time (e.g., for forward advice of
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3252 ;; 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
3253 ;; 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
3254 ;; 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
3255 ;; 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
3256 ;; arglist can be recovered at validation time from the cached definition),
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3257 ;; 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
3258 ;; was actually a function whose interactive form was not overridden by a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3259 ;; piece of advice.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3260 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3261 ;; 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
3262 ;; There is no way to avoid this without storing the complete advice definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3263 ;; in the cache-id which is not feasible.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3264 ;;
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3265 ;; 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
3266 ;; 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
3267 ;; the added efficiency. The validation itself is also pretty cheap, certainly
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3268 ;; a lot cheaper than reconstructing an advised definition.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3269
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3270 (defmacro ad-get-cache-definition (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3271 `(car (ad-get-advice-info-field ,function 'cache)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3272
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3273 (defmacro ad-get-cache-id (function)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3274 `(cdr (ad-get-advice-info-field ,function 'cache)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3275
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3276 (defmacro ad-set-cache (function definition id)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3277 `(ad-set-advice-info-field
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3278 ,function 'cache (cons ,definition ,id)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3279
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3280 (defun ad-clear-cache (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3281 "Clears a previously cached advised definition of FUNCTION.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3282 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
3283 advised definition from scratch."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3284 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3285 (list (ad-read-advised-function "Clear cached definition of: ")))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3286 (ad-set-advice-info-field function 'cache nil))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3287
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3288 (defun ad-make-cache-id (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3289 "Generate an identifying image of the current advices of FUNCTION."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3290 (let ((original-definition (ad-real-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3291 (cached-definition (ad-get-cache-definition function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3292 (list (mapcar (function (lambda (advice) (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3293 (ad-get-enabled-advices function 'before))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3294 (mapcar (function (lambda (advice) (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3295 (ad-get-enabled-advices function 'around))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3296 (mapcar (function (lambda (advice) (ad-advice-name advice)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3297 (ad-get-enabled-advices function 'after))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3298 (ad-definition-type original-definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3299 (if (equal (ad-arglist original-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3300 (ad-arglist cached-definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3301 t
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3302 (ad-arglist original-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3303 (if (eq (ad-definition-type original-definition) 'function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3304 (equal (ad-interactive-form original-definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3305 (ad-interactive-form cached-definition))))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3306
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3307 (defun ad-get-cache-class-id (function class)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3308 "Return the part of FUNCTION's cache id that identifies CLASS."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3309 (let ((cache-id (ad-get-cache-id function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3310 (if (eq class 'before)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3311 (car cache-id)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3312 (if (eq class 'around)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3313 (nth 1 cache-id)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3314 (nth 2 cache-id)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3315
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3316 (defun ad-verify-cache-class-id (cache-class-id advices)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3317 (ad-dolist (advice advices (null cache-class-id))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3318 (if (ad-advice-enabled advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3319 (if (eq (car cache-class-id) (ad-advice-name advice))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3320 (setq cache-class-id (cdr cache-class-id))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3321 (ad-do-return nil)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3322
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3323 ;; 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
3324 ;; 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
3325 ;; 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
3326 ;; `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
3327 ;; verification failed. Tracing `ad-verify-cache-class-id' might provide
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3328 ;; some additional useful information.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3329
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3330 (defun ad-cache-id-verification-code (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3331 (let ((cache-id (ad-get-cache-id function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3332 (code 'before-advice-mismatch))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3333 (and (ad-verify-cache-class-id
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3334 (car cache-id) (ad-get-advice-info-field function 'before))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3335 (setq code 'around-advice-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3336 (ad-verify-cache-class-id
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3337 (nth 1 cache-id) (ad-get-advice-info-field function 'around))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3338 (setq code 'after-advice-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3339 (ad-verify-cache-class-id
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3340 (nth 2 cache-id) (ad-get-advice-info-field function 'after))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3341 (setq code 'definition-type-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3342 (let ((original-definition (ad-real-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3343 (cached-definition (ad-get-cache-definition function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3344 (and (eq (nth 3 cache-id) (ad-definition-type original-definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3345 (setq code 'arglist-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3346 (equal (if (eq (nth 4 cache-id) t)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3347 (ad-arglist original-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3348 (nth 4 cache-id) )
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3349 (ad-arglist cached-definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3350 (setq code 'interactive-form-mismatch)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3351 (or (null (nth 5 cache-id))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3352 (equal (ad-interactive-form original-definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3353 (ad-interactive-form cached-definition)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3354 (setq code 'verified))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3355 code))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3356
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3357 (defun ad-verify-cache-id (function)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3358 "True if FUNCTION's cache-id is compatible with its current advices."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3359 (eq (ad-cache-id-verification-code function) 'verified))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3360
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3361
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3362 ;; @@ Preactivation:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3363 ;; =================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3364 ;; Preactivation can be used to generate compiled advised definitions
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3365 ;; 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
3366 ;; of the advice mechanism. Preactivation is a special feature of `defadvice',
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3367 ;; it involves the following steps:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3368 ;; - remembering the function's current state (definition and advice-info)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3369 ;; - advising it with the defined piece of advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3370 ;; - clearing its cache
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3371 ;; - generating an interpreted advised definition by activating it, this will
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3372 ;; make use of all its current active advice and its current definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3373 ;; - saving the so generated cached definition and id
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3374 ;; - resetting the function's advice and definition state to what it was
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3375 ;; before the preactivation
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3376 ;; - 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
3377 ;; `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
3378 ;; at time the `defadvice' gets compiled.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3379 ;; Naturally, for preactivation to be effective it has to be applied/compiled
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3380 ;; 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
3381 ;; definition exactly reflects the state at activation time. Should that not
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3382 ;; be the case, the precompiled definition will just be discarded and a new
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3383 ;; advised definition will be generated.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3384
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3385 (defun ad-preactivate-advice (function advice class position)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3386 "Preactivate FUNCTION and returns the constructed cache."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3387 (let* ((function-defined-p (fboundp function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3388 (old-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3389 (if function-defined-p
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3390 (symbol-function function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3391 (old-advice-info (ad-copy-advice-info function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3392 (ad-advised-functions ad-advised-functions))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3393 (unwind-protect
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3394 (progn
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3395 (ad-add-advice function advice class position)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3396 (ad-enable-advice function class (ad-advice-name advice))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3397 (ad-clear-cache function)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3398 (ad-activate function -1)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3399 (if (and (ad-is-active function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3400 (ad-get-cache-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3401 (list (ad-get-cache-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3402 (ad-get-cache-id function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3403 (ad-set-advice-info function old-advice-info)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3404 ;; Don't `fset' function to nil if it was previously unbound:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3405 (if function-defined-p
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3406 (ad-safe-fset function old-definition)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3407 (fmakunbound function)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3408
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3409
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3410 ;; @@ Freezing:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3411 ;; ============
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3412 ;; 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
3413 ;; 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
3414 ;; 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
3415 ;; 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
3416 ;; 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
3417 ;; cannot be undone.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3418
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3419 ;; 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
3420 ;; 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
3421 ;; 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
3422 ;; 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
3423 ;; 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
3424 ;; 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
3425 ;; 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
3426
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3427 ;; 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
3428 ;; 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
3429 ;; 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
3430 ;; incomprehensible pretty quickly.
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3431
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3432 (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
3433 (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
3434 (error
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3435 "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
3436 function))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3437 (let* ((name (ad-advice-name advice))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3438 ;; 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
3439 ;; 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
3440 (unique-origname
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3441 (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
3442 (orig-definition
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3443 ;; 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
3444 ;; 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
3445 (or (ad-get-orig-definition function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3446 (symbol-function function)))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3447 (old-advice-info
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3448 (if (ad-is-advised function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3449 (ad-copy-advice-info function)))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3450 (real-docstring-fn
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3451 (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
3452 (real-origname-fn
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3453 (symbol-function 'ad-make-origname))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3454 (frozen-definition
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3455 (unwind-protect
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3456 (progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3457 ;; Make sure we construct a proper docstring:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3458 (ad-safe-fset 'ad-make-advised-definition-docstring
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3459 'ad-make-freeze-docstring)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3460 ;; 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
3461 (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
3462 ;; 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
3463 ;; generate an advised definition that's solely determined
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3464 ;; by ADVICE and the current origdef of FUNCTION:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3465 (ad-set-advice-info function nil)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3466 (ad-add-advice function advice class position)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3467 ;; The following will provide proper real docstrings as
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3468 ;; 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
3469 (ad-set-orig-definition function orig-definition)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3470 (ad-make-advised-definition function))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3471 ;; Restore the old advice state:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3472 (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
3473 ;; Restore functions:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3474 (ad-safe-fset
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3475 '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
3476 (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
3477 (if frozen-definition
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3478 (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
3479 (body (cdr (if macro-p
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3480 (ad-lambdafy frozen-definition)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3481 frozen-definition))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3482 `(progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3483 (if (not (fboundp ',unique-origname))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3484 (fset ',unique-origname
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3485 ;; avoid infinite recursion in case the function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3486 ;; we want to freeze is already advised:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3487 (or (ad-get-orig-definition ',function)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3488 (symbol-function ',function))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3489 (,(if macro-p 'defmacro 'defun)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3490 ,function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3491 ,@body))))))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3492
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3493
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3494 ;; @@ Activation and definition handling:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3495 ;; ======================================
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3496
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3497 (defun ad-should-compile (function compile)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3498 "Return non-nil if the advised FUNCTION should be compiled.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3499 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
3500 If COMPILE is a negative number then it returns nil.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3501 If COMPILE is nil then the result depends on the value of
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3502 `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
3503 (if (integerp compile)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3504 (>= compile 0)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3505 (if compile
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3506 compile
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3507 (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
3508 nil)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3509 ((eq ad-default-compilation-action 'always)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3510 t)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3511 ((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
3512 (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
3513 (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
3514 ;; everything else means `maybe':
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3515 (t (featurep 'byte-compile))))))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3516
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3517 (defun ad-activate-advised-definition (function compile)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3518 "Redefine FUNCTION with its advised definition from cache or scratch.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3519 The resulting FUNCTION will be compiled if `ad-should-compile' returns t.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3520 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
3521 (let ((verified-cached-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3522 (if (ad-verify-cache-id function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3523 (ad-get-cache-definition function))))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3524 (ad-safe-fset function
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3525 (or verified-cached-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3526 (ad-make-advised-definition function)))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3527 (if (ad-should-compile function compile)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3528 (ad-compile-function function))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3529 (if verified-cached-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3530 (if (not (eq verified-cached-definition (symbol-function function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3531 ;; we must have compiled, cache the compiled definition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3532 (ad-set-cache
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3533 function (symbol-function function) (ad-get-cache-id function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3534 ;; We created a new advised definition, cache it with a proper id:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3535 (ad-clear-cache function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3536 ;; ad-make-cache-id needs the new cached definition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3537 (ad-set-cache function (symbol-function function) nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3538 (ad-set-cache
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3539 function (symbol-function function) (ad-make-cache-id function)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3540
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3541 (defun ad-handle-definition (function)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3542 "Handle re/definition of an advised FUNCTION during de/activation.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3543 If FUNCTION does not have an original definition associated with it and
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3544 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
3545 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
3546 case of undefinition) nothing will be done. In the case of redefinition
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3547 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
3548 see). Redefinition occurs when FUNCTION already has an original definition
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3549 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
3550 de/activated. If you do not like the current redefinition action change
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3551 the value of `ad-redefinition-action' and de/activate again."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3552 (let ((original-definition (ad-get-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3553 (current-definition (if (ad-real-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3554 (symbol-function function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3555 (if original-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3556 (if current-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3557 (if (and (not (eq current-definition original-definition))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3558 ;; Redefinition with an advised definition from a
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3559 ;; different function won't count as such:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3560 (not (ad-advised-definition-p current-definition)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3561 ;; we have a redefinition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3562 (if (not (memq ad-redefinition-action '(accept discard warn)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3563 (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
3564 function "invalidly redefined")
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3565 (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
3566 (ad-safe-fset function original-definition)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3567 (ad-set-orig-definition function current-definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3568 (if (eq ad-redefinition-action 'warn)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3569 (message "ad-handle-definition: `%s' got redefined"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3570 function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3571 ;; either advised def or correct original is in place:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3572 nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3573 ;; we have an undefinition, ignore it:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3574 nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3575 (if current-definition
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3576 ;; we have a first definition, save it as original:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3577 (ad-set-orig-definition function current-definition)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3578 ;; we don't have anything noteworthy:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3579 nil))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3580
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3581
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3582 ;; @@ The top-level advice interface:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3583 ;; ==================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3584
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3585 (defun ad-activate (function &optional compile)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3586 "Activate all the advice information of an advised FUNCTION.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3587 If FUNCTION has a proper original definition then an advised
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3588 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
3589 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
3590 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
3591 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
3592 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
3593 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
3594 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
3595 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
3596 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
3597 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
3598 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
3599 enabled is equivalent to a call to `ad-deactivate'. The current advised
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3600 definition will always be cached for later usage."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3601 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3602 (list (ad-read-advised-function "Activate advice of: ")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3603 current-prefix-arg))
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3604 (if ad-activate-on-top-level
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3605 ;; 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
3606 (ad-with-auto-activation-disabled
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3607 (if (not (ad-is-advised function))
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3608 (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
3609 (ad-handle-definition function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3610 ;; 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
3611 (if (ad-get-orig-definition function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3612 (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
3613 (ad-unadvise function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3614 ;; Otherwise activate the advice:
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3615 (cond ((ad-has-redefining-advice function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3616 (ad-activate-advised-definition function compile)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3617 (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
3618 (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
3619 function)
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3620 ;; 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
3621 (t (ad-deactivate function)))))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3622
26247
f96b2bc4ef08 (ad-activate-on): Make it an alias for ad-activate.
Gerd Moellmann <gerd@gnu.org>
parents: 26217
diff changeset
3623 (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
3624
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3625 (defun ad-deactivate (function)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3626 "Deactivate the advice of an actively advised FUNCTION.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3627 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
3628 definition of FUNCTION will be replaced with it. All the advice
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3629 information will still be available so it can be activated again with
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3630 a call to `ad-activate'."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3631 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3632 (list (ad-read-advised-function "Deactivate advice of: " 'ad-is-active)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3633 (if (not (ad-is-advised function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3634 (error "ad-deactivate: `%s' is not advised" function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3635 (cond ((ad-is-active function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3636 (ad-handle-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3637 (if (not (ad-get-orig-definition function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3638 (error "ad-deactivate: `%s' has no original definition"
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3639 function)
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3640 (ad-safe-fset function (ad-get-orig-definition function))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3641 (ad-set-advice-info-field function 'active nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3642 (eval (ad-make-hook-form function 'deactivation))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3643 function)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3644
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3645 (defun ad-update (function &optional compile)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3646 "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
3647 See `ad-activate' for documentation on the optional COMPILE argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3648 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3649 (list (ad-read-advised-function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3650 "Update advised definition of: " 'ad-is-active)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3651 (if (ad-is-active function)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3652 (ad-activate function compile)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3653
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3654 (defun ad-unadvise (function)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3655 "Deactivate FUNCTION and then remove all its advice information.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3656 If FUNCTION was not advised this will be a noop."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3657 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3658 (list (ad-read-advised-function "Unadvise function: ")))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3659 (cond ((ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3660 (if (ad-is-active function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3661 (ad-deactivate function))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3662 (ad-clear-orig-definition function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3663 (ad-set-advice-info function nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3664 (ad-pop-advised-function function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3665
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3666 (defun ad-recover (function)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3667 "Try to recover FUNCTION's original definition, and unadvise it.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3668 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
3669 deactivation, which might run hooks and get into other trouble.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3670 Use in emergencies."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3671 ;; Use more primitive interactive behavior here: Accept any symbol that's
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3672 ;; currently defined in obarray, not necessarily with a function definition:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3673 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3674 (list (intern
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3675 (completing-read "Recover advised function: " obarray nil t))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3676 (cond ((ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3677 (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
3678 (ad-safe-fset function (ad-get-orig-definition function))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3679 (ad-clear-orig-definition function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3680 (ad-set-advice-info function nil)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3681 (ad-pop-advised-function function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3682
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3683 (defun ad-activate-regexp (regexp &optional compile)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3684 "Activate functions with an advice name containing a REGEXP match.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3685 This activates the advice for each function
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3686 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
3687 See `ad-activate' for documentation on the optional COMPILE argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3688 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3689 (list (ad-read-regexp "Activate via advice regexp: ")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3690 current-prefix-arg))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3691 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3692 (if (ad-find-some-advice function 'any regexp)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3693 (ad-activate function compile))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3694
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3695 (defun ad-deactivate-regexp (regexp)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3696 "Deactivate functions with an advice name containing REGEXP match.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3697 This deactivates the advice for each function
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3698 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
3699 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3700 (list (ad-read-regexp "Deactivate via advice regexp: ")))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3701 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3702 (if (ad-find-some-advice function 'any regexp)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3703 (ad-deactivate function))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3704
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3705 (defun ad-update-regexp (regexp &optional compile)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3706 "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
3707 This reactivates the advice for each function
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3708 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
3709 See `ad-activate' for documentation on the optional COMPILE argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3710 (interactive
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3711 (list (ad-read-regexp "Update via advice regexp: ")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3712 current-prefix-arg))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3713 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3714 (if (ad-find-some-advice function 'any regexp)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3715 (ad-update function compile))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3716
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3717 (defun ad-activate-all (&optional compile)
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3718 "Activate all currently advised functions.
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3719 See `ad-activate' for documentation on the optional COMPILE argument."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3720 (interactive "P")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3721 (ad-do-advised-functions (function)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3722 (ad-activate function compile)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3723
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3724 (defun ad-deactivate-all ()
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3725 "Deactivate all currently advised functions."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3726 (interactive)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3727 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3728 (ad-deactivate function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3729
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3730 (defun ad-update-all (&optional compile)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3731 "Update all currently advised functions.
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3732 With prefix argument, COMPILE resulting advised definitions."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3733 (interactive "P")
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3734 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3735 (ad-update function compile)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3736
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3737 (defun ad-unadvise-all ()
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3738 "Unadvise all currently advised functions."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3739 (interactive)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3740 (ad-do-advised-functions (function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3741 (ad-unadvise function)))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3742
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3743 (defun ad-recover-all ()
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3744 "Recover all currently advised functions. Use in emergencies.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3745 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
3746 definition, and delete all advice.
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3747 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
3748 deactivation, which might run hooks and get into other trouble."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3749 (interactive)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3750 (ad-do-advised-functions (function)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3751 (condition-case nil
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3752 (ad-recover function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3753 (error nil))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3754
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3755
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3756 ;; Completion alist of legal `defadvice' flags
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3757 (defvar ad-defadvice-flags
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3758 '(("protect") ("disable") ("activate")
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3759 ("compile") ("preactivate") ("freeze")))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3760
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3761 ;;;###autoload
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3762 (defmacro defadvice (function args &rest body)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3763 "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
3764 The syntax of `defadvice' is as follows:
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3765
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3766 \(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
3767 [DOCSTRING] [INTERACTIVE-FORM]
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3768 BODY... )
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3769
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3770 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
3771 CLASS ::= `before' | `around' | `after' | `activation' | `deactivation'.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3772 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
3773 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
3774 see also `ad-add-advice'.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3775 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
3776 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
3777 before/around/after-advices will be used.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3778 FLAG ::= `protect'|`disable'|`activate'|`compile'|`preactivate'|`freeze'.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3779 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
3780 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
3781 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
3782 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
3783 BODY ::= Any s-expression.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3784
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3785 Semantics of the various flags:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3786 `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
3787 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
3788 then automatically all around-advices will be protected (the complete onion).
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3789
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3790 `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
3791 FUNCTION has been properly defined prior to this application of `defadvice'.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3792
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3793 `compile': In conjunction with `activate' specifies that the resulting
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3794 advised function should be compiled.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3795
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3796 `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
3797 during activation until somebody enables it.
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3798
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3799 `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
3800 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
3801 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
3802 this if the `defadvice' gets actually compiled.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3803
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3804 `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
3805 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
3806 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
3807 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
3808 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
3809 during preloading.
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3810
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3811 See Info node `(elisp)Advising Functions' for comprehensive documentation."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3812 (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
3813 (error "defadvice: Invalid function name: %s" function))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3814 (let* ((class (car args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3815 (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
3816 (error "defadvice: Invalid advice class: %s" class)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3817 (nth 1 args)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3818 (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
3819 (error "defadvice: Invalid advice name: %s" name)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3820 (setq args (nthcdr 2 args))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3821 (if (ad-position-p (car args))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3822 (prog1 (car args)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3823 (setq args (cdr args))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3824 (arglist (if (listp (car args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3825 (prog1 (car args)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3826 (setq args (cdr args)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3827 (flags
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3828 (mapcar
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3829 (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3830 (lambda (flag)
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3831 (let ((completion
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3832 (try-completion (symbol-name flag) ad-defadvice-flags)))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3833 (cond ((eq completion t) flag)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3834 ((assoc completion ad-defadvice-flags)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3835 (intern completion))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3836 (t (error "defadvice: Invalid or ambiguous flag: %s"
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3837 flag))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3838 args))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3839 (advice (ad-make-advice
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3840 name (memq 'protect flags)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3841 (not (memq 'disable flags))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3842 `(advice lambda ,arglist ,@body)))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3843 (preactivation (if (memq 'preactivate flags)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3844 (ad-preactivate-advice
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3845 function advice class position))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3846 ;; 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
3847 (if (memq 'freeze flags)
6038
2f1deaa86ee2 Removed all support for Emacs-18:
Richard M. Stallman <rms@gnu.org>
parents: 5746
diff changeset
3848 ;; 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
3849 ;; 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
3850 (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
3851 ;; the normal case:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3852 `(progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3853 (ad-add-advice ',function ',advice ',class ',position)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3854 ,@(if preactivation
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3855 `((ad-set-cache
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3856 ',function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3857 ;; the function will get compiled:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3858 ,(cond ((ad-macro-p (car preactivation))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3859 `(ad-macrofy
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3860 (function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3861 ,(ad-lambdafy
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3862 (car preactivation)))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3863 (t `(function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3864 ,(car preactivation))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3865 ',(car (cdr preactivation)))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3866 ,@(if (memq 'activate flags)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3867 `((ad-activate ',function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3868 ,(if (memq 'compile flags) t))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3869 ',function))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3870
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3871
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3872 ;; @@ Tools:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3873 ;; =========
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3874
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3875 (defmacro ad-with-originals (functions &rest body)
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3876 "Binds FUNCTIONS to their original definitions and execute BODY.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3877 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
3878 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
3879 undone on exit of this macro."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3880 (let* ((index -1)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3881 ;; Make let-variables to store current definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3882 (current-bindings
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3883 (mapcar (function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3884 (lambda (function)
41608
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 (list (intern (format "ad-oRiGdEf-%d" index))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3887 `(symbol-function ',function))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3888 functions)))
41608
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3889 `(let ,current-bindings
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3890 (unwind-protect
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3891 (progn
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 redefine functions to their
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3894 ;; original definitions if they are advised:
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 (or (ad-get-orig-definition ',function)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3903 ,(car (nth index current-bindings))))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3904 functions))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3905 ,@body)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3906 ,@(progn
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3907 ;; 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
3908 ;; they had outside this macro call:
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3909 (setq index -1)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3910 (mapcar
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3911 (function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3912 (lambda (function)
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3913 (setq index (1+ index))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3914 `(ad-safe-fset
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3915 ',function
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3916 ,(car (nth index current-bindings)))))
45db352a0971 Converted backquote to the new style.
Sam Steingold <sds@gnu.org>
parents: 38336
diff changeset
3917 functions))))))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3918
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3919 (if (not (get 'ad-with-originals 'lisp-indent-hook))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3920 (put 'ad-with-originals 'lisp-indent-hook 1))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3921
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3922
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3923 ;; @@ Advising `documentation':
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3924 ;; ============================
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3925 ;; 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
3926 ;; generate proper documentation strings for advised definitions:
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3927
45019
c726a3eeeb0f (documentation): Add ad-define-subr-args call.
Richard M. Stallman <rms@gnu.org>
parents: 41936
diff changeset
3928 ;; 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
3929 ;; during bootstrapping.
c726a3eeeb0f (documentation): Add ad-define-subr-args call.
Richard M. Stallman <rms@gnu.org>
parents: 41936
diff changeset
3930 (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
3931
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3932 (defadvice documentation (after ad-advised-docstring first disable preact)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3933 "Builds an advised docstring if FUNCTION is advised."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3934 ;; Because we get the function name from the advised docstring
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3935 ;; this will work for function names as well as for definitions:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3936 (if (and (stringp ad-return-value)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3937 (string-match
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3938 ad-advised-definition-docstring-regexp ad-return-value))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3939 (let ((function
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3940 (car (read-from-string
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3941 ad-return-value (match-beginning 1) (match-end 1)))))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3942 (cond ((ad-is-advised function)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3943 (setq ad-return-value (ad-make-advised-docstring function))
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3944 ;; Handle optional `raw' argument:
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3945 (if (not (ad-get-arg 1))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3946 (setq ad-return-value
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3947 (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
3948
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3949
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3950 ;; @@ Starting, stopping and recovering from the advice package magic:
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3951 ;; ===================================================================
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3952
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3953 (defun ad-start-advice ()
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3954 "Start the automatic advice handling magic."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3955 (interactive)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3956 ;; Advising `ad-activate-internal' means death!!
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3957 (ad-set-advice-info 'ad-activate-internal nil)
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3958 (ad-safe-fset 'ad-activate-internal 'ad-activate)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3959 (ad-enable-advice 'documentation 'after 'ad-advised-docstring)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3960 (ad-activate 'documentation 'compile))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3961
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3962 (defun ad-stop-advice ()
26622
019c7ea59fd9 Many doc fixes.
Richard M. Stallman <rms@gnu.org>
parents: 26247
diff changeset
3963 "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
3964 You should only need this in case of Advice-related emergencies."
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3965 (interactive)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3966 ;; Advising `ad-activate-internal' means death!!
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3967 (ad-set-advice-info 'ad-activate-internal nil)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3968 (ad-disable-advice 'documentation 'after 'ad-advised-docstring)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3969 (ad-update 'documentation)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3970 (ad-safe-fset 'ad-activate-internal 'ad-activate-internal-off))
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3971
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3972 (defun ad-recover-normality ()
26217
5d24b6d99a9f Doc fixes.
Dave Love <fx@gnu.org>
parents: 26206
diff changeset
3973 "Undo all advice related redefinitions and unadvises everything.
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3974 Use only in REAL emergencies."
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3975 (interactive)
26206
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3976 ;; Advising `ad-activate-internal' means death!!
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3977 (ad-set-advice-info 'ad-activate-internal nil)
3d9818475597 (ad-activate-internal): Renamed from
Gerd Moellmann <gerd@gnu.org>
parents: 25260
diff changeset
3978 (ad-safe-fset 'ad-activate-internal 'ad-activate-internal-off)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3979 (ad-recover-all)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3980 (setq ad-advised-functions nil))
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3981
8445
81f7b5d9b990 New handling of automatic advice activation that
Richard M. Stallman <rms@gnu.org>
parents: 6082
diff changeset
3982 (ad-start-advice)
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3983
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3984 (provide 'advice)
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3985
52401
695cf19ef79e Add arch taglines
Miles Bader <miles@gnu.org>
parents: 50842
diff changeset
3986 ;;; arch-tag: 29f8c9a1-8c88-471f-95d7-e28541c6b7c0
4110
ccdff27edd2e Initial revision
Roland McGrath <roland@gnu.org>
parents:
diff changeset
3987 ;;; advice.el ends here