Files
sydnix/users/crumb/programs/emacs/modules/doom-popup/doom-popup-config.el
Madeleine Sydney c05b7f456d fix: Repls finally respect popup rules TwT
- Required patching on.el to run their hooks at the correct time.
2025-01-30 08:14:55 -07:00

213 lines
8.3 KiB
EmacsLisp

;;; doom-popup-config.el -*- lexical-binding: t; -*-
;; The MIT License (MIT)
;;
;; Copyright (c) 2014-2024 Henrik Lissner.
;;
;; Permission is hereby granted, free of charge, to any person obtaining
;; a copy of this software and associated documentation files (the
;; "Software"), to deal in the Software without restriction, including
;; without limitation the rights to use, copy, modify, merge, publish,
;; distribute, sublicense, and/or sell copies of the Software, and to
;; permit persons to whom the Software is furnished to do so, subject to
;; the following conditions:
;;
;; The above copyright notice and this permission notice shall be
;; included in all copies or substantial portions of the Software.
;;
;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
;; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
;; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
(defconst doom-popup-window-parameters '(ttl quit select modeline popup)
"A list of custom parameters to be added to `window-persistent-parameters'.
Modifying this has no effect, unless done before ui/popup loads.")
(defvar doom-popup-default-display-buffer-actions
'(doom-popup-display-buffer-stacked-side-window-fn)
"The functions to use to display the popup buffer.")
(defvar doom-popup-default-alist
'((window-height . 0.16) ; remove later
(reusable-frames . visible))
"The default alist for `display-buffer-alist' rules.")
(defvar doom-popup-default-parameters
'((transient . t) ; remove later
(quit . t) ; remove later
(select . ignore) ; remove later
(no-other-window . t))
"The default window parameters.")
(defvar doom-popup-margin-width 1
"Size of the margins to give popup windows. Set this to nil to disable margin
adjustment.")
(defvar doom-popup--inhibit-transient nil)
(defvar doom-popup--inhibit-select nil)
(defvar doom-popup--old-display-buffer-alist nil)
(defvar doom-popup--remember-last t)
(defvar doom-popup--last nil)
(defvar-local doom-popup--timer nil)
;;
;; Global modes
(defvar doom-popup-mode-map (make-sparse-keymap)
"Active keymap in a session with the popup system enabled. See
`doom-popup-mode'.")
(defvar doom-popup-buffer-mode-map
(let ((map (make-sparse-keymap)))
(when (featurep 'evil)
;; For maximum escape coverage in emacs state buffers; this only works in
;; GUI Emacs, in tty Emacs use C-g instead
(define-key map [escape] #'syd/escape))
map)
"Active keymap in popup windows. See `doom-popup-buffer-mode'.")
(define-minor-mode doom-popup-mode
"Global minor mode representing Doom's popup management system."
:init-value nil
:global t
:keymap doom-popup-mode-map
(progn
(message "doom-popup-mode: %S" doom-popup-mode)
(cond (doom-popup-mode
(add-hook 'doom-escape-hook #'doom-popup-close-on-escape-h 'append)
(setq doom-popup--old-display-buffer-alist display-buffer-alist
display-buffer-alist doom-popup--display-buffer-alist
window--sides-inhibit-check t)
(dolist (prop doom-popup-window-parameters)
(push (cons prop 'writable) window-persistent-parameters)))
(t
(remove-hook 'doom-escape-hook #'doom-popup-close-on-escape-h)
(setq display-buffer-alist doom-popup--old-display-buffer-alist
window--sides-inhibit-check nil)
(doom-popup-cleanup-rules-h)
(dolist (prop doom-popup-window-parameters)
(delq (assq prop window-persistent-parameters)
window-persistent-parameters))))))
(define-minor-mode doom-popup-buffer-mode
"Minor mode for individual popup windows.
It is enabled when a buffer is displayed in a popup window and disabled when
that window has been changed or closed."
:init-value nil
:keymap doom-popup-buffer-mode-map
(if (not doom-popup-buffer-mode)
(remove-hook 'after-change-major-mode-hook #'doom-popup-set-modeline-on-enable-h t)
(add-hook 'after-change-major-mode-hook #'doom-popup-set-modeline-on-enable-h
nil 'local)
(when (timerp doom-popup--timer)
(remove-hook 'kill-buffer-hook #'doom-popup-kill-buffer-hook-h t)
(cancel-timer doom-popup--timer)
(setq doom-popup--timer nil))))
(put 'doom-popup-buffer-mode 'permanent-local t)
(put 'doom-popup-buffer-mode 'permanent-local-hook t)
(put 'doom-popup-set-modeline-on-enable-h 'permanent-local-hook t)
;;
;; Macros
(defmacro with-popup-rules! (rules &rest body)
"Evaluate BODY with popup RULES. RULES is a list of popup rules. Each rule
should match the arguments of `doom-popup-define' or the :popup setting."
(declare (indent defun))
`(let ((doom-popup--display-buffer-alist doom-popup--old-display-buffer-alist)
display-buffer-alist)
(set-popup-rules! ,rules)
(when (bound-and-true-p doom-popup-mode)
(setq display-buffer-alist doom-popup--display-buffer-alist))
,@body))
(defmacro save-popups! (&rest body)
"Sets aside all popups before executing the original function, usually to
prevent the popup(s) from messing up the UI (or vice versa)."
`(let* ((in-popup-p (doom-popup-buffer-p))
(popups (doom-popup-windows))
(doom-popup--inhibit-transient t)
buffer-list-update-hook
doom-popup--last)
(dolist (p popups)
(doom-popup/close p 'force))
(unwind-protect
(progn ,@body)
(when popups
(let ((origin (selected-window)))
(doom-popup/restore)
(unless in-popup-p
(select-window origin)))))))
;;
;; Default popup rules & bootstrap
(defvar doom-popup-use-aggressive-defaults nil)
(defvar doom-popup-use-defaults t)
(set-popup-rules!
(when doom-popup-use-aggressive-defaults
'(("^\\*" :slot 1 :vslot -1 :select t)
("^ \\*" :slot 1 :vslot -1 :size doom-popup-shrink-to-fit)))
(when doom-popup-use-defaults
'(("^\\*Completions" :ignore t)
("^\\*Local variables\\*$"
:vslot -1 :slot 1 :size doom-popup-shrink-to-fit)
("^\\*\\(?:[Cc]ompil\\(?:ation\\|e-Log\\)\\|Messages\\)"
:vslot -2 :size 0.3 :autosave t :quit t :ttl nil)
("^\\*\\(?:doom \\|Pp E\\)" ; transient buffers (no interaction required)
:vslot -3 :size doom-popup-shrink-to-fit :autosave t :select ignore :quit t :ttl 0)
("^\\*doom:" ; editing buffers (interaction required)
:vslot -4 :size 0.35 :autosave t :select t :modeline t :quit nil :ttl t)
("^\\*doom:\\(?:v?term\\|e?shell\\)-popup" ; editing buffers (interaction required)
:vslot -5 :size 0.35 :select t :modeline nil :quit nil :ttl nil)
("^\\*\\(?:Wo\\)?Man "
:vslot -6 :size 0.45 :select t :quit t :ttl 0)
("^\\*Calc"
:vslot -7 :side bottom :size 0.4 :select t :quit nil :ttl 0)
("^\\*Customize"
:slot 2 :side right :size 0.5 :select t :quit nil)
("^ \\*undo-tree\\*"
:slot 2 :side left :size 20 :select t :quit t)
;; `help-mode', `helpful-mode'
("^\\*\\([Hh]elp\\|Apropos\\)"
:slot 2 :vslot -8 :size 0.42 :select t)
("^\\*eww\\*" ; `eww' (and used by dash docsets)
:vslot -11 :size 0.35 :select t)
("^\\*xwidget"
:vslot -11 :size 0.35 :select nil)
("^\\*info\\*$" ; `Info-mode'
:slot 2 :vslot 2 :size 0.45 :select t)))
'(("^\\*Warnings" :vslot 99 :size 0.25)
("^\\*Backtrace" :vslot 99 :size 0.4 :quit nil)
("^\\*CPU-Profiler-Report " :side bottom :vslot 100 :slot 1 :height 0.4 :width 0.5 :quit nil)
("^\\*Memory-Profiler-Report " :side bottom :vslot 100 :slot 2 :height 0.4 :width 0.5 :quit nil)
("^\\*Process List\\*" :side bottom :vslot 101 :size 0.25 :select t :quit t)
("^\\*\\(?:Proced\\|timer-list\\|Abbrevs\\|Output\\|Occur\\|unsent mail.*?\\|message\\)\\*" :ignore t)))
(add-hook 'on-init-ui-hook #'doom-popup-mode 'append)
(dolist (hook-fn (list #'doom-popup-adjust-fringes-h
#'doom-popup-adjust-margins-h
#'doom-popup-set-modeline-on-enable-h
#'doom-popup-unset-modeline-on-disable-h))
(add-hook 'doom-popup-buffer-mode-hook hook-fn))
;;
;;; Hacks
(require 'doom-popup-hacks)
(provide 'doom-popup-config)