Emacs Lisp: Advice Combinators
— Kaushal ModiMy diagrammatic take on summarizing all the Emacs advice combinators.
- Improved the diagrams for
:before-while
,:before-until
,:after-while
and:after-until
. Thanks @shom for the feedback.
If you have read some of my earlier posts, you would know that I really enjoy using the Emacs Advice system 😃.
The “advice” feature lets you add to the existing definition of a function, by advising the function. This is a cleaner method than redefining the whole function, because it’s easier to debug and if you don’t need it, you can just remove the advice.
You can jump to the References section below if you need to look at the related sections in the Emacs Lisp Manual.
Overview on using advices #
I do not plan to write a tutorial on how to write advices in Emacs-Lisp, but here’s a 3-second primer:
- To add an advice
(advice-add 'original-fn <combinator> #'advising-fn)
- To remove an advice
(advice-remove 'original-fn #'advising-fn)
This article attempts to briefly describe different ways of advising a function, using 10 different combinators. If you have never used advices in your Emacs config, don’t worry. I am hopeful that the diagrams in this post and the examples linked for some of the combinators in the Summary section makes this concept a bit easier to assimilate.
- Diagram Legend
- Initial black circle: Original Fn input arguments
- Yellow box: Original Fn
- Gray box: Advising Fn
- Black circle inside a white circle: Return values
1 :before
#
2 :after
#
3 :override
#
4 :around
#
5 :before-while
#
6 :before-until
#
7 :after-while
#
8 :after-until
#
9 :filter-args
#
10 :filter-return
#
Summary #
Here’s a concise summary of what each advice combinator does. For brevity, the advising function is called A and the original function is called O.
Once you click on any of the example posts, search for advice-add
on
that page to find the code example.
Combinator | Description | Example |
---|---|---|
:before | A is called before O. O args and return values are not modified. | |
:after | A is called after O. O args and return values are not modified. | |
:override | A is called in lieu of O. A gets the same args as O. | Zero HTML Validation Errors! |
:around | A is called in lieu of O. A gets O fn + O args as args. | Using Emacs advice to silence messages from functions |
:before-while | A is called first. If it returns non-nil, O is called. | |
:before-until | A is called first. If it returns nil, O is called. | Org: Show only Post subtree headings |
:after-while | O is called first. If it returns non-nil, A is called. | |
:after-until | O is called first. If it returns nil, A is called. | |
:filter-args | A is called first. O is called next with return value from A as input. | Narrowing the Author column in Magit |
:filter-return | O is called first. A is called next with return value from O as input. | Zero HTML Validation Errors! |
If you have any feedback on how these diagrams can be made easier to understand, please let me know.