28.28 Hooks for Window Scrolling and Changes
This section describes how Lisp programs can take action after a window has been scrolled or other window modifications occurred. We first consider the case where a window shows a different part of its buffer.
variable
window-scroll-functions​
This variable holds a list of functions that Emacs should call before redisplaying a window with scrolling. Displaying a different buffer in a window and making a new window also call these functions.
This variable is not a normal hook, because each function is called with two arguments: the window, and its new display-start position. At the time of the call, the display-start position of the argument window is already set to its new value, and the buffer to be displayed in the window is set as the current buffer.
These functions must take care when using window-end
(see Window Start and End); if you need an up-to-date value, you must use the update
argument to ensure you get it.
Warning: don’t use this feature to alter the way the window is scrolled. It’s not designed for that, and such use probably won’t work.
In addition, you can use jit-lock-register
to register a Font Lock fontification function, which will be called whenever parts of a buffer are (re)fontified because a window was scrolled or its size changed. See Other Font Lock Variables.
The remainder of this section covers six hooks that are called during redisplay provided a significant, non-scrolling change of a window has been detected. For simplicity, these hooks and the functions they call will be collectively referred to as window change functions.
The first of these hooks is run after a window buffer change is detected, which means that a window was created, deleted or assigned another buffer.
variable
window-buffer-change-functions​
This variable specifies functions called during redisplay when window buffers have changed. The value should be a list of functions that take one argument.
Functions specified buffer-locally are called for any window showing the corresponding buffer if that window has been created or assigned that buffer since the last time window change functions were run. In this case the window is passed as argument.
Functions specified by the default value are called for a frame if at least one window on that frame has been added, deleted or assigned another buffer since the last time window change functions were run. In this case the frame is passed as argument.
The second of these hooks is run when a window size change has been detected which means that a window was created, assigned another buffer, or changed its total size or that of its text area.
variable
window-size-change-functions​
This variable specifies functions called during redisplay when a window size change occurred. The value should be a list of functions that take one argument.
Functions specified buffer-locally are called for any window showing the corresponding buffer if that window has been added or assigned another buffer or changed its total or body size since the last time window change functions were run. In this case the window is passed as argument.
Functions specified by the default value are called for a frame if at least one window on that frame has been added or assigned another buffer or changed its total or body size since the last time window change functions were run. In this case the frame is passed as argument.
The third of these hooks is run when a window selection change has selected another window since the last redisplay.
variable
window-selection-change-functions​
This variable specifies functions called during redisplay when the selected window or a frame’s selected window has changed. The value should be a list of functions that take one argument.
Functions specified buffer-locally are called for any window showing the corresponding buffer if that window has been selected or deselected (among all windows or among all windows on its frame) since the last time window change functions were run. In this case the window is passed as argument.
Functions specified by the default value are called for a frame if that frame has been selected or deselected or the frame’s selected window has changed since the last time window change functions were run. In this case the frame is passed as argument.
The fourth of these hooks is run when a window state change has been detected, which means that at least one of the three preceding window changes has occurred.
variable
window-state-change-functions​
This variable specifies functions called during redisplay when a window buffer or size change occurred or the selected window or a frame’s selected window has changed. The value should be a list of functions that take one argument.
Functions specified buffer-locally are called for any window showing the corresponding buffer if that window has been added or assigned another buffer, changed its total or body size or has been selected or deselected (among all windows or among all windows on its frame) since the last time window change functions were run. In this case the window is passed as argument.
Functions specified by the default value are called for a frame if at least one window on that frame has been added, deleted or assigned another buffer, changed its total or body size or that frame has been selected or deselected or the frame’s selected window has changed since the last time window change functions were run. In this case the frame is passed as argument.
Functions specified by the default value are also run for a frame when that frame’s window state change flag (see below) has been set since last redisplay.
The fifth of these hooks is run when a window configuration change has been detected which means that either the buffer or the size of a window changed. It differs from the four preceding hooks in the way it is run.
variable
window-configuration-change-hook​
This variable specifies functions called during redisplay when either the buffer or the size of a window has changed. The value should be a list of functions that take no argument.
Functions specified buffer-locally are called for any window showing the corresponding buffer if at least one window on that frame has been added, deleted or assigned another buffer or changed its total or body size since the last time window change functions were run. Each call is performed with the window showing the buffer temporarily selected and its buffer current.
Functions specified by the default value are called for each frame if at least one window on that frame has been added, deleted or assigned another buffer or changed its total or body size since the last time window change functions were run. Each call is performed with the frame temporarily selected and the selected window’s buffer current.
Finally, Emacs runs a normal hook that generalizes the behavior of window-state-change-functions
.
variable
window-state-change-hook​
The default value of this variable specifies functions called during redisplay when a window state change has been detected or the window state change flag has been set on at least one frame. The value should be a list of functions that take no argument.
Applications should put a function on this hook only if they want to react to changes that happened on (or have been signaled for) two or more frames since last redisplay. In every other case, putting the function on window-state-change-functions
should be preferred.
Window change functions are called during redisplay for each frame as follows: First, any buffer-local window buffer change function, window size change function, selected window change and window state change functions are called in this order. Next, the default values for these functions are called in the same order. Then any buffer-local window configuration change functions are called followed by functions specified by the default value of those functions. Finally, functions on window-state-change-hook
are run.
Window change functions are run for a specific frame only if a corresponding change was registered for that frame earlier. Such changes include the creation or deletion of a window or the assignment of another buffer or size to a window. Note that even when such a change has been registered, this does not mean that any of the hooks described above is run. If, for example, a change was registered within the scope of a window excursion (see Window Configurations), this will trigger a call of window change functions only if that excursion still persists at the time change functions are run. If it is exited earlier, hooks will be run only if registered by a change outside the scope of that excursion.
The window state change flag of a frame, if set, will cause the default values of window-state-change-functions
(for that frame) and window-state-change-hook
to be run during next redisplay regardless of whether a window state change actually occurred for that frame or not. After running any functions on these hooks, the flag is reset for each frame. Applications can set that flag and inspect its value using the following functions.
function
set-frame-window-state-change \&optional frame arg​
This function sets frame
’s window state change flag if arg
is non-nil
and resets it otherwise. frame
must be a live frame and defaults to the selected one.
function
frame-window-state-change \&optional frame​
This functions returns t
if frame
’s window state change flag is set and nil
otherwise. frame
must be a live frame and defaults to the selected one.
While window change functions are run, the functions described next can be called to get more insight into what has changed for a specific window or frame since the last redisplay. All these functions take a live window as single, optional argument, defaulting to the selected window.
function
window-old-buffer \&optional window​
This function returns the buffer shown in window
at the last time window change functions were run for window
’s frame. If it returns nil
, window
has been created after that. If it returns t
, window
was not shown at that time but has been restored from a previously saved window configuration afterwards. Otherwise, the return value is the buffer shown by window
at that time.
function
window-old-pixel-width \&optional window​
This function returns the total pixel width of window
the last time window change functions found window
live on its frame. It is zero if window
was created after that.
function
window-old-pixel-height \&optional window​
This function returns the total pixel height of window
the last time window change functions found window
live on its frame. It is zero if window
was created after that.
function
window-old-body-pixel-width \&optional window​
This function returns the pixel width of window
’s text area the last time window change functions found window
live on its frame. It is zero if window
was created after that.
function
window-old-body-pixel-height \&optional window​
This function returns the pixel height of window
’s text area the last time window change functions found window
live on its frame. It is zero if window
was created after that.
In order to find out which window or frame was selected the last time window change functions were run, the following functions can be used:
function
frame-old-selected-window \&optional frame​
This function returns the selected window of frame
at the last time window change functions were run. If omitted or nil
frame
defaults to the selected frame.
function
old-selected-window​
This function returns the selected window at the last time window change functions were run.
function
old-selected-frame​
This function returns the selected frame at the last time window change functions were run.
Note that window change functions provide no information about which windows have been deleted since the last time they were run. If necessary, applications should remember any window showing a specific buffer in a local variable of that buffer and update it in a function run by the default values of any of the hooks that are run when a window buffer change was detected.
The following caveats should be considered when adding a function to window change functions:
- Some operations will not trigger a call of window change functions. These include showing another buffer in a minibuffer window or any change of a tooltip window.
- Window change functions should not create or delete windows or change the buffer, size or selection status of any window because there is no guarantee that the information about such a change will be propagated to other window change functions. If at all, any such change should be executed only by the last function listed by the default value of
window-state-change-hook
. - Macros like
save-window-excursion
,with-selected-window
orwith-current-buffer
can be used when running window change functions. - Running window change functions does not save and restore match data. Unless running
window-configuration-change-hook
it does not save or restore the selected window or frame or the current buffer either. - Any redisplay triggering the run of window change functions may be aborted. If the abort occurs before window change functions have run to their completion, they will be run again with the previous values, that is, as if redisplay had not been performed. If aborted later, they will be run with the new values, that is, as if redisplay had been actually performed.