branch: externals/embark commit 53ff463a7907fc2eef33322f0178abb6ecf34a27 Author: Omar AntolÃn Camarena <omar.anto...@gmail.com> Commit: Omar AntolÃn Camarena <omar.anto...@gmail.com>
Allow fine-grained control of minibuffer quitting behavior This fixes #453 and implements a proposal from #343. --- README.org | 45 +++++++++++++++++++++++++++++---------------- embark.el | 34 ++++++++++++++++++++++++++-------- embark.texi | 45 +++++++++++++++++++++++++++++---------------- 3 files changed, 84 insertions(+), 40 deletions(-) diff --git a/README.org b/README.org index c4341625e2..8b075bd6a4 100644 --- a/README.org +++ b/README.org @@ -381,24 +381,37 @@ embark to always prompt you for actions by setting the variable By default, if you call =embark-act= from the minibuffer it quits the minibuffer after performing the action. You can change this by setting -the user option =embark-quit-after-action= to =nil=. That variable -controls whether or not =embark-act= quits the minibuffer when you call -it without a prefix argument, and you can select the opposite behavior -to what the variable says by calling =embark-act= with =C-u=. Note that -both the variable =embark-quit-after-action= and =C-u= have no effect when -you call =embark-act= outside the minibuffer. - -Having =embark-act= /not/ quit the minibuffer can be useful to turn -commands into little "thing managers". For example, you can use -=find-file= as a little file manager or =describe-package= as a little -package manager: you can run those commands, perform a series of -actions, and then quit the command. +the user option =embark-quit-after-action= to =nil=. Having =embark-act= /not/ +quit the minibuffer can be useful to turn commands into little "thing +managers". For example, you can use =find-file= as a little file manager +or =describe-package= as a little package manager: you can run those +commands, perform a series of actions, and then quit the command. + +If you want to control the quitting behavior in a fine-grained manner +depending on the action, you can set =embark-quit-after-action= to an +alist, associating commands to either =t= for quitting or =nil= for not +quitting. When using an alist, you can use the special key =t= to +specify the default behavior. For example, to specify that by default +actions should not quit the minibuffer but that using =kill-buffer= as +an action should quit, you can use the following configuration: + +#+begin_src emacs-lisp + (setq embark-quit-after-action '((kill-buffer . t) (t . nil))) +#+end_src + +The variable =embark-quit-after-action= only specifies a default, that +is, it only controls whether or not =embark-act= quits the minibuffer +when you call it without a prefix argument, and you can select the +opposite behavior to what the variable says by calling =embark-act= with +=C-u=. Also note that both the variable =embark-quit-after-action= and =C-u= +have no effect when you call =embark-act= outside the minibuffer. If you find yourself using the quitting and non-quitting variants of -=embark-act= about equally often, you may prefer to have separate -commands for them instead of a single command that you call with =C-u= -half the time. You could, for example, keep the default exiting -behavior of =embark-act= and define a non-quitting version as follows: +=embark-act= about equally often, independently of the action, you may +prefer to simply have separate commands for them instead of a single +command that you call with =C-u= half the time. You could, for example, +keep the default exiting behavior of =embark-act= and define a +non-quitting version as follows: #+begin_src emacs-lisp (defun embark-act-noquit () diff --git a/embark.el b/embark.el index d566f78447..9803eb41ef 100644 --- a/embark.el +++ b/embark.el @@ -349,8 +349,15 @@ opposite behavior to that indicated by this variable by calling `embark-act' with \\[universal-argument]. Note that `embark-act' can also be called from outside the -minibuffer and this variable is irrelevant in that case." - :type 'boolean) +minibuffer and this variable is irrelevant in that case. + +In addition to `t' or `nil' this variable can also be set to an +alist to specify the minibuffer quitting behavior per command. +In the alist case one can additionally use the key `t' to +prescribe a default for commands not used as alist keys." + :type '(choice boolean + (alist :key-type (choice function (const t)) + :value-type boolean))) (defcustom embark-default-action-overrides nil "Alist associating target types with overriding default actions. @@ -365,7 +372,7 @@ make `find-file' the default action for all files, even if they wre obtained from a `delete-file' prompt. In that case you can configure that by adding an entry to this variable pairing `file' with `find-file'." - :type '(alist :key-type symbol :value-type command)) + :type '(alist :key-type symbol :value-type function)) (define-obsolete-variable-alias 'embark-allow-edit-commands @@ -1966,6 +1973,16 @@ keymap for the given type." :target (plist-get target :orig-target)) :type (plist-get target :orig-type))) +(defun embark--quit-p (action &optional negate) + "Determine whether to quit the minibuffer after ACTION. +This function consults `embark-quit-after-action' to decide +whether or not the user wishes to quit the minibuffer after +performing the ACTION, assuming this is done from a minibuffer. +If NEGATE is non-nil, return the opposite value." + (let* ((cfg embark-quit-after-action) + (quit (if (consp cfg) (alist-get action cfg (alist-get t cfg)) cfg))) + (if negate (not quit) quit))) + ;;;###autoload (defun embark-act (&optional arg) "Prompt the user for an action and perform it. @@ -2033,7 +2050,7 @@ target." (eq action embark--command)) (embark--orig-target target) target) - (if embark-quit-after-action (not arg) arg)) + (embark--quit-p action arg)) (user-error (funcall (if repeat #'message #'user-error) "%s" (cadr err)))) @@ -2129,7 +2146,7 @@ ARG is the prefix argument." (cl-letf (((symbol-function 'embark--restart) #'ignore) ((symbol-function 'embark--confirm) #'ignore)) (embark--act action candidate)))) - (quit (if embark-quit-after-action (not arg) arg))) + (quit (embark--quit-p action arg))) (when (and (eq action (embark--default-action type)) (eq action embark--command)) (setq candidates (mapcar #'embark--orig-target candidates))) @@ -2217,12 +2234,13 @@ See `embark-act' for the meaning of the prefix ARG." 0 (mod (prefix-numeric-value arg) (length targets))) targets))) - (default-action (embark--default-action (plist-get target :type)))) - (embark--act (or (command-remapping default-action) default-action) + (default-action (embark--default-action (plist-get target :type))) + (action (or (command-remapping default-action) default-action))) + (embark--act action (if (eq default-action embark--command) (embark--orig-target target) target) - (if embark-quit-after-action (not arg) arg))) + (embark--quit-p action arg))) (user-error "No target found"))) (define-obsolete-function-alias diff --git a/embark.texi b/embark.texi index 5d304cda30..bea884d707 100644 --- a/embark.texi +++ b/embark.texi @@ -500,24 +500,37 @@ embark to always prompt you for actions by setting the variable By default, if you call @samp{embark-act} from the minibuffer it quits the minibuffer after performing the action. You can change this by setting -the user option @samp{embark-quit-after-action} to @samp{nil}. That variable -controls whether or not @samp{embark-act} quits the minibuffer when you call -it without a prefix argument, and you can select the opposite behavior -to what the variable says by calling @samp{embark-act} with @samp{C-u}. Note that -both the variable @samp{embark-quit-after-action} and @samp{C-u} have no effect when -you call @samp{embark-act} outside the minibuffer. - -Having @samp{embark-act} @emph{not} quit the minibuffer can be useful to turn -commands into little ``thing managers''. For example, you can use -@samp{find-file} as a little file manager or @samp{describe-package} as a little -package manager: you can run those commands, perform a series of -actions, and then quit the command. +the user option @samp{embark-quit-after-action} to @samp{nil}. Having @samp{embark-act} @emph{not} +quit the minibuffer can be useful to turn commands into little ``thing +managers''. For example, you can use @samp{find-file} as a little file manager +or @samp{describe-package} as a little package manager: you can run those +commands, perform a series of actions, and then quit the command. + +If you want to control the quitting behavior in a fine-grained manner +depending on the action, you can set @samp{embark-quit-after-action} to an +alist, associating commands to either @samp{t} for quitting or @samp{nil} for not +quitting. When using an alist, you can use the special key @samp{t} to +specify the default behavior. For example, to specify that by default +actions should not quit the minibuffer but that using @samp{kill-buffer} as +an action should quit, you can use the following configuration: + +@lisp +(setq embark-quit-after-action '((kill-buffer . t) (t . nil))) +@end lisp + +The variable @samp{embark-quit-after-action} only specifies a default, that +is, it only controls whether or not @samp{embark-act} quits the minibuffer +when you call it without a prefix argument, and you can select the +opposite behavior to what the variable says by calling @samp{embark-act} with +@samp{C-u}. Also note that both the variable @samp{embark-quit-after-action} and @samp{C-u} +have no effect when you call @samp{embark-act} outside the minibuffer. If you find yourself using the quitting and non-quitting variants of -@samp{embark-act} about equally often, you may prefer to have separate -commands for them instead of a single command that you call with @samp{C-u} -half the time. You could, for example, keep the default exiting -behavior of @samp{embark-act} and define a non-quitting version as follows: +@samp{embark-act} about equally often, independently of the action, you may +prefer to simply have separate commands for them instead of a single +command that you call with @samp{C-u} half the time. You could, for example, +keep the default exiting behavior of @samp{embark-act} and define a +non-quitting version as follows: @lisp (defun embark-act-noquit ()