From 9823881d47dcf8084e258f8bf4907f1cab865a15 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 25 Jun 2019 11:21:39 +0200 Subject: [PATCH] ui/workspaces: general refactor - Fixes #1506: unsets uniquify-buffer-name-style to work around breakage in persp-mode having to do with buffers being retrospectively renamed. See Bad-ptr/persp-mode.el#104. - Move creation of main workspace into persp-mode-hook, to ensure main workspace always exists and nil workspace is never active. - Remove +workspaces|init-frame and significantly reduce LOC in +workspaces|init to the bare essentials. This _may_ break persp-mode in daemon Emacs, but I'll deal with that next. --- modules/ui/workspaces/config.el | 107 +++++++++++++++----------------- 1 file changed, 50 insertions(+), 57 deletions(-) diff --git a/modules/ui/workspaces/config.el b/modules/ui/workspaces/config.el index 75cb4fa4a..b2ec31505 100644 --- a/modules/ui/workspaces/config.el +++ b/modules/ui/workspaces/config.el @@ -30,6 +30,8 @@ nil Never create a new workspace on project switch.") "The basename of the file to store single workspace perspectives. Will be stored in `persp-save-dir'.") +(defvar +workspace--old-uniquify-style nil) + ;; ;; Packages @@ -39,43 +41,14 @@ stored in `persp-save-dir'.") :init (defun +workspaces|init () ;; Remove default buffer predicate so persp-mode can put in its own - (setq default-frame-alist - (delq (assq 'buffer-predicate default-frame-alist) - default-frame-alist)) - (add-hook 'after-make-frame-functions #'+workspaces|init-frame) - (require 'persp-mode) - (unless (daemonp) - (+workspaces|init-frame (selected-frame)))) - - (defun +workspaces|init-frame (frame) - "Ensure a main workspace exists and is switched to, if FRAME isn't in any -workspace. Also ensures that the *Warnings* buffer will be visible in main. - -Uses `+workspaces-main' to determine the name of the main workspace." - (unless persp-mode - (persp-mode +1) - (unless noninteractive - (let (persp-before-switch-functions) - (with-selected-frame frame - ;; The default perspective persp-mode creates (`persp-nil-name') is - ;; special and doesn't represent a real persp object, so buffers can't - ;; really be assigned to it, among other quirks. We create a *real* - ;; main workspace to fill this role. - (unless (persp-get-by-name +workspaces-main) - (persp-add-new +workspaces-main)) - ;; Switch to it if we aren't auto-loading the last session - (when (and (string= (safe-persp-name (get-current-persp)) persp-nil-name) - (= persp-auto-resume-time -1)) - (persp-frame-switch +workspaces-main frame) - ;; We want to know where we are in every new daemon frame - (when (daemonp) - (run-at-time 0.1 nil #'+workspace/display)) - ;; Fix #319: the warnings buffer gets swallowed by creating - ;; `+workspaces-main', so we display it manually, if it exists. - (when-let* ((warnings (get-buffer "*Warnings*"))) - (save-excursion - (display-buffer-in-side-window - warnings '((window-height . shrink-window-if-larger-than-buffer))))))))))) + (delq! 'buffer-predicate default-frame-alist 'assq) + (persp-mode +1) + ;; Fix #319: the warnings buffer gets swallowed by creating + ;; `+workspaces-main', so we display it manually, if it exists. + (when-let (warnings (get-buffer "*Warnings*")) + (save-excursion + (display-buffer-in-side-window + warnings '((window-height . shrink-window-if-larger-than-buffer)))))) (add-hook 'doom-init-modules-hook #'+workspaces|init t) :config @@ -91,34 +64,54 @@ Uses `+workspaces-main' to determine the name of the main workspace." (advice-add #'persp-asave-on-exit :around #'+workspaces*autosave-real-buffers) - ;; Don't rely on the built-in mechanism for auto-registering a buffer to the - ;; current workspace. Instead, we add buffers when they are switched to. - (setq persp-add-buffer-on-find-file nil - persp-add-buffer-on-after-change-major-mode nil) - (add-hook 'persp-add-buffer-on-after-change-major-mode-filter-functions #'doom-unreal-buffer-p) - - (defun +workspaces|add-current-buffer () - (persp-add-buffer (current-buffer) (get-current-persp))) - (add-hook 'doom-switch-buffer-hook #'+workspaces|add-current-buffer) - (defun +workspaces|init-persp-mode () (cond (persp-mode - ;; `persp-kill-buffer-query-function' must be last + ;; `uniquify' breaks persp-mode. It renames old buffers, which causes + ;; errors when switching between perspective (their buffers are + ;; serialized by name and persp-mode expects them to have the same + ;; name when restored). + (when uniquify-buffer-name-style + (setq +workspace--old-uniquify-style uniquify-buffer-name-style)) + (setq uniquify-buffer-name-style nil) + ;; ensure `persp-kill-buffer-query-function' is last (remove-hook 'kill-buffer-query-functions 'persp-kill-buffer-query-function) (add-hook 'kill-buffer-query-functions 'persp-kill-buffer-query-function t) ;; Restrict buffer list to workspace (advice-add #'doom-buffer-list :override #'+workspace-buffer-list)) - ((advice-remove #'doom-buffer-list #'+workspace-buffer-list)))) + (t + (setq uniquify-buffer-name-style +workspace--old-uniquify-style) + (advice-remove #'doom-buffer-list #'+workspace-buffer-list)))) (add-hook 'persp-mode-hook #'+workspaces|init-persp-mode) - (defun +workspaces|leave-nil-perspective (&rest _) - "Ensure that Doom is never in the nil perspective." - (when (string= (+workspace-current-name) persp-nil-name) - (+workspace-switch (or (if (+workspace-p +workspace--last) +workspace--last) - (car (+workspace-list-names)) - +workspaces-main) - 'auto-create))) - (add-hook 'persp-after-load-state-functions #'+workspaces|leave-nil-perspective) + (defun +workspaces|ensure-main-workspace (&rest _) + "Ensure the main workspace exists and the nil workspace is never active." + (let (persp-before-switch-functions) + ;; The default perspective persp-mode creates (`persp-nil-name') is + ;; special and doesn't represent a real persp object, so buffers can't + ;; really be assigned to it, among other quirks. We create a *real* main + ;; workspace to fill this role. + (unless (persp-get-by-name +workspaces-main) + (persp-add-new +workspaces-main)) + ;; Switch to it if we aren't auto-loading the last session + (when (and (string= (safe-persp-name (get-current-persp)) persp-nil-name) + (or after-init-time (= persp-auto-resume-time -1))) + (persp-frame-switch +workspaces-main)))) + (add-hook 'persp-mode-hook #'+workspaces|ensure-main-workspace) + (add-hook 'persp-after-load-state-functions #'+workspaces|ensure-main-workspace) + + ;; 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 + ;; add buffers when they are switched to. + (setq persp-add-buffer-on-find-file nil + persp-add-buffer-on-after-change-major-mode nil) + + (defun +workspaces|add-current-buffer () + "Add current buffer to focused perspective." + (persp-add-buffer (current-buffer) (get-current-persp))) + (add-hook 'doom-switch-buffer-hook #'+workspaces|add-current-buffer) + + (add-to-list 'persp-add-buffer-on-after-change-major-mode-filter-functions + #'doom-unreal-buffer-p) (defun +workspaces*evil-alternate-buffer (&optional window) "Make `evil-alternate-buffer' ignore buffers outside the current workspace."