ui/workspaces: conform to new hook/advice conventions

This commit is contained in:
Henrik Lissner 2019-07-22 00:52:05 +02:00
parent 951a414ca4
commit 5e0177d667
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
2 changed files with 87 additions and 97 deletions

View file

@ -441,7 +441,7 @@ the next."
;;; Hooks ;;; Hooks
;;;###autoload ;;;###autoload
(defun +workspaces|delete-associated-workspace (&optional frame) (defun +workspaces-delete-associated-workspace-h (&optional frame)
"Delete workspace associated with current frame. "Delete workspace associated with current frame.
A workspace gets associated with a frame when a new frame is interactively A workspace gets associated with a frame when a new frame is interactively
created." created."
@ -453,17 +453,7 @@ created."
(+workspace/delete frame-persp))))) (+workspace/delete frame-persp)))))
;;;###autoload ;;;###autoload
(defun +workspaces|cleanup-unassociated-buffers () (defun +workspaces-associate-frame-fn (frame &optional _new-frame-p)
"Kill leftover buffers that are unassociated with any perspective."
(when persp-mode
(cl-loop for buf in (buffer-list)
unless (or (persp--buffer-in-persps buf)
(get-buffer-window buf))
if (kill-buffer buf)
sum 1)))
;;;###autoload
(defun +workspaces|associate-frame (frame &optional _new-frame-p)
"Create a blank, new perspective and associate it with FRAME." "Create a blank, new perspective and associate it with FRAME."
(when persp-mode (when persp-mode
(if (not (persp-frame-list-without-daemon)) (if (not (persp-frame-list-without-daemon))
@ -479,13 +469,13 @@ created."
(defvar +workspaces--project-dir nil) (defvar +workspaces--project-dir nil)
;;;###autoload ;;;###autoload
(defun +workspaces|set-project-action () (defun +workspaces-set-project-action-fn ()
"A `projectile-switch-project-action' that sets the project directory for "A `projectile-switch-project-action' that sets the project directory for
`+workspaces|switch-to-project'." `+workspaces-switch-to-project-h'."
(setq +workspaces--project-dir default-directory)) (setq +workspaces--project-dir default-directory))
;;;###autoload ;;;###autoload
(defun +workspaces|switch-to-project (&optional dir) (defun +workspaces-switch-to-project-h (&optional dir)
"Creates a workspace dedicated to a new project. If one already exists, switch "Creates a workspace dedicated to a new project. If one already exists, switch
to it. If in the main workspace and it's empty, recycle that workspace, without to it. If in the main workspace and it's empty, recycle that workspace, without
renaming it. renaming it.
@ -527,7 +517,7 @@ This be hooked to `projectile-after-switch-project-hook'."
;;; Advice ;;; Advice
;;;###autoload ;;;###autoload
(defun +workspaces*autosave-real-buffers (orig-fn &rest args) (defun +workspaces-autosave-real-buffers-a (orig-fn &rest args)
"Don't autosave if no real buffers are open." "Don't autosave if no real buffers are open."
(when (doom-real-buffer-list) (when (doom-real-buffer-list)
(apply orig-fn args)) (apply orig-fn args))

View file

@ -37,17 +37,17 @@ stored in `persp-save-dir'.")
;; Packages ;; Packages
(def-package! persp-mode (def-package! persp-mode
:commands (persp-switch-to-buffer) :commands persp-switch-to-buffer
:init :init
(defun +workspaces|init () (add-hook 'doom-init-modules-hook
;; Remove default buffer predicate so persp-mode can put in its own (defun +workspaces-init-h ()
(delq! 'buffer-predicate default-frame-alist 'assq) (unless noninteractive
(require 'persp-mode) ;; Remove default buffer predicate so persp-mode can put in its own
(if (daemonp) (delq! 'buffer-predicate default-frame-alist 'assq)
(add-hook 'after-make-frame-functions #'persp-mode-start-and-remove-from-make-frame-hook) (require 'persp-mode)
(persp-mode +1))) (if (daemonp)
(unless noninteractive (add-hook 'after-make-frame-functions #'persp-mode-start-and-remove-from-make-frame-hook)
(add-hook 'doom-init-modules-hook #'+workspaces|init)) (persp-mode +1)))))
:config :config
(setq persp-autokill-buffer-on-remove 'kill-weak (setq persp-autokill-buffer-on-remove 'kill-weak
persp-nil-hidden t persp-nil-hidden t
@ -59,50 +59,49 @@ stored in `persp-save-dir'.")
persp-auto-resume-time -1 ; Don't auto-load on startup persp-auto-resume-time -1 ; Don't auto-load on startup
persp-auto-save-opt (if noninteractive 0 1)) ; auto-save on kill persp-auto-save-opt (if noninteractive 0 1)) ; auto-save on kill
(advice-add #'persp-asave-on-exit :around #'+workspaces*autosave-real-buffers) (advice-add #'persp-asave-on-exit :around #'+workspaces-autosave-real-buffers-a)
(defun +workspaces|ensure-main-workspace (&rest _) (add-hook! '(persp-mode-hook persp-after-load-state-functions)
"Ensure the main workspace exists and the nil workspace is never active." (defun +workspaces-ensure-main-workspace-h (&rest _)
(when persp-mode "Ensure the main workspace exists and the nil workspace is never active."
(let (persp-before-switch-functions) (when persp-mode
;; The default perspective persp-mode creates (`persp-nil-name') is (let (persp-before-switch-functions)
;; special and doesn't represent a real persp object, so buffers can't ;; The default perspective persp-mode creates (`persp-nil-name') is
;; really be assigned to it, among other quirks. We create a *real* main ;; special and doesn't represent a real persp object, so buffers can't
;; workspace to fill this role. ;; really be assigned to it, among other quirks. We create a *real* main
(unless (persp-get-by-name +workspaces-main) ;; workspace to fill this role.
(persp-add-new +workspaces-main)) (unless (persp-get-by-name +workspaces-main)
;; Switch to it if we're in the nil perspective (persp-add-new +workspaces-main))
(dolist (frame (frame-list)) ;; Switch to it if we're in the nil perspective
(when (string= (safe-persp-name (get-current-persp frame)) persp-nil-name) (dolist (frame (frame-list))
(persp-frame-switch +workspaces-main frame) (when (string= (safe-persp-name (get-current-persp frame)) persp-nil-name)
;; Fix #319: the warnings buffer gets swallowed by creating (persp-frame-switch +workspaces-main frame)
;; `+workspaces-main', so we display it manually, if it exists. ;; Fix #319: the warnings buffer gets swallowed by creating
(when-let (warnings (get-buffer "*Warnings*")) ;; `+workspaces-main', so we display it manually, if it exists.
(save-excursion (when-let (warnings (get-buffer "*Warnings*"))
(display-buffer-in-side-window (save-excursion
warnings '((window-height . shrink-window-if-larger-than-buffer)))))))))) (display-buffer-in-side-window
(add-hook 'persp-mode-hook #'+workspaces|ensure-main-workspace) warnings '((window-height . shrink-window-if-larger-than-buffer)))))))))))
(add-hook 'persp-after-load-state-functions #'+workspaces|ensure-main-workspace)
(defun +workspaces|init-persp-mode () (add-hook 'persp-mode-hook
(cond (persp-mode (defun +workspaces-init-persp-mode-h ()
;; `uniquify' breaks persp-mode. It renames old buffers, which causes (cond (persp-mode
;; errors when switching between perspective (their buffers are ;; `uniquify' breaks persp-mode. It renames old buffers, which causes
;; serialized by name and persp-mode expects them to have the same ;; errors when switching between perspective (their buffers are
;; name when restored). ;; serialized by name and persp-mode expects them to have the same
(when uniquify-buffer-name-style ;; name when restored).
(setq +workspace--old-uniquify-style uniquify-buffer-name-style)) (when uniquify-buffer-name-style
(setq uniquify-buffer-name-style nil) (setq +workspace--old-uniquify-style uniquify-buffer-name-style))
;; Ensure `persp-kill-buffer-query-function' is last (setq uniquify-buffer-name-style nil)
(remove-hook 'kill-buffer-query-functions #'persp-kill-buffer-query-function) ;; Ensure `persp-kill-buffer-query-function' is last
(add-hook 'kill-buffer-query-functions #'persp-kill-buffer-query-function t) (remove-hook 'kill-buffer-query-functions #'persp-kill-buffer-query-function)
;; Restrict buffer list to workspace (add-hook 'kill-buffer-query-functions #'persp-kill-buffer-query-function t)
(advice-add #'doom-buffer-list :override #'+workspace-buffer-list)) ;; Restrict buffer list to workspace
(t (advice-add #'doom-buffer-list :override #'+workspace-buffer-list))
(when +workspace--old-uniquify-style (t
(setq uniquify-buffer-name-style +workspace--old-uniquify-style)) (when +workspace--old-uniquify-style
(advice-remove #'doom-buffer-list #'+workspace-buffer-list)))) (setq uniquify-buffer-name-style +workspace--old-uniquify-style))
(add-hook 'persp-mode-hook #'+workspaces|init-persp-mode) (advice-remove #'doom-buffer-list #'+workspace-buffer-list)))))
;; We don't rely on the built-in mechanism for auto-registering a buffer to ;; We don't rely on the built-in mechanism for auto-registering a buffer to
;; the current workspace; some buffers slip through the cracks. Instead, we ;; the current workspace; some buffers slip through the cracks. Instead, we
@ -110,26 +109,27 @@ stored in `persp-save-dir'.")
(setq persp-add-buffer-on-find-file nil (setq persp-add-buffer-on-find-file nil
persp-add-buffer-on-after-change-major-mode nil) persp-add-buffer-on-after-change-major-mode nil)
(defun +workspaces|add-current-buffer () (add-hook 'doom-switch-buffer-hook
"Add current buffer to focused perspective." (defun +workspaces-add-current-buffer-h ()
(when persp-mode "Add current buffer to focused perspective."
(persp-add-buffer (current-buffer) (get-current-persp)))) (when persp-mode
(add-hook 'doom-switch-buffer-hook #'+workspaces|add-current-buffer) (persp-add-buffer (current-buffer) (get-current-persp)))))
(add-to-list 'persp-add-buffer-on-after-change-major-mode-filter-functions (add-to-list 'persp-add-buffer-on-after-change-major-mode-filter-functions
#'doom-unreal-buffer-p) #'doom-unreal-buffer-p)
(defun +workspaces*evil-alternate-buffer (&optional window) (def-advice! +workspaces-evil-alternate-buffer-a (&optional window)
"Make `evil-alternate-buffer' ignore buffers outside the current workspace." "Make `evil-alternate-buffer' ignore buffers outside the current workspace."
(let* ((prev-buffers (if persp-mode :override #'evil-alternate-buffer
(cl-remove-if-not #'persp-contain-buffer-p (window-prev-buffers) (let* ((prev-buffers
:key #'car) (if persp-mode
(window-prev-buffers))) (cl-remove-if-not #'persp-contain-buffer-p (window-prev-buffers)
:key #'car)
(window-prev-buffers)))
(head (car prev-buffers))) (head (car prev-buffers)))
(if (eq (car head) (window-buffer window)) (if (eq (car head) (window-buffer window))
(cadr prev-buffers) (cadr prev-buffers)
head))) head)))
(advice-add #'evil-alternate-buffer :override #'+workspaces*evil-alternate-buffer)
;; Delete the current workspace if closing the last open window ;; Delete the current workspace if closing the last open window
(define-key! persp-mode-map (define-key! persp-mode-map
@ -139,14 +139,14 @@ stored in `persp-save-dir'.")
;; per-frame workspaces ;; per-frame workspaces
(setq persp-init-frame-behaviour t (setq persp-init-frame-behaviour t
persp-init-new-frame-behaviour-override nil persp-init-new-frame-behaviour-override nil
persp-interactive-init-frame-behaviour-override #'+workspaces|associate-frame persp-interactive-init-frame-behaviour-override #'+workspaces-associate-frame-fn
persp-emacsclient-init-frame-behaviour-override #'+workspaces|associate-frame) persp-emacsclient-init-frame-behaviour-override #'+workspaces-associate-frame-fn)
(add-hook 'delete-frame-functions #'+workspaces|delete-associated-workspace) (add-hook 'delete-frame-functions #'+workspaces-delete-associated-workspace-h)
;; per-project workspaces, but reuse current workspace if empty ;; per-project workspaces, but reuse current workspace if empty
(setq projectile-switch-project-action #'+workspaces|set-project-action (setq projectile-switch-project-action #'+workspaces-set-project-action-fn
counsel-projectile-switch-project-action counsel-projectile-switch-project-action
'(1 ("o" +workspaces|switch-to-project "open project in new workspace") '(1 ("o" +workspaces-switch-to-project-h "open project in new workspace")
("O" counsel-projectile-switch-project-action "jump to a project buffer or file") ("O" counsel-projectile-switch-project-action "jump to a project buffer or file")
("f" counsel-projectile-switch-project-action-find-file "jump to a project file") ("f" counsel-projectile-switch-project-action-find-file "jump to a project file")
("d" counsel-projectile-switch-project-action-find-dir "jump to a project directory") ("d" counsel-projectile-switch-project-action-find-dir "jump to a project directory")
@ -166,7 +166,7 @@ stored in `persp-save-dir'.")
("xt" counsel-projectile-switch-project-action-run-term "invoke term from project root") ("xt" counsel-projectile-switch-project-action-run-term "invoke term from project root")
("X" counsel-projectile-switch-project-action-org-capture "org-capture into project"))) ("X" counsel-projectile-switch-project-action-org-capture "org-capture into project")))
(add-hook 'projectile-after-switch-project-hook #'+workspaces|switch-to-project) (add-hook 'projectile-after-switch-project-hook #'+workspaces-switch-to-project-h)
;; In some scenarios, persp-mode throws error when Emacs tries to die, ;; In some scenarios, persp-mode throws error when Emacs tries to die,
;; preventing its death and trapping us in Emacs. ;; preventing its death and trapping us in Emacs.
@ -176,9 +176,9 @@ stored in `persp-save-dir'.")
;; Fix #1017: stop session persistence from restoring a broken posframe ;; Fix #1017: stop session persistence from restoring a broken posframe
(after! posframe (after! posframe
(defun +workspaces|delete-all-posframes (&rest _) (add-hook 'persp-after-load-state-functions
(posframe-delete-all)) (defun +workspaces-delete-all-posframes-h (&rest _)
(add-hook 'persp-after-load-state-functions #'+workspaces|delete-all-posframes)) (posframe-delete-all))))
;; ;;
;; eshell ;; eshell
@ -204,12 +204,12 @@ stored in `persp-save-dir'.")
(push (cons buf-name base-buf-name) (push (cons buf-name base-buf-name)
+workspaces--indirect-buffers-to-restore) +workspaces--indirect-buffers-to-restore)
nil))) nil)))
(defun +workspaces|reload-indirect-buffers (&rest _) (add-hook 'persp-after-load-state-functions
(dolist (ibc +workspaces--indirect-buffers-to-restore) (defun +workspaces-reload-indirect-buffers-h (&rest _)
(cl-destructuring-bind (buffer-name . base-buffer-name) ibc (dolist (ibc +workspaces--indirect-buffers-to-restore)
(when (buffer-live-p (get-buffer base-buffer-name)) (cl-destructuring-bind (buffer-name . base-buffer-name) ibc
(when (get-buffer buffer-name) (when (buffer-live-p (get-buffer base-buffer-name))
(setq buffer-name (generate-new-buffer-name buffer-name))) (when (get-buffer buffer-name)
(make-indirect-buffer bb buffer-name t)))) (setq buffer-name (generate-new-buffer-name buffer-name)))
(setq +workspaces--indirect-buffers-to-restore nil)) (make-indirect-buffer bb buffer-name t))))
(add-hook 'persp-after-load-state-functions #'+workspaces|reload-indirect-buffers)) (setq +workspaces--indirect-buffers-to-restore nil))))