core-popups: refactor window parameters & popup init
This commit is contained in:
parent
8271342b2e
commit
92fb1e3417
2 changed files with 93 additions and 84 deletions
|
@ -5,9 +5,7 @@
|
||||||
(defun doom-popup-p (&optional window)
|
(defun doom-popup-p (&optional window)
|
||||||
"Return t if WINDOW is a popup. Uses current window if WINDOW is omitted."
|
"Return t if WINDOW is a popup. Uses current window if WINDOW is omitted."
|
||||||
(let ((window (or window (selected-window))))
|
(let ((window (or window (selected-window))))
|
||||||
(and window
|
(and window (window-parameter window 'popup))))
|
||||||
(or (window-parameter window 'popup)
|
|
||||||
(buffer-local-value 'doom-popup-mode (window-buffer window))))))
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom-popup-buffer (buffer &rest plist)
|
(defun doom-popup-buffer (buffer &rest plist)
|
||||||
|
@ -35,7 +33,9 @@ possible rules."
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/popup-restore ()
|
(defun doom/popup-restore ()
|
||||||
"Restore the last popups."
|
"Restore the last popups. If the buffers have been killed, and represented
|
||||||
|
real files, they will be restored. Special buffers or buffers with non-nil
|
||||||
|
:autokill properties will not be."
|
||||||
(interactive)
|
(interactive)
|
||||||
(unless doom-popup-history
|
(unless doom-popup-history
|
||||||
(error "No popups to restore"))
|
(error "No popups to restore"))
|
||||||
|
@ -72,14 +72,11 @@ possible rules."
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun doom/popup-close-all ()
|
(defun doom/popup-close-all ()
|
||||||
"Closes all open popups. If DONT-KILL is non-nil, don't kill their buffers."
|
"Closes all open popups."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let* ((orig-win (selected-window))
|
(let ((orig-win (selected-window)))
|
||||||
(popups (cl-remove-if-not (lambda (win) (and (doom-popup-p win)
|
(when-let (popups (doom-popup-windows))
|
||||||
(not (eq win orig-win))))
|
(setq doom-popup-history (mapcar 'doom--popup-data popups))
|
||||||
(window-list))))
|
|
||||||
(when popups
|
|
||||||
(setq doom-popup-history (mapcar 'doom--popup-data (doom-popup-windows)))
|
|
||||||
(let (doom-popup-remember-history)
|
(let (doom-popup-remember-history)
|
||||||
(mapc 'delete-window popups)))))
|
(mapc 'delete-window popups)))))
|
||||||
|
|
||||||
|
@ -88,7 +85,7 @@ possible rules."
|
||||||
"Close the current popup *if* its window doesn't have a noesc parameter."
|
"Close the current popup *if* its window doesn't have a noesc parameter."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((window (selected-window)))
|
(let ((window (selected-window)))
|
||||||
(if (window-parameter window 'noesc)
|
(if (window-parameter window :noesc)
|
||||||
(call-interactively (if (featurep 'evil)
|
(call-interactively (if (featurep 'evil)
|
||||||
'evil-force-normal-state
|
'evil-force-normal-state
|
||||||
'keyboard-escape-quit))
|
'keyboard-escape-quit))
|
||||||
|
|
|
@ -34,6 +34,10 @@
|
||||||
map)
|
map)
|
||||||
"Active keymap in popup windows.")
|
"Active keymap in popup windows.")
|
||||||
|
|
||||||
|
(defvar doom-popup-window-parameters '(:noesc :modeline :autokill)
|
||||||
|
"A list of window parameters that are set (and cleared) when `doom-popup-mode
|
||||||
|
is enabled/disabled.'")
|
||||||
|
|
||||||
(@def-setting :popup (&rest rules)
|
(@def-setting :popup (&rest rules)
|
||||||
"Prepend a new popup rule to `shackle-rules'."
|
"Prepend a new popup rule to `shackle-rules'."
|
||||||
(if (cl-every 'listp rules)
|
(if (cl-every 'listp rules)
|
||||||
|
@ -61,7 +65,7 @@
|
||||||
("*Pp Eval Output*" :size 0.3 :autokill t)
|
("*Pp Eval Output*" :size 0.3 :autokill t)
|
||||||
("*Apropos*" :size 0.3)
|
("*Apropos*" :size 0.3)
|
||||||
("*Backtrace*" :size 25 :noselect t)
|
("*Backtrace*" :size 25 :noselect t)
|
||||||
("*Help*" :size 16 :autokill t)
|
("*Help*" :size 16)
|
||||||
("*Messages*" :size 10)
|
("*Messages*" :size 10)
|
||||||
("*Warnings*" :size 10 :noselect t :autokill t)
|
("*Warnings*" :size 10 :noselect t :autokill t)
|
||||||
("*command-log*" :size 28 :noselect t :align right)
|
("*command-log*" :size 28 :noselect t :align right)
|
||||||
|
@ -73,87 +77,98 @@
|
||||||
(tabulated-list-mode :noesc t)))
|
(tabulated-list-mode :noesc t)))
|
||||||
|
|
||||||
:config
|
:config
|
||||||
(shackle-mode 1))
|
(shackle-mode 1)
|
||||||
|
|
||||||
|
(defun doom*shackle-always-align (plist)
|
||||||
;;
|
"Ensure popups are always aligned and selected by default. Eliminates the need
|
||||||
;; Modifications
|
|
||||||
;;
|
|
||||||
|
|
||||||
(defun doom*shackle-always-align (plist)
|
|
||||||
"Ensure popups are always aligned and selected by default. Eliminates the need
|
|
||||||
for :align t on every rule."
|
for :align t on every rule."
|
||||||
(when plist
|
(when plist
|
||||||
(unless (plist-member plist :align)
|
(unless (plist-member plist :align)
|
||||||
(plist-put plist :align t))
|
(plist-put plist :align t))
|
||||||
(unless (or (plist-member plist :select)
|
(unless (or (plist-member plist :select)
|
||||||
(plist-member plist :noselect))
|
(plist-member plist :noselect))
|
||||||
(plist-put plist :select t)))
|
(plist-put plist :select t)))
|
||||||
plist)
|
plist)
|
||||||
(advice-add 'shackle--match :filter-return 'doom*shackle-always-align)
|
(advice-add 'shackle--match :filter-return 'doom*shackle-always-align))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Integration
|
||||||
|
;;
|
||||||
|
|
||||||
;; Tell `window-state-get' and `current-window-configuration' to persist these
|
;; Tell `window-state-get' and `current-window-configuration' to persist these
|
||||||
;; custom parameters. Allows `persp-mode' to remember popup states.
|
;; custom parameters. Helpful for `persp-mode' to persist popup windows.
|
||||||
(nconc window-persistent-parameters
|
(push (cons 'no-other-window 'writable) window-persistent-parameters)
|
||||||
'((popup . writable)
|
(dolist (param doom-popup-window-parameters)
|
||||||
(noesc . writable)
|
(push (cons param 'writable) window-persistent-parameters))
|
||||||
(autokill . writable)))
|
|
||||||
|
|
||||||
|
|
||||||
(define-minor-mode doom-popup-mode
|
(define-minor-mode doom-popup-mode
|
||||||
"Minor mode for popup windows."
|
"Minor mode for popup windows."
|
||||||
:init-value nil
|
:init-value nil
|
||||||
:keymap doom-popup-mode-map
|
:keymap doom-popup-mode-map
|
||||||
;; Don't show modeline in popup windows without a :modeline rule. If one
|
(let ((window (selected-window)))
|
||||||
;; exists and it's a symbol, use `doom-modeline' to grab the format. If
|
;; Major mode changes (and other things) may call
|
||||||
;; non-nil, show the mode-line as normal. If nil (or omitted), then hide the
|
;; `kill-all-local-variables', turning off things like `doom-popup-mode'.
|
||||||
;; modeline entirely.
|
;; This prevents that.
|
||||||
(if (and (not doom-popup-mode)
|
(put 'doom-popup-mode 'permanent-local doom-popup-mode)
|
||||||
doom-hide-modeline-mode)
|
;; Ensure that buffer-opening functions/commands (like
|
||||||
(doom-hide-modeline-mode -1)
|
;; `switch-to-buffer-other-window' won't use this window).
|
||||||
(let ((modeline (plist-get doom-popup-rules :modeline)))
|
(set-window-parameter window 'no-other-window doom-popup-mode)
|
||||||
(cond ((or (eq modeline 'nil)
|
;; Makes popup window resist interactively changing its buffer.
|
||||||
(not modeline))
|
(set-window-dedicated-p window doom-popup-mode)
|
||||||
(doom-hide-modeline-mode +1))
|
(cond (doom-popup-mode
|
||||||
((symbolp modeline)
|
;; Don't show modeline in popup windows without a :modeline rule. If
|
||||||
(let ((doom--hidden-modeline-format (doom-modeline modeline)))
|
;; one exists and it's a symbol, use `doom-modeline' to grab the
|
||||||
(doom-hide-modeline-mode +1)))))))
|
;; format. If non-nil, show the mode-line as normal. If nil (or
|
||||||
(put 'doom-popup-mode 'permanent-local t)
|
;; omitted, by default), then hide the modeline entirely.
|
||||||
|
(let ((modeline (plist-get doom-popup-rules :modeline)))
|
||||||
|
(cond ((or (eq modeline 'nil)
|
||||||
|
(not modeline))
|
||||||
|
(doom-hide-modeline-mode +1))
|
||||||
|
((symbolp modeline)
|
||||||
|
(let ((doom--hidden-modeline-format (doom-modeline modeline)))
|
||||||
|
(doom-hide-modeline-mode +1)))))
|
||||||
|
;; Save metadata into window parameters so it can be saved by window
|
||||||
|
;; config persisting plugins like workgroups or persp-mode.
|
||||||
|
(set-window-parameter window 'popup (or doom-popup-rules t))
|
||||||
|
(when doom-popup-rules
|
||||||
|
(dolist (param doom-popup-window-parameters)
|
||||||
|
(when-let (val (plist-get doom-popup-rules param))
|
||||||
|
(set-window-parameter window param val)))))
|
||||||
|
|
||||||
|
(t
|
||||||
|
;; show modeline
|
||||||
|
(when doom-hide-modeline-mode
|
||||||
|
(doom-hide-modeline-mode -1))
|
||||||
|
;; Ensure window parameters are cleaned up
|
||||||
|
(set-window-parameter window 'popup nil)
|
||||||
|
(dolist (param doom-popup-window-parameters)
|
||||||
|
(set-window-parameter window param nil))))))
|
||||||
|
|
||||||
;; Hide modeline in completion popups
|
;; Hide modeline in completion popups
|
||||||
(@add-hook (completion-in-region-mode completion-list-mode) 'doom-hide-modeline-mode)
|
(@add-hook (completion-in-region-mode completion-list-mode) 'doom-hide-modeline-mode)
|
||||||
|
|
||||||
(defun doom-popup--init (window &optional plist)
|
|
||||||
"Initializes a window as a popup window. Sets custom window parameters and
|
|
||||||
enables `doom-popup-mode'."
|
|
||||||
(unless window
|
|
||||||
(error "No window was found for %s: %s" (car args) plist))
|
|
||||||
(unless plist
|
|
||||||
(setq plist (shackle-match (window-buffer window))))
|
|
||||||
(mapc (lambda (cfg) (set-window-parameter window (car cfg) (cdr cfg)))
|
|
||||||
(append `((popup . ,plist)
|
|
||||||
(no-other-window . ,t))
|
|
||||||
(when (plist-get plist :noesc)
|
|
||||||
`((noesc . ,t)))
|
|
||||||
(when (plist-get plist :autokill)
|
|
||||||
`((autokill . ,t)))))
|
|
||||||
(with-selected-window window
|
|
||||||
(unless (eq plist t)
|
|
||||||
(setq-local doom-popup-rules plist))
|
|
||||||
(doom-popup-mode +1))
|
|
||||||
window)
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
(defun doom*popup-init (orig-fn &rest args)
|
(defun doom*popup-init (orig-fn &rest args)
|
||||||
"Invokes `doom-popup--init' on windows that qualify as popups. Returns the window."
|
"Initializes a window as a popup window by enabling `doom-popup-mode' in it.
|
||||||
|
Returns the window."
|
||||||
(unless (doom-popup-p)
|
(unless (doom-popup-p)
|
||||||
(setq doom-popup-other-window (selected-window)))
|
(setq doom-popup-other-window (selected-window)))
|
||||||
(doom-popup--init (apply orig-fn args) (nth 2 args)))
|
(let ((plist (or (nth 2 args)
|
||||||
|
(and (bufferp (car args))
|
||||||
|
(shackle-match (window-buffer (car args))))))
|
||||||
|
(window (apply orig-fn args)))
|
||||||
|
(unless window
|
||||||
|
(error "No popup window was found for %s: %s" (car args) plist))
|
||||||
|
(with-selected-window window
|
||||||
|
(unless (eq plist t)
|
||||||
|
(setq-local doom-popup-rules plist))
|
||||||
|
(doom-popup-mode +1))
|
||||||
|
window))
|
||||||
|
|
||||||
(defun doom*popups-save (orig-fn &rest args)
|
(defun doom*popups-save (orig-fn &rest args)
|
||||||
"Puts aside all popups before executing the original function, usually to
|
"Sets aside all popups before executing the original function, usually to
|
||||||
prevent popups from messaging up the UI (or vice versa)."
|
prevent the popup(s) from messing up the UI (or vice versa)."
|
||||||
(let ((in-popup-p (doom-popup-p))
|
(let ((in-popup-p (doom-popup-p))
|
||||||
(popups (doom-popup-windows))
|
(popups (doom-popup-windows))
|
||||||
(doom-popup-remember-history t))
|
(doom-popup-remember-history t))
|
||||||
|
@ -166,25 +181,22 @@ prevent popups from messaging up the UI (or vice versa)."
|
||||||
(unless in-popup-p
|
(unless in-popup-p
|
||||||
(select-window origin)))))))
|
(select-window origin)))))))
|
||||||
|
|
||||||
(defun doom*delete-popup-window (orig-fn &rest args)
|
(defun doom*delete-popup-window (&optional window)
|
||||||
"Ensure that popups are deleted properly, and killed if they have :autokill
|
"Ensure that popups are deleted properly, and killed if they have :autokill
|
||||||
properties."
|
properties."
|
||||||
(let ((window (or (car args) (selected-window))))
|
(let ((window (or window (selected-window))))
|
||||||
(when (doom-popup-p window)
|
(when (doom-popup-p window)
|
||||||
(when doom-popup-remember-history
|
(when doom-popup-remember-history
|
||||||
(setq doom-popup-history (list (doom--popup-data window))))
|
(setq doom-popup-history (list (doom--popup-data window))))
|
||||||
(set-window-dedicated-p window nil)
|
(let ((autokill-p (window-parameter window :autokill)))
|
||||||
(if (window-parameter window 'autokill)
|
|
||||||
(kill-buffer (window-buffer window))
|
|
||||||
(with-selected-window window
|
(with-selected-window window
|
||||||
(doom-popup-mode -1)))
|
(doom-popup-mode -1)
|
||||||
(mapc (lambda (cfg) (set-window-parameter window cfg nil))
|
(when autokill-p
|
||||||
'(popup no-other-window noesc autokill))))
|
(kill-buffer (current-buffer))))))))
|
||||||
(apply orig-fn args))
|
|
||||||
|
|
||||||
(advice-add 'shackle-display-buffer :around 'doom*popup-init)
|
(advice-add 'shackle-display-buffer :around 'doom*popup-init)
|
||||||
(advice-add 'balance-windows :around 'doom*popups-save)
|
(advice-add 'balance-windows :around 'doom*popups-save)
|
||||||
(advice-add 'delete-window :around 'doom*delete-popup-window)
|
(advice-add 'delete-window :before 'doom*delete-popup-window)
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue