diff --git a/core/autoload/buffers.el b/core/autoload/buffers.el index b708ef679..1c474cd94 100644 --- a/core/autoload/buffers.el +++ b/core/autoload/buffers.el @@ -65,11 +65,16 @@ the current workspace." (cl-remove-if-not #'doom-real-buffer-p (or buffer-list (doom-buffer-list)))) ;;;###autoload -(defun doom-buffers-in-mode (modes &optional buffer-list) +(defun doom-buffers-in-mode (modes &optional buffer-list derived-p) "Get a list of all buffers (in the current workspace OR in BUFFER-LIST) whose `major-mode' is one of MODES." (let ((modes (if (listp modes) modes (list modes)))) - (cl-remove-if-not (lambda (buf) (memq (buffer-local-value 'major-mode buf) modes)) + (cl-remove-if-not (if derived-p + (lambda (buf) + (with-current-buffer buf + (apply #'derived-mode-p modes))) + (lambda (buf) + (memq (buffer-local-value 'major-mode buf) modes))) (or buffer-list (doom-buffer-list))))) ;;;###autoload diff --git a/core/autoload/popups.el b/core/autoload/popups.el index 43d38da17..410706e82 100644 --- a/core/autoload/popups.el +++ b/core/autoload/popups.el @@ -23,6 +23,18 @@ current window if omitted." buffer nil (or plist (shackle-match buffer)))) +;;;###autoload +(defun doom-popup-switch-to-buffer (buffer) + (unless (doom-popup-p) + (let ((popups (doom-popup-windows))) + (unless popups + (error "No popups to switch")) + (select-window (car popups)))) + (set-window-dedicated-p nil nil) + (switch-to-buffer buffer nil t) + (prog1 (selected-window) + (set-window-dedicated-p nil t))) + ;;;###autoload (defun doom-popup-file (file &rest plist) "Display FILE in a shackle popup, with PLIST rules. See `shackle-rules' for diff --git a/core/core-popups.el b/core/core-popups.el index 7b0198765..bbedb5186 100644 --- a/core/core-popups.el +++ b/core/core-popups.el @@ -391,6 +391,39 @@ the command buffer." (doom--switch-from-popup (find-function-search-for-symbol fun 'defface file))))) +(after! magit + (set! :popup "^\\*magit" :regexp t :size 0.5 :noesc t :autokill t) + + ;; magit doesn't need much coercing. It works with shackle as is, except for + ;; one problem: following non-file magit links tends to open additional + ;; popups. We want all this to be contained within one window, so... + (defun doom-magit-popup-buffer (buffer) + "Pop up the magit window with shackle." + (cond ((doom-popup-p) + (prog1 (doom-popup-switch-to-buffer buffer) + (doom-hide-modeline-mode +1))) + (t + (magit-display-buffer-traditional buffer)))) + + (defun doom-magit-quit-window (kill-buffer) + "Close the current magit window properly." + (let ((last (current-buffer))) + (cond ((when-let (dest (doom-buffers-in-mode + 'magit-mode + (cl-remove-if (lambda (buf) (eq buf last)) + (mapcar #'car (window-prev-buffers))) + t)) + (doom-popup-switch-to-buffer (car dest))) + (kill-buffer last)) + (t + (mapc #'kill-buffer + (doom-buffers-in-mode '(magit-mode magit-process-mode) + (buffer-list) t)))))) + + (setq magit-display-buffer-function #'doom-magit-popup-buffer + magit-bury-buffer-function #'doom-magit-quit-window)) + + (after! mu4e (defun doom*mu4e-popup-window (buf height) (doom-popup-buffer buf :size 10 :noselect t) diff --git a/modules/feature/version-control/+git.el b/modules/feature/version-control/+git.el index acabd17f0..3a4682b82 100644 --- a/modules/feature/version-control/+git.el +++ b/modules/feature/version-control/+git.el @@ -74,13 +74,7 @@ (def-package! magit - :commands (magit-status magit-blame) - :config - (set! :popup "^\\*magit" :regexp t) - (map! :map magit-mode-map - ;; Don't interfere with window movement keys - :nv "C-j" nil - :nv "C-k" nil)) + :commands (magit-status magit-blame)) (def-package! git-link @@ -89,5 +83,10 @@ (def-package! evil-magit :when (featurep! :feature evil) - :after magit) + :after magit + :init (setq evil-magit-want-horizontal-movement t) + :config + (map! :map (magit-status-mode-map magit-revision-mode-map) + :n "C-j" nil + :n "C-k" nil))