2018-06-15 02:58:12 +02:00
|
|
|
;;; ui/popup/autoload/settings.el -*- lexical-binding: t; -*-
|
|
|
|
|
2018-09-19 21:38:50 +01:00
|
|
|
;;;###autoload
|
2018-06-15 02:58:12 +02:00
|
|
|
(defvar +popup--display-buffer-alist nil)
|
|
|
|
|
2018-06-18 02:26:05 +02:00
|
|
|
;;;###autoload
|
|
|
|
(defvar +popup-defaults
|
|
|
|
(list :side 'bottom
|
|
|
|
:height 0.16
|
|
|
|
:width 40
|
|
|
|
:quit t
|
|
|
|
:select #'ignore
|
|
|
|
:ttl 5)
|
2018-06-23 22:18:44 +02:00
|
|
|
"Default properties for popup rules defined with `set-popup-rule!'.")
|
2018-06-18 02:26:05 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
2019-11-21 14:45:18 -05:00
|
|
|
(defun +popup-make-rule (predicate plist)
|
2019-10-21 06:12:57 -04:00
|
|
|
(if (plist-get plist :ignore)
|
|
|
|
(list predicate nil)
|
|
|
|
(let* ((plist (append plist +popup-defaults))
|
|
|
|
(alist
|
|
|
|
`((actions . ,(plist-get plist :actions))
|
|
|
|
(side . ,(plist-get plist :side))
|
|
|
|
(size . ,(plist-get plist :size))
|
|
|
|
(window-width . ,(plist-get plist :width))
|
|
|
|
(window-height . ,(plist-get plist :height))
|
|
|
|
(slot . ,(plist-get plist :slot))
|
|
|
|
(vslot . ,(plist-get plist :vslot))))
|
|
|
|
(params
|
|
|
|
`((ttl . ,(plist-get plist :ttl))
|
|
|
|
(quit . ,(plist-get plist :quit))
|
|
|
|
(select . ,(plist-get plist :select))
|
|
|
|
(modeline . ,(plist-get plist :modeline))
|
|
|
|
(autosave . ,(plist-get plist :autosave))
|
|
|
|
,@(plist-get plist :parameters))))
|
|
|
|
`(,predicate (+popup-buffer)
|
|
|
|
,@alist
|
|
|
|
(window-parameters ,@params)))))
|
2018-06-15 02:58:12 +02:00
|
|
|
|
|
|
|
;;;###autodef
|
2018-06-18 02:26:05 +02:00
|
|
|
(defun set-popup-rule! (predicate &rest plist)
|
2018-06-15 02:58:12 +02:00
|
|
|
"Define a popup rule.
|
|
|
|
|
2018-06-23 22:18:44 +02:00
|
|
|
These rules affect buffers displayed with `pop-to-buffer' and `display-buffer'
|
|
|
|
(or their siblings). Buffers displayed with `switch-to-buffer' (and its
|
|
|
|
variants) will not be affected by these rules (as they are unaffected by
|
|
|
|
`display-buffer-alist', which powers the popup management system).
|
2018-06-15 02:58:12 +02:00
|
|
|
|
2024-07-18 22:28:25 -04:00
|
|
|
PREDICATE accepts anything that the CONDITION argument in `buffer-match-p' takes
|
|
|
|
(if you're on Emacs 29 or newer). On Emacs 28 or older, it can either be a) a
|
|
|
|
regexp string (matched against the buffer's name) or b) a function that takes
|
|
|
|
two arguments (a buffer name and the ACTION argument of `display-buffer') and
|
|
|
|
returns a boolean.
|
2018-06-18 02:26:05 +02:00
|
|
|
|
|
|
|
PLIST can be made up of any of the following properties:
|
|
|
|
|
2018-07-07 11:44:47 +02:00
|
|
|
:ignore BOOL
|
|
|
|
If BOOL is non-nil, popups matching PREDICATE will not be handled by the popup
|
|
|
|
system. Use this for buffers that have their own window management system like
|
|
|
|
magit or helm.
|
|
|
|
|
2018-06-18 02:26:05 +02:00
|
|
|
:actions ACTIONS
|
|
|
|
ACTIONS is a list of functions or an alist containing (FUNCTION . ALIST). See
|
|
|
|
`display-buffer''s second argument for more information on its format and what
|
|
|
|
it accepts. If omitted, `+popup-default-display-buffer-actions' is used.
|
|
|
|
|
|
|
|
:side 'bottom|'top|'left|'right
|
|
|
|
Which side of the frame to open the popup on. This is only respected if
|
2019-07-22 04:46:14 +02:00
|
|
|
`+popup-display-buffer-stacked-side-window-fn' or `display-buffer-in-side-window'
|
2018-06-18 02:26:05 +02:00
|
|
|
is in :actions or `+popup-default-display-buffer-actions'.
|
|
|
|
|
2018-06-23 22:18:44 +02:00
|
|
|
:size/:width/:height FLOAT|INT|FN
|
2020-02-29 12:14:17 -08:00
|
|
|
Determines the size of the popup. If more than one of these size properties are
|
2018-06-23 22:18:44 +02:00
|
|
|
given :size always takes precedence, and is mapped with window-width or
|
|
|
|
window-height depending on what :side the popup is opened. Setting a height
|
|
|
|
for a popup that opens on the left or right is harmless, but comes into play
|
|
|
|
if two popups occupy the same :vslot.
|
2018-06-18 02:26:05 +02:00
|
|
|
|
2018-06-23 22:18:44 +02:00
|
|
|
If a FLOAT (0 < x < 1), the number represents how much of the window will be
|
|
|
|
consumed by the popup (a percentage).
|
|
|
|
If an INT, the number determines the size in lines (height) or units of
|
2018-06-18 02:26:05 +02:00
|
|
|
character width (width).
|
2018-06-23 22:18:44 +02:00
|
|
|
If a function, it takes one argument: the popup window, and can do whatever it
|
|
|
|
wants with it, typically resize it, like `+popup-shrink-to-fit'.
|
2018-06-18 02:26:05 +02:00
|
|
|
|
|
|
|
:slot/:vslot INT
|
2018-06-23 22:18:44 +02:00
|
|
|
(This only applies to popups with a :side and only if :actions is blank or
|
2019-07-22 04:46:14 +02:00
|
|
|
contains the `+popup-display-buffer-stacked-side-window-fn' action) These control
|
2018-06-23 22:18:44 +02:00
|
|
|
how multiple popups are laid out. INT can be any integer, positive and
|
|
|
|
negative.
|
|
|
|
|
|
|
|
:slot controls lateral positioning (e.g. the horizontal positioning for
|
|
|
|
top/bottom popups, or vertical positioning for left/right popups).
|
|
|
|
:vslot controls popup stacking (from the edge of the frame toward the center).
|
|
|
|
|
|
|
|
Let's assume popup A and B are opened with :side 'bottom, in that order.
|
|
|
|
If they possess the same :slot and :vslot, popup B will replace popup A.
|
|
|
|
If popup B has a higher :slot, it will open to the right of popup A.
|
|
|
|
If popup B has a lower :slot, it will open to the left of popup A.
|
|
|
|
If popup B has a higher :vslot, it will open above popup A.
|
|
|
|
If popup B has a lower :vslot, it will open below popup A.
|
2018-06-18 02:26:05 +02:00
|
|
|
|
|
|
|
:ttl INT|BOOL|FN
|
2018-06-23 22:18:44 +02:00
|
|
|
Stands for time-to-live. It can be t, an integer, nil or a function. This
|
|
|
|
controls how (and if) the popup system will clean up after the popup.
|
2018-06-18 02:26:05 +02:00
|
|
|
|
2018-06-23 22:18:44 +02:00
|
|
|
If any non-zero integer, wait that many seconds before killing the buffer (and
|
|
|
|
any associated processes).
|
2018-06-18 02:26:05 +02:00
|
|
|
If 0, the buffer is immediately killed.
|
2018-06-23 22:18:44 +02:00
|
|
|
If nil, the buffer won't be killed and is left to its own devices.
|
|
|
|
If t, resort to the default :ttl in `+popup-defaults'. If none exists, this is
|
|
|
|
the same as nil.
|
|
|
|
If a function, it takes one argument: the target popup buffer. The popup
|
|
|
|
system does nothing else and ignores the function's return value.
|
2018-06-18 02:26:05 +02:00
|
|
|
|
2018-06-23 22:18:44 +02:00
|
|
|
:quit FN|BOOL|'other|'current
|
|
|
|
Can be t, 'other, 'current, nil, or a function. This determines the behavior
|
|
|
|
of the ESC/C-g keys in or outside of popup windows.
|
2018-06-18 02:26:05 +02:00
|
|
|
|
2018-06-23 22:18:44 +02:00
|
|
|
If t, close the popup if ESC/C-g is pressed anywhere.
|
2018-06-18 02:26:05 +02:00
|
|
|
If 'other, close this popup if ESC/C-g is pressed outside of any popup. This
|
2018-06-23 22:18:44 +02:00
|
|
|
is great for popups you may press ESC/C-g a lot in.
|
2018-06-18 02:26:05 +02:00
|
|
|
If 'current, close the current popup if ESC/C-g is pressed from inside of the
|
2018-06-23 22:18:44 +02:00
|
|
|
popup. This makes it harder to accidentally close a popup until you really
|
|
|
|
want to.
|
|
|
|
If nil, pressing ESC/C-g will never close this popup.
|
|
|
|
If a function, it takes one argument: the to-be-closed popup window, and is
|
|
|
|
run when ESC/C-g is pressed while that popup is open. It must return one of
|
|
|
|
the other values to determine the fate of the popup.
|
2018-06-18 02:26:05 +02:00
|
|
|
|
|
|
|
:select BOOL|FN
|
2018-06-23 22:18:44 +02:00
|
|
|
Can be a boolean or function. The boolean determines whether to focus the
|
2018-06-18 02:26:05 +02:00
|
|
|
popup window after it opens (non-nil) or focus the origin window (nil).
|
|
|
|
|
2018-06-23 22:18:44 +02:00
|
|
|
If a function, it takes two arguments: the popup window and originating window
|
|
|
|
(where you were before the popup opened). The popup system does nothing else
|
|
|
|
and ignores the function's return value.
|
2018-06-18 02:26:05 +02:00
|
|
|
|
2018-07-29 18:36:12 +02:00
|
|
|
:modeline BOOL|FN|LIST
|
|
|
|
Can be t (show the default modeline), nil (show no modeline), a function that
|
|
|
|
returns a modeline format or a valid value for `mode-line-format' to be used
|
|
|
|
verbatim. The function takes no arguments and is run in the context of the
|
|
|
|
popup buffer.
|
2018-06-18 02:26:05 +02:00
|
|
|
|
|
|
|
:autosave BOOL|FN
|
2018-06-23 22:18:44 +02:00
|
|
|
This parameter determines what to do with modified buffers when closing popup
|
|
|
|
windows. It accepts t, 'ignore, a function or nil.
|
2018-06-18 02:26:05 +02:00
|
|
|
|
|
|
|
If t, no prompts. Just save them automatically (if they're file-visiting
|
2018-06-23 22:18:44 +02:00
|
|
|
buffers). Same as 'ignore for non-file-visiting buffers.
|
2018-06-18 02:26:05 +02:00
|
|
|
If nil (the default), prompt the user what to do if the buffer is
|
|
|
|
file-visiting and modified.
|
2018-06-23 22:18:44 +02:00
|
|
|
If 'ignore, no prompts, no saving. Just silently kill it.
|
|
|
|
If a function, it is run with one argument: the popup buffer, and must return
|
|
|
|
non-nil to save or nil to do nothing (but no prompts).
|
2018-06-18 02:26:05 +02:00
|
|
|
|
|
|
|
:parameters ALIST
|
2018-06-23 22:18:44 +02:00
|
|
|
An alist of custom window parameters. See `(elisp)Window Parameters'.
|
2018-06-18 02:26:05 +02:00
|
|
|
|
|
|
|
If any of these are omitted, defaults derived from `+popup-defaults' will be
|
2019-03-16 23:57:38 -04:00
|
|
|
used.
|
|
|
|
|
|
|
|
\(fn PREDICATE &key IGNORE ACTIONS SIDE SIZE WIDTH HEIGHT SLOT VSLOT TTL QUIT SELECT MODELINE AUTOSAVE PARAMETERS)"
|
2018-06-16 00:39:20 +02:00
|
|
|
(declare (indent defun))
|
2019-11-21 14:45:18 -05:00
|
|
|
(push (+popup-make-rule predicate plist) +popup--display-buffer-alist)
|
2024-08-15 23:18:47 -04:00
|
|
|
;; TODO: Don't overwrite user entries in `display-buffer-alist'
|
2018-06-15 02:58:12 +02:00
|
|
|
(when (bound-and-true-p +popup-mode)
|
|
|
|
(setq display-buffer-alist +popup--display-buffer-alist))
|
|
|
|
+popup--display-buffer-alist)
|
|
|
|
|
|
|
|
;;;###autodef
|
|
|
|
(defun set-popup-rules! (&rest rulesets)
|
2018-06-23 22:18:44 +02:00
|
|
|
"Defines multiple popup rules.
|
|
|
|
|
|
|
|
Every entry in RULESETS should be a list of alists where the CAR is the
|
|
|
|
predicate and CDR is a plist. See `set-popup-rule!' for details on the predicate
|
|
|
|
and plist.
|
2018-06-18 02:26:05 +02:00
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
(set-popup-rules!
|
|
|
|
'((\"^ \\*\" :slot 1 :vslot -1 :size #'+popup-shrink-to-fit)
|
|
|
|
(\"^\\*\" :slot 1 :vslot -1 :select t))
|
|
|
|
'((\"^\\*Completions\" :slot -1 :vslot -2 :ttl 0)
|
|
|
|
(\"^\\*Compil\\(?:ation\\|e-Log\\)\" :size 0.3 :ttl 0 :quit t)))"
|
|
|
|
(declare (indent 0))
|
|
|
|
(dolist (rules rulesets)
|
|
|
|
(dolist (rule rules)
|
2019-11-21 14:45:18 -05:00
|
|
|
(push (+popup-make-rule (car rule) (cdr rule))
|
2018-06-18 02:26:05 +02:00
|
|
|
+popup--display-buffer-alist)))
|
2018-06-15 02:58:12 +02:00
|
|
|
(when (bound-and-true-p +popup-mode)
|
|
|
|
(setq display-buffer-alist +popup--display-buffer-alist))
|
|
|
|
+popup--display-buffer-alist)
|