aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2014-03-17 21:51:12 -0400
committerStefan Monnier2014-03-17 21:51:12 -0400
commit6c187ef5a510d493bf74de04da2b3a80e944c5e6 (patch)
treed95b292464fa019c6816661a6513a25d6a852c2f
parent09b73f0820fd38194b46aa71e1652c594a25586c (diff)
downloademacs-6c187ef5a510d493bf74de04da2b3a80e944c5e6.tar.gz
emacs-6c187ef5a510d493bf74de04da2b3a80e944c5e6.zip
* doc/lispref/functions.texi (Advising Functions): Try and improve the text.
Add example use of advice-add. (Core Advising Primitives): Rename. Explain handling of interactive specs, including advice-eval-interactive-spec. (Advising Named Functions): Try and better explain the difference with add-function. (Porting old advices): New node. Fixes: debbugs:16959
-rw-r--r--doc/lispref/ChangeLog39
-rw-r--r--doc/lispref/functions.texi243
-rw-r--r--lisp/ChangeLog4
3 files changed, 213 insertions, 73 deletions
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index 37531b0fb31..35ad6e86de9 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,3 +1,13 @@
12014-03-18 Stefan <monnier@iro.umontreal.ca>
2
3 * functions.texi (Advising Functions): Try and improve the text.
4 Add example use of advice-add (bug#16959).
5 (Core Advising Primitives): Rename. Explain handling of interactive
6 specs, including advice-eval-interactive-spec.
7 (Advising Named Functions): Try and better explain the difference with
8 add-function.
9 (Porting old advices): New node.
10
12014-03-18 Paul Eggert <eggert@cs.ucla.edu> 112014-03-18 Paul Eggert <eggert@cs.ucla.edu>
2 12
3 Style fixes for floating-point doc. 13 Style fixes for floating-point doc.
@@ -16,8 +26,7 @@
16 26
17 * display.texi (Temporary Displays): Rewrite descriptions of 27 * display.texi (Temporary Displays): Rewrite descriptions of
18 `with-output-to-temp-buffer' and `with-temp-buffer-window'. 28 `with-output-to-temp-buffer' and `with-temp-buffer-window'.
19 * help.texi (Help Functions): Rewrite description of 29 * help.texi (Help Functions): Rewrite description of `with-help-window'.
20 `with-help-window'.
21 30
222014-03-15 Dmitry Gutov <dgutov@yandex.ru> 312014-03-15 Dmitry Gutov <dgutov@yandex.ru>
23 32
@@ -34,12 +43,10 @@
34 43
352014-03-09 Martin Rudalics <rudalics@gmx.at> 442014-03-09 Martin Rudalics <rudalics@gmx.at>
36 45
37 * elisp.texi (Top): Rename section "Width" to "Size of Displayed 46 * elisp.texi (Top): Rename section "Width" to "Size of Displayed Text".
38 Text".
39 * text.texi (Primitive Indent): 47 * text.texi (Primitive Indent):
40 * strings.texi (String Basics): 48 * strings.texi (String Basics):
41 * sequences.texi (Sequence Functions): Update references 49 * sequences.texi (Sequence Functions): Update references accordingly.
42 accordingly.
43 * display.texi (Size of Displayed Text): Rename section from 50 * display.texi (Size of Displayed Text): Rename section from
44 "Width". Add description for `window-text-pixel-size'. 51 "Width". Add description for `window-text-pixel-size'.
45 (Window Dividers): Reword description of window dividers. 52 (Window Dividers): Reword description of window dividers.
@@ -64,12 +71,12 @@
642014-03-06 Martin Rudalics <rudalics@gmx.at> 712014-03-06 Martin Rudalics <rudalics@gmx.at>
65 72
66 * frames.texi (Size and Position): Rewrite entries for 73 * frames.texi (Size and Position): Rewrite entries for
67 `fit-frame-to-buffer' and `fit-frame-to-buffer-margins'. Add 74 `fit-frame-to-buffer' and `fit-frame-to-buffer-margins'.
68 description for `fit-frame-to-buffer-sizes'. 75 Add description for `fit-frame-to-buffer-sizes'.
69 * windows.texi (Resizing Windows): Add descriptions for 76 * windows.texi (Resizing Windows): Add descriptions for
70 pixelwise resizing. Add entries for `window-resize-pixelwise' 77 pixelwise resizing. Add entries for `window-resize-pixelwise'
71 and `fit-window-to-buffer-horizontally'. Rewrite 78 and `fit-window-to-buffer-horizontally'.
72 `fit-window-to-buffer' entry. 79 Rewrite `fit-window-to-buffer' entry.
73 80
742014-03-06 Xue Fuqiao <xfq@gnu.org> 812014-03-06 Xue Fuqiao <xfq@gnu.org>
75 82
@@ -93,8 +100,7 @@
93 `window-min-height' and `window-min-width'. Remove description 100 `window-min-height' and `window-min-width'. Remove description
94 of `window-size-fixed-p' moving part of it to that of 101 of `window-size-fixed-p' moving part of it to that of
95 `window-size-fixed'. 102 `window-size-fixed'.
96 (Resizing Windows): Mention dividers when talking about minimum 103 (Resizing Windows): Mention dividers when talking about minimum sizes.
97 sizes.
98 104
992014-03-05 Glenn Morris <rgm@gnu.org> 1052014-03-05 Glenn Morris <rgm@gnu.org>
100 106
@@ -349,8 +355,7 @@
349 355
3502013-12-28 Chong Yidong <cyd@gnu.org> 3562013-12-28 Chong Yidong <cyd@gnu.org>
351 357
352 * modes.texi (Auto Major Mode): Document interpreter-mode-alist 358 * modes.texi (Auto Major Mode): Document interpreter-mode-alist change.
353 change.
354 359
355 * buffers.texi (Modification Time): Document visited-file-modtime 360 * buffers.texi (Modification Time): Document visited-file-modtime
356 change. 361 change.
@@ -387,8 +392,7 @@
387 392
388 * display.texi (Font Selection): Tweak example. 393 * display.texi (Font Selection): Tweak example.
389 394
390 * commands.texi (Event Input Misc): Document new arg to 395 * commands.texi (Event Input Misc): Document new arg to input-pending-p.
391 input-pending-p.
392 396
393 * nonascii.texi (Specifying Coding Systems): Don't refer to 397 * nonascii.texi (Specifying Coding Systems): Don't refer to
394 emacs-mule-dos. 398 emacs-mule-dos.
@@ -633,7 +637,8 @@
633 * display.texi (Showing Images): Add an index for image-size. 637 * display.texi (Showing Images): Add an index for image-size.
634 Use @code instead of @var for a normal variable. 638 Use @code instead of @var for a normal variable.
635 (Multi-Frame Images): Improve indexing. 639 (Multi-Frame Images): Improve indexing.
636 (Button Buffer Commands): Use @code instead of @var for a normal variable. 640 (Button Buffer Commands): Use @code instead of @var for a normal
641 variable.
637 (Abstract Display): Explain the meaning of Ewoc. 642 (Abstract Display): Explain the meaning of Ewoc.
638 643
6392013-10-27 Xue Fuqiao <xfq.free@gmail.com> 6442013-10-27 Xue Fuqiao <xfq.free@gmail.com>
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index b85ed6e715c..faae0010f6e 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -11,23 +11,23 @@ explains what functions are, how they accept arguments, and how to
11define them. 11define them.
12 12
13@menu 13@menu
14* What Is a Function:: Lisp functions vs. primitives; terminology. 14* What Is a Function:: Lisp functions vs. primitives; terminology.
15* Lambda Expressions:: How functions are expressed as Lisp objects. 15* Lambda Expressions:: How functions are expressed as Lisp objects.
16* Function Names:: A symbol can serve as the name of a function. 16* Function Names:: A symbol can serve as the name of a function.
17* Defining Functions:: Lisp expressions for defining functions. 17* Defining Functions:: Lisp expressions for defining functions.
18* Calling Functions:: How to use an existing function. 18* Calling Functions:: How to use an existing function.
19* Mapping Functions:: Applying a function to each element of a list, etc. 19* Mapping Functions:: Applying a function to each element of a list, etc.
20* Anonymous Functions:: Lambda expressions are functions with no names. 20* Anonymous Functions:: Lambda expressions are functions with no names.
21* Function Cells:: Accessing or setting the function definition 21* Function Cells:: Accessing or setting the function definition
22 of a symbol. 22 of a symbol.
23* Closures:: Functions that enclose a lexical environment. 23* Closures:: Functions that enclose a lexical environment.
24* Advising Functions:: Adding to the definition of a function. 24* Advising Functions:: Adding to the definition of a function.
25* Obsolete Functions:: Declaring functions obsolete. 25* Obsolete Functions:: Declaring functions obsolete.
26* Inline Functions:: Functions that the compiler will expand inline. 26* Inline Functions:: Functions that the compiler will expand inline.
27* Declare Form:: Adding additional information about a function. 27* Declare Form:: Adding additional information about a function.
28* Declaring Functions:: Telling the compiler that a function is defined. 28* Declaring Functions:: Telling the compiler that a function is defined.
29* Function Safety:: Determining whether a function is safe to call. 29* Function Safety:: Determining whether a function is safe to call.
30* Related Topics:: Cross-references to specific Lisp primitives 30* Related Topics:: Cross-references to specific Lisp primitives
31 that have a special bearing on how functions work. 31 that have a special bearing on how functions work.
32@end menu 32@end menu
33 33
@@ -208,10 +208,10 @@ Before going into these details, the following subsections describe
208the components of a lambda expression and what they do. 208the components of a lambda expression and what they do.
209 209
210@menu 210@menu
211* Lambda Components:: The parts of a lambda expression. 211* Lambda Components:: The parts of a lambda expression.
212* Simple Lambda:: A simple example. 212* Simple Lambda:: A simple example.
213* Argument List:: Details and special features of argument lists. 213* Argument List:: Details and special features of argument lists.
214* Function Documentation:: How to put documentation in a function. 214* Function Documentation:: How to put documentation in a function.
215@end menu 215@end menu
216 216
217@node Lambda Components 217@node Lambda Components
@@ -1142,19 +1142,32 @@ examining or altering the structure of closure objects.
1142@cindex advising functions 1142@cindex advising functions
1143@cindex piece of advice 1143@cindex piece of advice
1144 1144
1145Any variable or object field which holds a function can be modified with the 1145When you need to modify a function defined in another library, or when you need
1146appropriate setter function, such as @code{set-process-filter}, @code{fset}, or 1146to modify a hook like @code{@var{foo}-function}, a process filter, or basically
1147@code{setq}, but those can be too blunt, completely throwing away the 1147any variable or object field which holds a function value, you can use the
1148appropriate setter function, such as @code{fset} or @code{defun} for named
1149functions, @code{setq} for hook variables, or @code{set-process-filter} for
1150process filters, but those are often too blunt, completely throwing away the
1148previous value. 1151previous value.
1149 1152
1150In order to modify such hooks in a more controlled way, Emacs provides the 1153 The @dfn{advice} feature lets you add to the existing definition of
1151macros @code{add-function} and @code{remove-function}, which let you modify the 1154a function, by @dfn{advising the function}. This is a cleaner method
1152existing function value by composing it with another function. 1155than redefining the whole function.
1153 1156
1154For example, in order to trace the calls to a process filter, you can use: 1157Emacs's advice system provides two sets of primitives for that: the core set,
1158for function values held in variables and object fields (with the corresponding
1159primitives being @code{add-function} and @code{remove-function}) and another
1160set layered on top of it for named functions (with the main primitives being
1161@code{advice-add} and @code{advice-remove}).
1162
1163For example, in order to trace the calls to the process filter of a process
1164@var{proc}, you could use:
1155 1165
1156@example 1166@example
1157(add-function :before (process-filter proc) #'my-tracing-function) 1167(defun my-tracing-function (proc string)
1168 (message "Proc %S received %S" proc string))
1169
1170(add-function :before (process-filter @var{proc}) #'my-tracing-function)
1158@end example 1171@end example
1159 1172
1160This will cause the process's output to be passed first to 1173This will cause the process's output to be passed first to
@@ -1162,33 +1175,55 @@ This will cause the process's output to be passed first to
1162When you're done with it, you can revert to the untraced behavior with: 1175When you're done with it, you can revert to the untraced behavior with:
1163 1176
1164@example 1177@example
1165(remove-function (process-filter proc) #'my-tracing-function) 1178(remove-function (process-filter @var{proc}) #'my-tracing-function)
1166@end example 1179@end example
1167 1180
1168The argument @code{:before} specifies how the two functions are composed, since 1181Similarly, if you want to trace the execution of the function named
1169there are many different ways to do it. The added function is also called an 1182@code{display-buffer}, you could use:
1170@emph{advice}. 1183
1184@example
1185(defun his-tracing-function (orig-fun &rest args)
1186 (message "display-buffer called with args %S" args)
1187 (let ((res (apply orig-fun args)))
1188 (message "display-buffer returned %S" res)
1189 res))
1190
1191(advice-add 'display-buffer :around #'his-tracing-function)
1192@end example
1171 1193
1172The function cell of a symbol can be manipulated similarly, but since it can 1194and when you're tired of seeing this output, you can revert to the untraced
1173contain other things than a plain function, you have to use @code{advice-add} 1195behavior with:
1174and @code{advice-remove} instead, which 1196
1175@c use @code{add-function} and @code{remove-function} internally, but 1197@example
1176know how to handle cases such as when the function cell holds a macro rather 1198(advice-remove 'display-buffer #'his-tracing-function)
1177than function, or when the function is autoloaded so the advice's activation 1199@end example
1178needs to be postponed. 1200
1201The arguments @code{:before} and @code{:above} used in the above examples
1202specify how the two functions are composed, since there are many different
1203ways to do it. The added function is also called an @emph{advice}.
1179 1204
1180@menu 1205@menu
1181* Advising Primitives:: Primitives to Manipulate Advices 1206* Core Advising Primitives:: Primitives to Manipulate Advices
1182* Advising Named Functions:: Advising Named Functions 1207* Advising Named Functions:: Advising Named Functions
1208* Porting old advices:: Adapting code using the old defadvice
1183@end menu 1209@end menu
1184 1210
1185@node Advising Primitives 1211@node Core Advising Primitives
1186@subsection Primitives to manipulate advice 1212@subsection Primitives to manipulate advices
1187 1213
1188@defmac add-function where place function &optional props 1214@defmac add-function where place function &optional props
1189This macro is the handy way to add the advice @var{function} to the function 1215This macro is the handy way to add the advice @var{function} to the function
1190stored in @var{place} (@pxref{Generalized Variables}). 1216stored in @var{place} (@pxref{Generalized Variables}).
1191 1217
1218If @var{function} is not interactive, then the combined function will inherit
1219the interactive spec, if any, of the original function. Else, the combined
1220function will be interactive and will use the interactive spec of
1221@var{function}. One exception: if the interactive spec of @var{function}
1222is a function (rather than an expression or a string), then the interactive
1223spec of the combined function will be a call to that function with as sole
1224argument the interactive spec of the original function. To interpret the spec
1225received as argument, use @code{advice-eval-interactive-spec}.
1226
1192@var{where} determines how @var{function} is composed with the 1227@var{where} determines how @var{function} is composed with the
1193existing function. It can be one of the following: 1228existing function. It can be one of the following:
1194 1229
@@ -1340,21 +1375,39 @@ Call the function @var{f} for every advice that was added to
1340and its properties. 1375and its properties.
1341@end defun 1376@end defun
1342 1377
1378@defun advice-eval-interactive-spec spec
1379Evaluate the interactive @var{spec} just like an interactive call to a function
1380with such a spec would, and then return the corresponding list of arguments
1381that was built. E.g. @code{(advice-eval-interactive-spec "r\nP")} will
1382return a list of three elements, containing the boundaries of the region and
1383the current prefix argument.
1384@end defun
1385
1343@node Advising Named Functions 1386@node Advising Named Functions
1344@subsection Advising Named Functions 1387@subsection Advising Named Functions
1345 1388
1346A common use of advice is for named functions and macros. 1389A common use of advice is for named functions and macros.
1347Since @code{add-function} does not know how to deal with macros and 1390You could just use @code{add-function} as in:
1348autoloaded functions, Emacs provides a separate set of functions to 1391
1349manipulate pieces of advice applied to named functions. 1392@example
1350 1393(add-function :around (symbol-function '@var{fun}) #'his-tracing-function)
1351 Advice can be useful for altering the behavior of an existing 1394@end example
1352function without having to redefine the whole function. However, it 1395
1353can be a source of bugs, since existing callers to the function may 1396 But you should use @code{advice-add} and @code{advice-remove} for that
1354assume the old behavior, and work incorrectly when the behavior is 1397instead. This separate set of functions to manipulate pieces of advice applied
1355changed by advice. Advice can also cause confusion in debugging, if 1398to named functions, offers the following extra features compared to
1356the person doing the debugging does not notice or remember that the 1399@code{add-function}: they know how to deal with macros and autoloaded
1357function has been modified by advice. 1400functions, they let @code{describe-function} preserve the original docstring as
1401well as document the added advice, and they let you add and remove advices
1402before a function is even defined.
1403
1404 @code{advice-add} can be useful for altering the behavior of existing calls
1405to an existing function without having to redefine the whole function.
1406However, it can be a source of bugs, since existing callers to the function may
1407assume the old behavior, and work incorrectly when the behavior is changed by
1408advice. Advice can also cause confusion in debugging, if the person doing the
1409debugging does not notice or remember that the function has been modified
1410by advice.
1358 1411
1359 For these reasons, advice should be reserved for the cases where you 1412 For these reasons, advice should be reserved for the cases where you
1360cannot modify a function's behavior in any other way. If it is 1413cannot modify a function's behavior in any other way. If it is
@@ -1400,6 +1453,88 @@ Call @var{function} for every advice that was added to the named function
1400and its properties. 1453and its properties.
1401@end defun 1454@end defun
1402 1455
1456@node Porting old advices
1457@subsection Adapting code using the old defadvice
1458
1459A lot of code uses the old @code{defadvice} mechanism, which is largely made
1460obsolete by the new @code{advice-add}, whose implementation and semantics is
1461significantly simpler.
1462
1463An old advice such as:
1464
1465@example
1466(defadvice previous-line (before next-line-at-end
1467 (&optional arg try-vscroll))
1468 "Insert an empty line when moving up from the top line."
1469 (if (and next-line-add-newlines (= arg 1)
1470 (save-excursion (beginning-of-line) (bobp)))
1471 (progn
1472 (beginning-of-line)
1473 (newline))))
1474@end example
1475
1476could be translated in the new advice mechanism into a plain function:
1477
1478@example
1479(defun previous-line--next-line-at-end (&optional arg try-vscroll)
1480 "Insert an empty line when moving up from the top line."
1481 (if (and next-line-add-newlines (= arg 1)
1482 (save-excursion (beginning-of-line) (bobp)))
1483 (progn
1484 (beginning-of-line)
1485 (newline))))
1486@end example
1487
1488Obviously, this does not actually modify @code{previous-line}. For that the
1489old advice needed:
1490@example
1491(ad-activate 'previous-line)
1492@end example
1493whereas the new advice mechanism needs:
1494@example
1495(advice-add 'previous-line :before #'previous-line--next-line-at-end)
1496@end example
1497
1498Note that @code{ad-activate} had a global effect: it activated all pieces of
1499advice enabled for that specified function. If you wanted to only activate or
1500deactivate a particular advice, you needed to @emph{enable} or @emph{disable}
1501that advice with @code{ad-enable-advice} and @code{ad-disable-advice}.
1502The new mechanism does away with this distinction.
1503
1504An around advice such as:
1505
1506@example
1507(defadvice foo (around foo-around)
1508 "Ignore case in `foo'."
1509 (let ((case-fold-search t))
1510 ad-do-it))
1511(ad-activate 'foo)
1512@end example
1513
1514could translate into:
1515
1516@example
1517(defun foo--foo-around (orig-fun &rest args)
1518 "Ignore case in `foo'."
1519 (let ((case-fold-search t))
1520 (apply orig-fun args)))
1521(advice-add 'foo :around #'foo--foo-around)
1522@end example
1523
1524Regarding the advice's @emph{class}, note that the new @code{:before} is not
1525quite equivalent to the old @code{before}, because in the old advice you could
1526modify the function's arguments (e.g., with @code{ad-set-arg}), and that would
1527affect the argument values seen by the original function, whereas in the new
1528@code{:before}, modifying an argument via @code{setq} in the advice has no
1529effect on the arguments seen by the original function.
1530When porting a @code{before} advice which relied on this behavior, you'll need
1531to turn it into a new @code{:around} or @code{:filter-args} advice instead.
1532
1533Similarly an old @code{after} advice could modify the returned value by
1534changing @code{ad-return-value}, whereas a new @code{:after} advice cannot, so
1535when porting such an old @code{after} advice, you'll need to turn it into a new
1536@code{:around} or @code{:filter-return} advice instead.
1537
1403@node Obsolete Functions 1538@node Obsolete Functions
1404@section Declaring Functions Obsolete 1539@section Declaring Functions Obsolete
1405@cindex obsolete functions 1540@cindex obsolete functions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 69419a3d1ea..3cec8c34a2c 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -27,8 +27,8 @@
27 * newcomment.el (comment-beginning): If `comment-start-skip' 27 * newcomment.el (comment-beginning): If `comment-start-skip'
28 doesn't match, move back one char and try again. (Bug#16971) 28 doesn't match, move back one char and try again. (Bug#16971)
29 29
30 * emacs-lisp/lisp-mode.el (lisp-mode-variables): Set 30 * emacs-lisp/lisp-mode.el (lisp-mode-variables):
31 `comment-use-syntax' to t to avoid the unnecessary runtime check. 31 Set `comment-use-syntax' to t to avoid the unnecessary runtime check.
32 Set `comment-start-skip' to a simpler value that doesn't try to 32 Set `comment-start-skip' to a simpler value that doesn't try to
33 check if the semicolon is escaped (this is handled by 33 check if the semicolon is escaped (this is handled by
34 `syntax-ppss' now). (Bug#16971) 34 `syntax-ppss' now). (Bug#16971)