diff options
Diffstat (limited to 'devdocs/elisp/core-advising-primitives.html')
| -rw-r--r-- | devdocs/elisp/core-advising-primitives.html | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/devdocs/elisp/core-advising-primitives.html b/devdocs/elisp/core-advising-primitives.html new file mode 100644 index 00000000..9b142519 --- /dev/null +++ b/devdocs/elisp/core-advising-primitives.html @@ -0,0 +1,42 @@ + <h4 class="subsection">Primitives to manipulate advices</h4> <dl> <dt id="add-function">Macro: <strong>add-function</strong> <em>where place function &optional props</em> +</dt> <dd> +<p>This macro is the handy way to add the advice <var>function</var> to the function stored in <var>place</var> (see <a href="generalized-variables">Generalized Variables</a>). </p> <p><var>where</var> determines how <var>function</var> is composed with the existing function, e.g., whether <var>function</var> should be called before, or after the original function. See <a href="advice-combinators">Advice Combinators</a>, for the list of available ways to compose the two functions. </p> <p>When modifying a variable (whose name will usually end with <code>-function</code>), you can choose whether <var>function</var> is used globally or only in the current buffer: if <var>place</var> is just a symbol, then <var>function</var> is added to the global value of <var>place</var>. Whereas if <var>place</var> is of the form <code>(local <var>symbol</var>)</code>, where <var>symbol</var> is an expression which returns the variable name, then <var>function</var> will only be added in the current buffer. Finally, if you want to modify a lexical variable, you will have to use <code>(var <var>variable</var>)</code>. </p> <p>Every function added with <code>add-function</code> can be accompanied by an association list of properties <var>props</var>. Currently only two of those properties have a special meaning: </p> <dl compact> <dt><code>name</code></dt> <dd> +<p>This gives a name to the advice, which <code>remove-function</code> can use to identify which function to remove. Typically used when <var>function</var> is an anonymous function. </p> </dd> <dt><code>depth</code></dt> <dd> +<p>This specifies how to order the advice, should several pieces of advice be present. By default, the depth is 0. A depth of 100 indicates that this piece of advice should be kept as deep as possible, whereas a depth of -100 indicates that it should stay as the outermost piece. When two pieces of advice specify the same depth, the most recently added one will be outermost. </p> <p>For <code>:before</code> advice, being outermost means that this advice will be run first, before any other advice, whereas being innermost means that it will run right before the original function, with no other advice run between itself and the original function. Similarly, for <code>:after</code> advice innermost means that it will run right after the original function, with no other advice run in between, whereas outermost means that it will be run right at the end after all other advice. An innermost <code>:override</code> piece of advice will only override the original function and other pieces of advice will apply to it, whereas an outermost <code>:override</code> piece of advice will override not only the original function but all other advice applied to it as well. </p> +</dd> </dl> <p>If <var>function</var> is not interactive, then the combined function will inherit the interactive spec, if any, of the original function. Else, the combined function will be interactive and will use the interactive spec of <var>function</var>. One exception: if the interactive spec of <var>function</var> is a function (i.e., a <code>lambda</code> expression or an <code>fbound</code> symbol rather than an expression or a string), then the interactive spec of the combined function will be a call to that function with the interactive spec of the original function as sole argument. To interpret the spec received as argument, use <code>advice-eval-interactive-spec</code>. </p> <p>Note: The interactive spec of <var>function</var> will apply to the combined function and should hence obey the calling convention of the combined function rather than that of <var>function</var>. In many cases, it makes no difference since they are identical, but it does matter for <code>:around</code>, <code>:filter-args</code>, and <code>:filter-return</code>, where <var>function</var> receives different arguments than the original function stored in <var>place</var>. </p> +</dd> +</dl> <dl> <dt id="remove-function">Macro: <strong>remove-function</strong> <em>place function</em> +</dt> <dd> +<p>This macro removes <var>function</var> from the function stored in <var>place</var>. This only works if <var>function</var> was added to <var>place</var> using <code>add-function</code>. </p> <p><var>function</var> is compared with functions added to <var>place</var> using <code>equal</code>, to try and make it work also with lambda expressions. It is additionally compared also with the <code>name</code> property of the functions added to <var>place</var>, which can be more reliable than comparing lambda expressions using <code>equal</code>. </p> +</dd> +</dl> <dl> <dt id="advice-function-member-p">Function: <strong>advice-function-member-p</strong> <em>advice function-def</em> +</dt> <dd><p>Return non-<code>nil</code> if <var>advice</var> is already in <var>function-def</var>. Like for <code>remove-function</code> above, instead of <var>advice</var> being the actual function, it can also be the <code>name</code> of the piece of advice. </p></dd> +</dl> <dl> <dt id="advice-function-mapc">Function: <strong>advice-function-mapc</strong> <em>f function-def</em> +</dt> <dd><p>Call the function <var>f</var> for every piece of advice that was added to <var>function-def</var>. <var>f</var> is called with two arguments: the advice function and its properties. </p></dd> +</dl> <dl> <dt id="advice-eval-interactive-spec">Function: <strong>advice-eval-interactive-spec</strong> <em>spec</em> +</dt> <dd> +<p>Evaluate the interactive <var>spec</var> just like an interactive call to a function with such a spec would, and then return the corresponding list of arguments that was built. E.g., <code>(advice-eval-interactive-spec "r\nP")</code> will return a list of three elements, containing the boundaries of the region and the current prefix argument. </p> <p>For instance, if you want to make the <kbd>C-x m</kbd> (<code>compose-mail</code>) command prompt for a ‘<samp>From:</samp>’ header, you could say something like this: </p> <div class="example"> <pre class="example">(defun my-compose-mail-advice (orig &rest args) + "Read From: address interactively." + (interactive + (lambda (spec) + (let* ((user-mail-address + (completing-read "From: " + '("one.address@example.net" + "alternative.address@example.net"))) + (from (message-make-from user-full-name + user-mail-address)) + (spec (advice-eval-interactive-spec spec))) + ;; Put the From header into the OTHER-HEADERS argument. + (push (cons 'From from) (nth 2 spec)) + spec))) + (apply orig args)) + +(advice-add 'compose-mail :around #'my-compose-mail-advice) +</pre> +</div> </dd> +</dl><div class="_attribution"> + <p class="_attribution-p"> + Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br> + <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Core-Advising-Primitives.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Core-Advising-Primitives.html</a> + </p> +</div> |
