From 25a2973c52177c85240b2d9c2b8b8e32b56a4b86 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 7 Jan 2018 02:33:57 -0500 Subject: [PATCH] feature/popup: make parameters support functions Now, the transient, quit, select and modeline parameters now accept a function FN. See `+popup-window-parameters` for details. (transient . (FN popup-buffer)) (quit . (FN popup-window)) (select . (FN popup-window)) (modeline . (FN popup-buffer)) --- modules/feature/popup/autoload.el | 58 +++++++++++++++++++------------ modules/feature/popup/config.el | 28 ++++++++++----- 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/modules/feature/popup/autoload.el b/modules/feature/popup/autoload.el index bd79154de..60ffba420 100644 --- a/modules/feature/popup/autoload.el +++ b/modules/feature/popup/autoload.el @@ -53,8 +53,8 @@ and enables `+popup-buffer-mode'." + Either kills the buffer or sets a transient timer, if the window has a `transient' window parameter (see `+popup-window-parameters'). + And finally deletes the window!" - (let ((ttl (+popup-parameter 'transient window)) - (buffer (window-buffer window))) + (let ((buffer (window-buffer window)) + ttl) (let ((ignore-window-parameters t)) (delete-window window)) (unless (window-live-p window) @@ -63,14 +63,17 @@ and enables `+popup-buffer-mode'." ;; t = default ;; integer = ttl ;; nil = no timer - (when (and ttl (not +popup--inhibit-transient)) - (when (eq ttl t) - (setq ttl +popup-ttl)) - (cl-assert (integerp ttl) t) - (if (= ttl 0) - (+popup--kill-buffer buffer 0) - (setq +popup--timer - (run-at-time ttl nil #'+popup--kill-buffer buffer ttl)))))))) + (unless +popup--inhibit-transient + (setq ttl (+popup-parameter-fn 'transient window buffer)) + (when ttl + (when (eq ttl t) + (setq ttl +popup-ttl)) + (cl-assert (integerp ttl) t) + (if (= ttl 0) + (+popup--kill-buffer buffer 0) + (setq +popup--timer + (run-at-time ttl nil #'+popup--kill-buffer + buffer ttl))))))))) (defun +popup--normalize-alist (alist) "Merge `+popup-default-alist' and `+popup-default-parameters' with ALIST." @@ -110,10 +113,10 @@ current buffer." (new-window (or (display-buffer-reuse-window buffer alist) (display-buffer-in-side-window buffer alist)))) (+popup--init new-window) - (select-window - (if (+popup-parameter 'select new-window) - new-window - old-window)) + (let ((select (+popup-parameter 'select new-window))) + (if (functionp select) + (funcall select new-window old-window) + (select-window (if select new-window old-window)))) new-window)) ;;;###autoload @@ -121,6 +124,15 @@ current buffer." "Fetch the window parameter of WINDOW" (window-parameter (or window (selected-window)) parameter)) +;;;###autoload +(defun +popup-parameter-fn (parameter &optional window &rest args) + "Fetch the window PARAMETER (symbol) of WINDOW. If it is a function, run it +with ARGS to get its return value." + (let ((val (+popup-parameter parameter window))) + (if (functionp val) + (apply val args) + val))) + ;;;###autoload (defun +popup-windows () "Returns a list of all popup windows." @@ -178,15 +190,17 @@ disabled." + If one exists and it's a symbol, use `doom-modeline' to grab the format. + If non-nil, show the mode-line as normal. -+ If nil (or omitted), then hide the modeline entirely (the default)." ++ If nil (or omitted), then hide the modeline entirely (the default). ++ If a function, it takes the current buffer as its argument and must return one + of the above values." (if +popup-buffer-mode - (let ((modeline (+popup-parameter 'modeline))) - (cond ((or (eq modeline 'nil) + (let ((modeline (+popup-parameter-fn 'modeline nil (current-buffer)))) + (cond ((eq modeline 't)) + ((or (eq modeline 'nil) (not modeline)) (doom-hide-modeline-mode +1)) - ((and (symbolp modeline) - (not (eq modeline 't))) - (setq-local doom--modeline-format (doom-modeline modeline)) + ((symbolp modeline) + (setq doom--modeline-format (doom-modeline modeline)) (when doom--modeline-format (doom-hide-modeline-mode +1))))) (when doom-hide-modeline-mode @@ -237,7 +251,7 @@ This will do nothing if the popup's `quit' window parameter is either nil or (setq window (selected-window))) (when (and (+popup-p window) (or force-p - (memq (+popup-parameter 'quit window) + (memq (+popup-parameter-fn 'quit window window) '(t current)))) (when +popup--remember-last (+popup--remember (list window))) @@ -254,7 +268,7 @@ This window parameter is ignored if FORCE-P is non-nil." (let (targets +popup--remember-last) (dolist (window (+popup-windows)) (when (or force-p - (memq (+popup-parameter 'quit window) + (memq (+popup-parameter-fn 'quit window window) '(t other))) (push window targets))) (when targets diff --git a/modules/feature/popup/config.el b/modules/feature/popup/config.el index 4c6247107..797f244c9 100644 --- a/modules/feature/popup/config.el +++ b/modules/feature/popup/config.el @@ -6,16 +6,20 @@ Modifying this has no effect, unless done before feature/popup loads. (transient . CDR) - CDR can be t, an integer or nil. It represents the number of seconds before - the buffer belonging to a closed popup window is killed. + CDR can be t, an integer, nil or a function that returns one of these. It + represents the number of seconds before the buffer belonging to a closed popup + window is killed. If t, CDR will default to `+popup-ttl'. If 0, the buffer is immediately killed. If nil, the buffer won't be killed. + If a function, it must return one of the other possible values above. It takes + the popup buffer as its sole argument. (quit . CDR) - CDR can be t, 'other, 'current or nil. This determines the behavior of the - ESC/C-g keys in or outside of popup windows. + CDR can be t, 'other, 'current, nil, or a function that returns one of these. + This determines the behavior of the ESC/C-g keys in or outside of popup + windows. If t, close the popup if ESC/C-g is pressed inside or outside of popups. If 'other, close this popup if ESC/C-g is pressed outside of any popup. This @@ -24,14 +28,22 @@ Modifying this has no effect, unless done before feature/popup loads. If 'current, close the current popup if ESC/C-g is pressed from inside of the popup. If nil, pressing ESC/C-g will never close this buffer. + If a function, it is checked each time ESC/C-g is pressed to determine the + fate of the popup window. This function takes one argument: the popup + window and must return one of the other possible values. -(select . BOOl) - CDR is a boolean that determines whether to focus the popup window after it - opens. +(select . CDR) + CDR can be a boolean or function. The boolean determines whether to focus the + popup window after it opens (non-nil) or focus the origin window (nil). + + If a function, it takes two arguments: the popup window and the source window + (where you were before the popup was opened). It does nothing else, and + ignores its return value. (modeline . CDR) CDR can be t (show the default modeline), a symbol representing the name of a - modeline defined with `def-modeline!', or nil (show no modeline). + modeline defined with `def-modeline!', nil (show no modeline) or a function + that returns one of these. The function takes one argument: the popup buffer. (popup . t) This is for internal use, do not change this. It simply marks a window as a