Rewrite switch-{buffer,window} hooks

+ Add doom-switch-frame-hook
+ Replace doom-{enter,exit}-{buffer,window}-hook with
  doom-switch-{buffer,window}-hook
+ New switch-buffer hooks run on buffer-list-update-hook rather than
  in select-window advice.
+ Blank our buffer-list-update-hook in some places to reduce how many
  times it gets triggered.
This commit is contained in:
Henrik Lissner 2019-03-07 00:26:51 -05:00
parent 8f2fb07948
commit a05b1877be
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
9 changed files with 93 additions and 104 deletions

View file

@ -66,71 +66,60 @@ behavior). Do not set this directly, this is let-bound in `doom|init-theme'.")
"Hook run after the theme is loaded with `load-theme' or reloaded with
`doom/reload-theme'.")
(defvar doom-exit-window-hook nil
"Hook run before `switch-window' or `switch-frame' are called.
(defvar doom-switch-buffer-hook nil
"TODO")
Also see `doom-enter-window-hook'.")
(defvar doom-switch-window-hook nil
"TODO")
(defvar doom-enter-window-hook nil
"Hook run after `switch-window' or `switch-frame' are called.
Also see `doom-exit-window-hook'.")
(defvar doom-exit-buffer-hook nil
"Hook run after `switch-to-buffer', `pop-to-buffer' or `display-buffer' are
called. The buffer to be switched to is current when these hooks run.
Also see `doom-enter-buffer-hook'.")
(defvar doom-enter-buffer-hook nil
"Hook run before `switch-to-buffer', `pop-to-buffer' or `display-buffer' are
called. The buffer to be switched to is current when these hooks run.
Also see `doom-exit-buffer-hook'.")
(defvar doom-switch-frame-hook nil
"TODO")
(defvar doom-inhibit-switch-buffer-hooks nil
"Letvar for inhibiting `doom-enter-buffer-hook' and `doom-exit-buffer-hook'.
Do not set this directly.")
"Letvar for inhibiting `doom-switch-buffer-hook'. Do not set this directly.")
(defvar doom-inhibit-switch-window-hooks nil
"Letvar for inhibiting `doom-enter-window-hook' and `doom-exit-window-hook'.
Do not set this directly.")
"Letvar for inhibiting `doom-switch-window-hook'. Do not set this directly.")
(defvar doom-inhibit-switch-frame-hooks nil
"Letvar for inhibiting `doom-switch-frame-hook'. Do not set this directly.")
(defun doom*switch-window-hooks (orig-fn window &optional norecord)
(if (or doom-inhibit-switch-window-hooks
norecord
(eq window (selected-window))
(window-minibuffer-p window))
(funcall orig-fn window norecord)
(let ((doom-inhibit-switch-window-hooks t))
(run-hooks 'doom-exit-window-hook)
(prog1 (funcall orig-fn window norecord)
(run-hooks 'doom-enter-window-hook)))))
(defvar doom--last-window nil)
(defvar doom--last-frame nil)
(defun doom*switch-buffer-hooks (orig-fn buffer-or-name &rest args)
(defun doom|run-switch-window-hooks ()
(unless (or doom-inhibit-switch-buffer-hooks
(eq doom--last-window (selected-window))
(minibufferp))
(let ((doom-inhibit-switch-buffer-hooks t))
(run-hooks 'doom-switch-window-hook)
(doom-log "Window switched to %s" (selected-window))
(setq doom--last-window (selected-window)))))
(defun doom|run-switch-frame-hooks (&rest _)
(let ((selected-frame (selected-frame)))
(unless (or doom-inhibit-switch-frame-hooks
(eq doom--last-frame (selected-frame))
(frame-parameter nil 'parent-frame))
(let ((doom-inhibit-switch-frame-hooks t))
(run-hooks 'doom-switch-frame-hook)
(doom-log "Frame switched to %s" (selected-frame))
(setq doom--last-frame (selected-frame))))))
(defun doom*run-switch-buffer-hooks (orig-fn buffer-or-name &rest args)
(if (or doom-inhibit-switch-buffer-hooks
(null buffer-or-name)
(if (eq orig-fn 'switch-to-buffer) (car args))
(if (eq orig-fn 'pop-to-buffer) (nth 1 args))
(eq (get-buffer buffer-or-name) (current-buffer)))
(if (eq orig-fn 'switch-to-buffer)
(car args) ; norecord
(eq (get-buffer buffer-or-name) (current-buffer))))
(apply orig-fn buffer-or-name args)
(let ((doom-inhibit-switch-buffer-hooks t))
(run-hooks 'doom-exit-buffer-hook)
(doom-log "Buffer switched in %s" (selected-window))
(prog1 (apply orig-fn buffer-or-name args)
(run-hooks 'doom-enter-buffer-hook)))))
(run-hooks 'doom-switch-buffer-hook)))))
(defun doom-init-switch-hooks (&optional disable)
(dolist (spec '((select-window . doom*switch-window-hooks)
(switch-to-buffer . doom*switch-buffer-hooks)
(display-buffer . doom*switch-buffer-hooks)
(pop-to-buffer . doom*switch-buffer-hooks)))
(if disable
(advice-remove (car spec) (cdr spec))
(advice-add (car spec) :around (cdr spec)))))
(defun doom*load-theme-hooks (theme &rest _)
(defun doom*run-load-theme-hooks (theme &optional _no-confirm no-enable)
"Set up `doom-load-theme-hook' to run after `load-theme' is called."
(setq doom-theme theme)
(run-hooks 'doom-load-theme-hook))
(unless no-enable
(setq doom-theme theme)
(run-hooks 'doom-load-theme-hook)))
(defun doom|protect-visible-buffer ()
"Don't kill the current buffer if it is visible in another window (bury it
@ -292,13 +281,14 @@ read-only or not file-visiting."
(def-package! winner
;; undo/redo changes to Emacs' window layout
:hook (doom-exit-window . winner-mode)
:preface (defvar winner-dont-bind-my-keys t)) ; I'll bind keys myself
:after-call (after-find-file doom-switch-window-hook)
:preface (defvar winner-dont-bind-my-keys t)
:config (winner-mode +1)) ; I'll bind keys myself
(def-package! paren
;; highlight matching delimiters
:after-call (after-find-file doom-exit-buffer-hook)
:after-call (after-find-file doom-switch-buffer-hook)
:init
(defun doom|disable-show-paren-mode ()
"Turn off `show-paren-mode' buffer-locally."
@ -539,9 +529,13 @@ frame's window-system, the theme will be reloaded.")
(add-hook 'after-make-frame-functions #'doom|reload-theme-in-frame-maybe)
(add-hook 'after-delete-frame-functions #'doom|reload-theme-maybe)
;; Set up `doom-enter-buffer-hook', `doom-exit-buffer-hook',
;; `doom-enter-window-hook' and `doom-exit-window-hook'
(doom-init-switch-hooks))
;; Initialize custom switch-{buffer,window,frame} hooks:
;; + `doom-switch-buffer-hook'
;; + `doom-switch-window-hook'
;; + `doom-switch-frame-hook'
(add-hook 'buffer-list-update-hook #'doom|run-switch-window-hooks)
(add-hook 'focus-in-hook #'doom|run-switch-frame-hooks)
(advice-add! '(switch-to-buffer display-buffer) :around #'doom*run-switch-buffer-hooks))
;; Set fonts
(add-hook 'doom-init-ui-hook #'doom|init-fonts)