I am trying to execute when the active buffer has changed by either
C-x <left>
).C-x o
). Are their hooks suitable for detecting this?
Looking through the Standard Hooks I found the following options, none of which quite do what I want:
buffer-list-update-hook
is called for both (1) and (2). It is however unsuitable, because it is run before the buffer is changed, while I want to know what the current-buffer
after the change is.
window-configuration-change-hook
can be used to detect a change of the buffer displayed in the current window, and it is run after the change, as needed. It is however not run for M-x other-window
.
mouse-leave-buffer-hook
seems viable for detecting mouse-based window switching, but it gets called a bit often (for me four times upon switching windows with the mouse, three times before and once after switching), which requires additional logical to prevent multiple execution.
post-command-hook
would be viable but a bit heavy handed, risking significant slow-down of the editor by even minor bugs.
Since my action would need to use with-selected-window
, which triggers these hooks, care has to be taken to avoid endless loops where the hook triggers itself.
Judging from the comments, the answer to this question is “No, there is no such hook.”
Additionally, some of the hooks mentioned in my question, are also triggered by changes, which are not user-visible, such as temporary changes due to with-current-buffer
and with-selected-window
.
However, using post-command-hook
has proven to be a non-issue for performance, since the required state-check is cheap.
Probably obvious, but stated for completeness.
Store state information in a global variable, in a frame-parameter, in a window-parameter or in a buffer-local variable, whichever is most applicable to the use-case. In my use-case, this necessary unique state is was defined by current-buffer
, current-window
, and in one case line-beginning-position
.*
In post-command-hook
, check if the state has changed, possibly skipping
even that, if this-command
is self-insert-command
.
* line-number-at-pos
is unsuitable, because it counts lines by iterating over the buffer from point-min
to point
, making it generally cheap, but not cheap enough to be executed after every typed character.
Emacs27.1 introduce a new variable called `window-buffer-change-functions'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With