may or may not run this hook.
@end defvar
+@defvar revert-buffer-restore-functions
+The value of this variable specifies a list of functions that preserve
+the state of the buffer. Before the revert operation each function from
+this list is called without arguments, and it should return a lambda
+that preserves some particular state (for example, the read-only state).
+After the revert operation each lambda will be called one by one in the
+order of the list, and it should restore the saved state in the reverted
+buffer.
+@end defvar
+
Emacs can revert buffers automatically. It does that by default for
buffers visiting files. The following describes how to add support
for auto-reverting new types of buffers.
** New buffer-local variable 'tabulated-list-groups'.
It controls display and separate sorting of groups of entries.
++++
+** New variable 'revert-buffer-restore-functions'.
+It helps to preserve various states after reverting the buffer.
+
---
** New text property 'context-menu-functions'.
Like the variable with the same name, it adds menus from the list that
["Quit" quit-window
:help "Remove the buffer menu from the display"]))
+(declare-function outline-minor-mode-highlight-buffer "outline" ())
+
(define-derived-mode Buffer-menu-mode tabulated-list-mode "Buffer Menu"
"Major mode for Buffer Menu buffers.
The Buffer Menu is invoked by the commands \\[list-buffers],
:interactive nil
(setq-local buffer-stale-function
(lambda (&optional _noconfirm) 'fast))
- (add-hook 'tabulated-list-revert-hook 'list-buffers--refresh nil t))
+ (add-hook 'tabulated-list-revert-hook 'list-buffers--refresh nil t)
+ (add-hook 'revert-buffer-restore-functions
+ (lambda ()
+ (when (bound-and-true-p outline-minor-mode)
+ (lambda ()
+ (outline-minor-mode-highlight-buffer))))
+ nil t))
(defun buffer-menu--display-help ()
(message "%s"
;; `preserve-modes' argument of `revert-buffer'.
(defvar revert-buffer-preserve-modes)
+(defvar revert-buffer-restore-functions '(revert-buffer-restore-read-only)
+ "Functions to preserve any state during `revert-buffer'.
+The value of this variable is a list of functions that are called before
+reverting the buffer. Each of these functions are called without
+arguments and should return a lambda that can restore a previous state
+of the buffer. Then after reverting the buffer each of these lambdas
+will be called one by one in the order of the list to restore previous
+states of the buffer. An example of the buffer state is keeping the
+buffer read-only, or keeping minor modes, etc.")
+
+(defun revert-buffer-restore-read-only ()
+ "Preserve read-only state for `revert-buffer'."
+ (when-let ((state (and (boundp 'read-only-mode--state)
+ (list read-only-mode--state))))
+ (lambda ()
+ (setq buffer-read-only (car state))
+ (setq-local read-only-mode--state (car state)))))
+
(defun revert-buffer (&optional ignore-auto noconfirm preserve-modes)
"Replace current buffer text with the text of the visited file on disk.
This undoes all changes since the file was visited or saved.
(interactive (list (not current-prefix-arg)))
(let ((revert-buffer-in-progress-p t)
(revert-buffer-preserve-modes preserve-modes)
- (state (and (boundp 'read-only-mode--state)
- (list read-only-mode--state))))
+ restore-functions)
+ (run-hook-wrapped 'revert-buffer-restore-functions
+ (lambda (f) (push (funcall f) restore-functions) nil))
;; Return whatever 'revert-buffer-function' returns.
(prog1 (funcall (or revert-buffer-function #'revert-buffer--default)
ignore-auto noconfirm)
- (when state
- (setq buffer-read-only (car state))
- (setq-local read-only-mode--state (car state))))))
+ (mapc #'funcall (delq nil restore-functions)))))
(defun revert-buffer--default (ignore-auto noconfirm)
"Default function for `revert-buffer'.