refactor: switch buffer/frame/window hooks
Emacs 27 introduced a bunch of `window-*-change-functions` hooks, including `window-selection-change-functions` and `window-buffer-change-functions`, which handles 98% of the use case for Doom's `doom-switch-{buffer,window,frame}-hook` hooks, so I've rewritten them to use them under the hood, which amounts to simpler code and fewer hacks.
This commit is contained in:
parent
2614df72bd
commit
0bb4d4dfcb
4 changed files with 35 additions and 75 deletions
|
@ -75,62 +75,20 @@ font to that size. It's rarely a good idea to do so!")
|
||||||
(defvar doom-switch-frame-hook nil
|
(defvar doom-switch-frame-hook nil
|
||||||
"A list of hooks run after changing the focused frame.")
|
"A list of hooks run after changing the focused frame.")
|
||||||
|
|
||||||
(defvar doom-inhibit-switch-buffer-hooks nil
|
(defun doom-run-switch-buffer-hooks-h (&optional _)
|
||||||
"Letvar for inhibiting `doom-switch-buffer-hook'. Do not set this directly.")
|
(let ((gc-cons-threshold most-positive-fixnum)
|
||||||
(defvar doom-inhibit-switch-window-hooks nil
|
(inhibit-redisplay t))
|
||||||
"Letvar for inhibiting `doom-switch-window-hook'. Do not set this directly.")
|
(run-hooks 'doom-switch-buffer-hook)))
|
||||||
(defvar doom-inhibit-switch-frame-hooks nil
|
|
||||||
"Letvar for inhibiting `doom-switch-frame-hook'. Do not set this directly.")
|
|
||||||
|
|
||||||
(defvar doom--last-window nil)
|
|
||||||
(defvar doom--last-frame nil)
|
(defvar doom--last-frame nil)
|
||||||
|
(defun doom-run-switch-window-or-frame-hooks-h (&optional _)
|
||||||
(defun doom-run-switch-window-hooks-h ()
|
(let ((gc-cons-threshold most-positive-fixnum)
|
||||||
(unless (or doom-inhibit-switch-window-hooks
|
(inhibit-redisplay t))
|
||||||
(eq doom--last-window (selected-window))
|
(unless (equal (old-selected-frame) (selected-frame))
|
||||||
(minibufferp))
|
(run-hooks 'doom-switch-frame-hook))
|
||||||
(let ((gc-cons-threshold most-positive-fixnum)
|
(unless (or (minibufferp)
|
||||||
(doom-inhibit-switch-window-hooks t)
|
(equal (old-selected-window) (minibuffer-window)))
|
||||||
(inhibit-redisplay t))
|
(run-hooks 'doom-switch-window-hook))))
|
||||||
(run-hooks 'doom-switch-window-hook)
|
|
||||||
(setq doom--last-window (selected-window)))))
|
|
||||||
|
|
||||||
(defun doom-run-switch-frame-hooks-h (&rest _)
|
|
||||||
(unless (or doom-inhibit-switch-frame-hooks
|
|
||||||
(eq doom--last-frame (selected-frame))
|
|
||||||
(frame-parameter nil 'parent-frame))
|
|
||||||
(let ((gc-cons-threshold most-positive-fixnum)
|
|
||||||
(doom-inhibit-switch-frame-hooks t))
|
|
||||||
(run-hooks 'doom-switch-frame-hook)
|
|
||||||
(setq doom--last-frame (selected-frame)))))
|
|
||||||
|
|
||||||
(defun doom-run-switch-buffer-hooks-a (fn buffer-or-name &rest args)
|
|
||||||
(if (or doom-inhibit-switch-buffer-hooks
|
|
||||||
(and buffer-or-name
|
|
||||||
(eq (current-buffer)
|
|
||||||
(get-buffer buffer-or-name)))
|
|
||||||
(and (eq fn #'switch-to-buffer) (car args)))
|
|
||||||
(apply fn buffer-or-name args)
|
|
||||||
(let ((gc-cons-threshold most-positive-fixnum)
|
|
||||||
(doom-inhibit-switch-buffer-hooks t)
|
|
||||||
(inhibit-redisplay t))
|
|
||||||
(when-let (buffer (apply fn buffer-or-name args))
|
|
||||||
(with-current-buffer (if (windowp buffer)
|
|
||||||
(window-buffer buffer)
|
|
||||||
buffer)
|
|
||||||
(run-hooks 'doom-switch-buffer-hook))
|
|
||||||
buffer))))
|
|
||||||
|
|
||||||
(defun doom-run-switch-to-next-prev-buffer-hooks-a (fn &rest args)
|
|
||||||
(if doom-inhibit-switch-buffer-hooks
|
|
||||||
(apply fn args)
|
|
||||||
(let ((gc-cons-threshold most-positive-fixnum)
|
|
||||||
(doom-inhibit-switch-buffer-hooks t)
|
|
||||||
(inhibit-redisplay t))
|
|
||||||
(when-let (buffer (apply fn args))
|
|
||||||
(with-current-buffer buffer
|
|
||||||
(run-hooks 'doom-switch-buffer-hook))
|
|
||||||
buffer))))
|
|
||||||
|
|
||||||
(defun doom-protect-fallback-buffer-h ()
|
(defun doom-protect-fallback-buffer-h ()
|
||||||
"Don't kill the scratch buffer. Meant for `kill-buffer-query-functions'."
|
"Don't kill the scratch buffer. Meant for `kill-buffer-query-functions'."
|
||||||
|
@ -256,7 +214,6 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
||||||
buf))))
|
buf))))
|
||||||
(user-error "Aborted")))
|
(user-error "Aborted")))
|
||||||
(let ((inhibit-redisplay t)
|
(let ((inhibit-redisplay t)
|
||||||
(doom-inhibit-switch-buffer-hooks t)
|
|
||||||
buffer-list-update-hook)
|
buffer-list-update-hook)
|
||||||
(when (or ;; if there aren't more real buffers than visible buffers,
|
(when (or ;; if there aren't more real buffers than visible buffers,
|
||||||
;; then there are no real, non-visible buffers left.
|
;; then there are no real, non-visible buffers left.
|
||||||
|
@ -270,7 +227,7 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
||||||
(with-current-buffer buf
|
(with-current-buffer buf
|
||||||
(restore-buffer-modified-p nil))
|
(restore-buffer-modified-p nil))
|
||||||
(kill-buffer buf)))
|
(kill-buffer buf)))
|
||||||
(run-hooks 'doom-switch-buffer-hook 'buffer-list-update-hook)
|
(run-hooks 'buffer-list-update-hook)
|
||||||
t)))))
|
t)))))
|
||||||
|
|
||||||
|
|
||||||
|
@ -645,18 +602,14 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
||||||
|
|
||||||
;; Initialize custom switch-{buffer,window,frame} hooks:
|
;; Initialize custom switch-{buffer,window,frame} hooks:
|
||||||
;;
|
;;
|
||||||
;; + `doom-switch-buffer-hook'
|
;; - `doom-switch-buffer-hook'
|
||||||
;; + `doom-switch-window-hook'
|
;; - `doom-switch-window-hook'
|
||||||
;; + `doom-switch-frame-hook'
|
;; - `doom-switch-frame-hook'
|
||||||
;;
|
;;
|
||||||
;; These should be done as late as possible, as not to prematurely trigger
|
;; These should be done as late as possible, as not to prematurely trigger
|
||||||
;; hooks during startup.
|
;; hooks during startup.
|
||||||
(add-hook 'buffer-list-update-hook #'doom-run-switch-window-hooks-h)
|
(add-hook 'window-buffer-change-functions #'doom-run-switch-buffer-hooks-h)
|
||||||
(add-hook 'focus-in-hook #'doom-run-switch-frame-hooks-h)
|
(add-hook 'window-selection-change-functions #'doom-run-switch-window-or-frame-hooks-h))
|
||||||
(dolist (fn '(switch-to-next-buffer switch-to-prev-buffer))
|
|
||||||
(advice-add fn :around #'doom-run-switch-to-next-prev-buffer-hooks-a))
|
|
||||||
(dolist (fn '(switch-to-buffer display-buffer))
|
|
||||||
(advice-add fn :around #'doom-run-switch-buffer-hooks-a)))
|
|
||||||
|
|
||||||
;; Apply `doom-font' et co
|
;; Apply `doom-font' et co
|
||||||
(let ((hook (if (daemonp) 'server-after-make-frame-hook)))
|
(let ((hook (if (daemonp) 'server-after-make-frame-hook)))
|
||||||
|
|
|
@ -477,6 +477,14 @@ If this is a daemon session, load them all immediately instead."
|
||||||
(cdr doom-incremental-packages) t))))
|
(cdr doom-incremental-packages) t))))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Fixes/hacks
|
||||||
|
|
||||||
|
;; Produce more helpful (and visible) error messages from errors emitted from
|
||||||
|
;; hooks (particularly mode hooks, that usually go unnoticed otherwise.
|
||||||
|
(advice-add #'run-hooks :override #'doom-run-hooks)
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; Bootstrapper
|
;;; Bootstrapper
|
||||||
|
|
||||||
|
|
|
@ -147,12 +147,12 @@ more information on modifiers."
|
||||||
;; HACK This ping-ponging between the destination and source windows is to
|
;; HACK This ping-ponging between the destination and source windows is to
|
||||||
;; update the window focus history, so that, if you close either split
|
;; update the window focus history, so that, if you close either split
|
||||||
;; afterwards you won't be sent to some random window.
|
;; afterwards you won't be sent to some random window.
|
||||||
(let ((doom-inhibit-switch-window-hooks t)
|
(let ((origwin (selected-window))
|
||||||
(origwin (selected-window)))
|
window-selection-change-functions)
|
||||||
(select-window (split-window origwin count 'below))
|
(select-window (split-window origwin count 'below))
|
||||||
(unless evil-split-window-below
|
(unless evil-split-window-below
|
||||||
(select-window origwin))
|
(select-window origwin)))
|
||||||
(run-hooks 'doom-switch-window-hook))
|
(run-hooks 'window-selection-change-functions)
|
||||||
(recenter)
|
(recenter)
|
||||||
(when (and (not count) evil-auto-balance-windows)
|
(when (and (not count) evil-auto-balance-windows)
|
||||||
(balance-windows (window-parent)))
|
(balance-windows (window-parent)))
|
||||||
|
@ -166,13 +166,12 @@ more information on modifiers."
|
||||||
;; HACK This ping-ponging between the destination and source windows is to
|
;; HACK This ping-ponging between the destination and source windows is to
|
||||||
;; update the window focus history, so that, if you close either split
|
;; update the window focus history, so that, if you close either split
|
||||||
;; afterwards you won't be sent to some random window.
|
;; afterwards you won't be sent to some random window.
|
||||||
(let ((doom-inhibit-switch-window-hooks t)
|
(let ((origwin (selected-window))
|
||||||
(origwin (selected-window)))
|
window-selection-change-functions)
|
||||||
(select-window (split-window origwin count 'right))
|
(select-window (split-window origwin count 'right))
|
||||||
(unless evil-vsplit-window-right
|
(unless evil-vsplit-window-right
|
||||||
(select-window origwin))
|
(select-window origwin)))
|
||||||
(run-hooks 'doom-switch-window-hook))
|
(run-hooks 'window-selection-change-functions)
|
||||||
(run-hooks)
|
|
||||||
(recenter)
|
(recenter)
|
||||||
(when (and (not count) evil-auto-balance-windows)
|
(when (and (not count) evil-auto-balance-windows)
|
||||||
(balance-windows (window-parent)))
|
(balance-windows (window-parent)))
|
||||||
|
|
|
@ -11,5 +11,5 @@
|
||||||
|
|
||||||
(defadvice! +hydra--inhibit-window-switch-hooks-a (fn)
|
(defadvice! +hydra--inhibit-window-switch-hooks-a (fn)
|
||||||
:around #'lv-window
|
:around #'lv-window
|
||||||
(let ((doom-inhibit-switch-window-hooks t))
|
(let (doom-switch-window-hook)
|
||||||
(funcall fn)))
|
(funcall fn)))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue