This is embark.info, produced by makeinfo version 6.7 from embark.texi.

INFO-DIR-SECTION Emacs
START-INFO-DIR-ENTRY
* Embark: (embark).     Emacs Mini-Buffer Actions Rooted in Keymaps.
END-INFO-DIR-ENTRY


File: embark.info,  Node: Top,  Next: Overview,  Up: (dir)

Embark: Emacs Mini-Buffer Actions Rooted in Keymaps
***************************************************

* Menu:

* Overview::
* Quick start::
* Advanced configuration::
* How does Embark call the actions?::
* Embark, Marginalia and Consult: Embark Marginalia and Consult.
* Resources::
* Contributions::
* Acknowledgments::

— The Detailed Node Listing —

Overview

* Acting on targets::
* The default action on a target::
* Working with sets of possible targets::
* Switching to a different command without losing what you've typed::

Advanced configuration

* Showing information about available targets and actions::
* Selecting commands via completions instead of key bindings::
* Quitting the minibuffer after an action::
* Running some setup after injecting the target::
* Running hooks before or after an action::
* Creating your own keymaps::
* Defining actions for new categories of targets::

Defining actions for new categories of targets

* New minibuffer target example - tab-bar tabs::
* New target example in regular buffers - short Wikipedia links::

How does Embark call the actions?

* Non-interactive functions as actions::



File: embark.info,  Node: Overview,  Next: Quick start,  Prev: Top,  Up: Top

1 Overview
**********

* Menu:

* Acting on targets::
* The default action on a target::
* Working with sets of possible targets::
* Switching to a different command without losing what you've typed::


File: embark.info,  Node: Acting on targets,  Next: The default action on a target,  Up: Overview

1.1 Acting on targets
=====================

This package provides a sort of right-click contextual menu for Emacs,
accessed through the ‘embark-act’ command (which you should bind to a
convenient key), offering you relevant _actions_ to use on a _target_
determined by the context:

   • In the minibuffer, the target is the current top completion
     candidate.
   • In the ‘*Completions*’ buffer the target is the completion at
     point.
   • In a regular buffer, the target is the region if active, or else
     the file, symbol, URL, s-expression or defun at point.

   Multiple targets can be present at the same location and you can
cycle between them by repeating the ‘embark-act’ key binding.  The type
of actions offered depend on the type of the target.  Here is a sample
of a few of the actions offered in the default configuration:

   • For files you get offered actions like deleting, copying, renaming,
     visiting in another window, running a shell command on the file,
     etc.
   • For buffers the actions include switching to or killing the buffer.
   • For package names the actions include installing, removing or
     visiting the homepage.
   • For Emacs Lisp symbols the actions include finding the definition,
     looking up documentation, evaluating (which for a variable
     immediately shows the value, but for a function lets you pass it
     some arguments first).  There are some actions specific to
     variables, such as setting the value directly or though the
     customize system, and some actions specific to commands, such as
     binding it to a key.

   By default when you use ‘embark-act’ if you don’t immediately select
an action, after a short delay Embark will pop up a buffer showing a
list of actions and their corresponding key bindings.  If you are using
‘embark-act’ outside the minibuffer, Embark will also highlight the
current target.  These behaviors are configurable via the variable
‘embark-indicators’.  Instead of selecting an action via its key
binding, you can select it by name with completion by typing ‘C-h’ after
‘embark-act’.

   Everything is easily configurable: determining the current target,
classifying it, and deciding which actions are offered for each type in
the classification.  The above introduction just mentions part of the
default configuration.

   Configuring which actions are offered for a type is particularly easy
and requires no programming: the variable ‘embark-keymap-alist’
associates target types with variables containing keymaps, and those
keymaps containing bindings for the actions.  (To examine the available
categories and their associated keymaps, you can use ‘C-h v
embark-keymap-alist’ or customize that variable.)  For example, in the
default configuration the type ‘file’ is associated with the symbol
‘embark-file-map’.  That symbol names a keymap with single-letter key
bindings for common Emacs file commands, for instance ‘c’ is bound to
‘copy-file’.  This means that if you are in the minibuffer after running
a command that prompts for a file, such as ‘find-file’ or ‘rename-file’,
you can copy a file by running ‘embark-act’ and then pressing ‘c’.

   These action keymaps are very convenient but not strictly necessary
when using ‘embark-act’: you can use any command that reads from the
minibuffer as an action and the target of the action will be inserted at
the first minibuffer prompt.  After running ‘embark-act’ all of your key
bindings and even ‘execute-extended-command’ can be used to run a
command.  For example, if you want to replace all occurrences of the
symbol at point, just use ‘M-%’ as the action, there is no need to bind
‘query-replace’ in one of Embark’s keymaps.  Also, those action keymaps
are normal Emacs keymaps and you should feel free to bind in them
whatever commands you find useful as actions and want to be available
through convenient bindings.

   The actions in ‘embark-general-map’ are available no matter what type
of completion you are in the middle of.  By default this includes
bindings to save the current candidate in the kill ring and to insert
the current candidate in the previously selected buffer (the buffer that
was current when you executed a command that opened up the minibuffer).

   Emacs’s minibuffer completion system includes metadata indicating the
_category_ of what is being completed.  For example, ‘find-file’’s
metadata indicates a category of ‘file’ and ‘switch-to-buffer’’s
metadata indicates a category of ‘buffer’.  Embark has the related
notion of the _type_ of a target for actions, and by default when
category metadata is present it is taken to be the type of minibuffer
completion candidates when used as targets.  Emacs commands often do not
set useful category metadata so the Marginalia
(https://github.com/minad/marginalia) package, which supplies this
missing metadata, is highly recommended for use with Embark.

   Embark’s default configuration has actions for the following target
types: files, buffers, symbols, packages, URLs, bookmarks, and as a
somewhat special case, actions for when the region is active.  You can
read about the default actions and their key bindings
(https://github.com/oantolin/embark/wiki/Default-Actions) on the GitHub
project wiki.


File: embark.info,  Node: The default action on a target,  Next: Working with sets of possible targets,  Prev: Acting on targets,  Up: Overview

1.2 The default action on a target
==================================

Embark has a notion of default action for a target:

   • If the target is a minibuffer completion candidate, then the
     default action is whatever command opened the minibuffer in the
     first place.  For example if you run ‘kill-buffer’, then the
     default action will be to kill buffers.
   • If the target comes from a regular buffer (i.e., not a minibuffer),
     then the default action is whatever is bound to ‘RET’ in the keymap
     of actions for that type of target.  For example, in Embark’s
     default configuration for a URL found at point the default action
     is ‘browse-url’, because ‘RET’ is bound to ‘browse-url’ in the
     ‘embark-url-map’ keymap.

   To run the default action you can press ‘RET’ after running
‘embark-act’.  Note that if there are several different targets at a
given location, each has its own default action, so first cycle to the
target you want and then press ‘RET’ to run the corresponding default
action.

   There is also ‘embark-dwim’ which runs the default action for the
first target found.  It’s pretty handy in non-minibuffer buffers: with
Embark’s default configuration it will:

   • Open the file at point.
   • Open the URL at point in a web browser (using the ‘browse-url’
     command).
   • Compose a new email to the email address at point.
   • In an Emacs Lisp buffer, if point is on an opening parenthesis or
     right after a closing one, it will evaluate the corresponding
     expression.
   • Go to the definition of an Emacs Lisp function, variable or macro
     at point.
   • Find the file corresponding to an Emacs Lisp library at point.


File: embark.info,  Node: Working with sets of possible targets,  Next: Switching to a different command without losing what you've typed,  Prev: The default action on a target,  Up: Overview

1.3 Working with sets of possible targets
=========================================

Besides acting individually on targets, Embark lets you work
collectively on a set of target _candidates_.  For example, while you
are in the minibuffer the candidates are simply the possible completions
of your input.  Embark provides three main commands to work on candidate
sets:

   • The ‘embark-act-all’ command runs the same action on each of the
     current candidates.  It is just like using ‘embark-act’ on each
     candidate in turn.  (Because you can easily act on many more
     candidates than you meant to, by default Embark asks you to confirm
     uses of ‘embark-act-all’; you can turn this off by setting the user
     option ‘embark-confirm-act-all’ to ‘nil’.)

   • The ‘embark-collect-snapshot’ command produces a buffer listing all
     the current candidates, for you to peruse and run actions on at
     your leisure.  The candidates can be viewed in a grid or as a list
     showing additional annotations.

   • The ‘embark-export’ command tries to open a buffer in an
     appropriate major mode for the set of candidates.  If the
     candidates are files export produces a Dired buffer; if they are
     buffers, you get an Ibuffer buffer; and if they are packages you
     get a buffer in package menu mode.

     If you use the grepping commands from the Consult
     (https://github.com/minad/consult/) package, ‘consult-grep’,
     ‘consult-git-grep’ or ‘consult-ripgrep’, then you’ll probably want
     to install and load the ‘embark-consult’ package, which adds
     support for exporting a list of grep results to an honest grep-mode
     buffer, on which you can even use wgrep
     (https://github.com/mhayashi1120/Emacs-wgrep) if you wish.

   When in doubt choosing between exporting and collecting, a good rule
of thumb is to always prefer ‘embark-export’ since when an exporter to a
special major mode is available for a given type of target, it will be
more featureful than an Embark collect buffer, and if no such exporter
is configured the ‘embark-export’ command falls back to the generic
‘embark-collect-snapshot’.

   These commands are always available as “actions” (although they do
not act on just the current target but on all candidates) for
‘embark-act’ and are bound to ‘A’, ‘S’, and ‘E’, respectively, in
‘embark-general-map’.  This means that you do not have to bind your own
key bindings for these (although you can, of course!), just a key
binding for ‘embark-act’.

   There is also the ‘embark-collect-live’ variant of
‘embark-collect-snapshot’ which produces “live” Embark Collect buffers,
meaning they auto-update as the set of candidates changes.  Most users
of visual completion UIs such as Vertico, Icomplete, Selectrum or Ivy
will probably either not want to use this from the minibuffer, to avoid
seeing double (the list of candidates is displayed both by Embark and by
the completion UI), or to configure their completion UI to hide while
using ‘embark-collect-live’.  See the Embark wiki for sample
configuration for Selectrum
(https://github.com/oantolin/embark/wiki/Additional-Configuration#pause-selectrum-while-using-embark-collect-live).
This command can also be used outside the minibuffer if you have a
relevant candidate collector registered in
‘embark-candidate-collectors’.  Users of the ‘embark-consult’ package,
for example, get such a candidate collector registered for them, and can
produce a live-updating table of contents for any buffer, whose items
are the lines matching ‘outline-regexp’.


File: embark.info,  Node: Switching to a different command without losing what you've typed,  Prev: Working with sets of possible targets,  Up: Overview

1.4 Switching to a different command without losing what you’ve typed
=====================================================================

Embark also has the ‘embark-become’ command which is useful for when you
run a command, start typing at the minibuffer and realize you meant a
different command.  The most common case for me is that I run
‘switch-to-buffer’, start typing a buffer name and realize I haven’t
opened the file I had in mind yet!  I’ll use this situation as a running
example to illustrate ‘embark-become’.  When this happens I can, of
course, press ‘C-g’ and then run ‘find-file’ and open the file, but this
requires retyping the portion of the file name you already typed.  This
process can be streamlined with ‘embark-become’: while still in the
‘switch-to-buffer’ you can run ‘embark-become’ and effectively make the
‘switch-to-buffer’ command become ‘find-file’ for this run.

   You can bind ‘embark-become’ to a key in ‘minibuffer-local-map’, but
it is also available as an action under the letter ‘B’ (uppercase), so
you don’t need a binding if you already have one for ‘embark-act’.  So,
assuming I have ‘embark-act’ bound to, say, ‘C-.’, once I realize I
haven’t open the file I can type ‘C-. B C-x C-f’ to have
‘switch-to-buffer’ become ‘find-file’ without losing what I have already
typed in the minibuffer.

   But for even more convenience, ‘embark-become’ offers shorter key
bindings for commands you are likely to want the current command to
become.  When you use ‘embark-become’ it looks for the current command
in all keymaps named in the list ‘embark-become-keymaps’ and then
activates all keymaps that contain it.  For example, the default value
of ‘embark-become-keymaps’ contains a keymap
‘embark-become-file+buffer-map’ with bindings for several commands
related to files and buffers, in particular, it binds ‘switch-to-buffer’
to ‘b’ and ‘find-file’ to ‘f’.  So when I accidentally try to switch to
a buffer for a file I haven’t opened yet, ‘embark-become’ finds that the
command I ran, ‘switch-to-buffer’, is in the keymap
‘embark-become-file+buffer-map’, so it activates that keymap (and any
others that also contain a binding for ‘switch-to-buffer’).  The end
result is that I can type ‘C-. B f’ to switch to ‘find-file’.


File: embark.info,  Node: Quick start,  Next: Advanced configuration,  Prev: Overview,  Up: Top

2 Quick start
*************

The easiest way to install Embark is from GNU ELPA, just run ‘M-x
package-install RET embark RET’.  (It is also available on MELPA.)  It
is highly recommended to also install Marginalia
(https://github.com/minad/marginalia) (also available on GNU ELPA), so
that Embark can offer you preconfigured actions in more contexts.  For
‘use-package’ users, the following is a very reasonable starting
configuration:

     (use-package marginalia
       :ensure t
       :config
       (marginalia-mode))

     (use-package embark
       :ensure t

       :bind
       (("C-." . embark-act)         ;; pick some comfortable binding
        ("C-;" . embark-dwim)        ;; good alternative: M-.
        ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'

       :init

       ;; Optionally replace the key help with a completing-read interface
       (setq prefix-help-command #'embark-prefix-help-command)

       :config

       ;; Hide the mode line of the Embark live/completions buffers
       (add-to-list 'display-buffer-alist
                    '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
                      nil
                      (window-parameters (mode-line-format . none)))))

     ;; Consult users will also want the embark-consult package.
     (use-package embark-consult
       :ensure t
       :after (embark consult)
       :demand t ; only necessary if you have the hook below
       ;; if you want to have consult previews as you move around an
       ;; auto-updating embark collect buffer
       :hook
       (embark-collect-mode . consult-preview-at-point-mode))

   Other Embark commands such as ‘mbark-act-all’, ‘embark-become’,
‘embark-collect-snapshot’, ‘embark-collect-live’, ‘embark-export’ can be
run through ‘embark-act’ as actions bound to ‘A’, ‘B’, ‘S’, ‘L’, ‘E’
respectively, and thus don’t really need a dedicated key binding, but
feel free to bind them directly if you so wish.  If you do choose to
bind them directly, you’ll probably want to bind them in
‘minibuffer-local-map’, since they are most useful in the minibuffer (in
fact, ‘embark-become’ only works in the minibuffer).

   The command ‘embark-dwim’ executes the default action at point.
Another good keybinding for ‘embark-dwim’ is ‘M-.’ since ‘embark-dwim’
acts like ‘xref-find-definitions’ on the symbol at point.  ‘C-.’ can be
seen as a right-click context menu at point and ‘M-.’ acts like
left-click.  The keybindings are mnemonic, both act at the point (‘.’).

   Embark needs to know what your minibuffer completion system considers
to be the list of candidates and which one is the current candidate.
Embark works out of the box if you use Emacs’s default tab completion,
the built-in ‘icomplete-mode’ or ‘fido-mode’, or the third-party
packages Vertico (https://github.com/minad/vertico), Selectrum
(https://github.com/raxod502/selectrum/) or Ivy
(https://github.com/abo-abo/swiper).

   If you are a Helm (https://emacs-helm.github.io/helm/) or Ivy
(https://github.com/abo-abo/swiper) user you are unlikely to want Embark
since those packages include comprehensive functionality for acting on
minibuffer completion candidates.  (Embark does come with Ivy
integration despite this.)


File: embark.info,  Node: Advanced configuration,  Next: How does Embark call the actions?,  Prev: Quick start,  Up: Top

3 Advanced configuration
************************

* Menu:

* Showing information about available targets and actions::
* Selecting commands via completions instead of key bindings::
* Quitting the minibuffer after an action::
* Running some setup after injecting the target::
* Running hooks before or after an action::
* Creating your own keymaps::
* Defining actions for new categories of targets::


File: embark.info,  Node: Showing information about available targets and actions,  Next: Selecting commands via completions instead of key bindings,  Up: Advanced configuration

3.1 Showing information about available targets and actions
===========================================================

By default, if you run ‘embark-act’ and do not immediately select an
action, after a short delay Embark will pop up a buffer called ‘*Embark
Actions*’ containing a list of available actions with their key
bindings.  You can scroll that buffer with the mouse of with the usual
commands ‘scroll-other-window’ and ‘scroll-other-window-down’ (bound by
default to ‘C-M-v’ and ‘C-M-S-v’).

   That functionality is provided by the ‘embark-mixed-indicator’, but
Embark has other indicators that can provide information about the
target and its type, what other targets you can cycle to, and which
actions have key bindings in the action map for the current type of
target.  Any number of indicators can be active at once and the user
option ‘embark-indicators’ should be set to a list of the desired
indicators.

   Embark comes with the following indicators:

   • ‘embark-minimal-indicator’: shows a messages in the echo area or
     minibuffer prompt showing the current target and the types of all
     targets starting with the current one; this one is on by default.

   • ‘embark-highlight-indicator’: highlights the target at point; also
     on by default.

   • ‘embark-verbose-indicator’: displays a table of actions and their
     key bindings in a buffer; this is not on by default, in favor of
     the mixed indicator described next.

   • ‘embark-mixed-indicator’: starts out by behaving as the minimal
     indicator but after a short delay acts as the verbose indicator;
     this is on by default.

   • ‘embark-isearch-highlight-indicator’: this only does something when
     the current target is the symbol at point, in which case it lazily
     highlights all occurrences of that symbol in the current buffer,
     like isearch; also on by default.

   Users of the popular which-key
(https://github.com/justbur/emacs-which-key) package may prefer to use
the ‘embark-which-key-indicator’ from the Embark wiki
(https://github.com/oantolin/embark/wiki/Additional-Configuration#use-which-key-like-a-key-menu-prompt).
Just copy its definition from the wiki into your configuration and
customize the ‘embark-indicators’ user option to exclude the mixed and
verbose indicators and to include ‘embark-which-key-indicator’.


File: embark.info,  Node: Selecting commands via completions instead of key bindings,  Next: Quitting the minibuffer after an action,  Prev: Showing information about available targets and actions,  Up: Advanced configuration

3.2 Selecting commands via completions instead of key bindings
==============================================================

As an alternative to reading the list of actions in the verbose or mixed
indicators (see the previous section for a description of these), you
can press the ‘embark-help-key’, which is ‘C-h’ by default (but you may
prefer ‘?’ to free up ‘C-h’ for use as a prefix) after running
‘embark-act’.  Pressing the help key will prompt you for the name of an
action with completion (but feel free to enter a command that is not
among the offered candidates!), and will also remind you of the key
bindings.  You can press ‘embark-keymap-prompter-key’, which is ‘@’ by
default, at the prompt and then one of the key bindings to enter the
name of the corresponding action.

   You may think that with the ‘*Embark Actions*’ buffer popping up to
remind you of the key bindings you’d never want to use completion to
select an action by name, but personally I find that typing a small
portion of the action name to narrow down the list of candidates feels
significantly faster than visually scanning the entire list of actions.

   If you find you prefer entering actions that way, you can configure
embark to always prompt you for actions by setting the variable
‘embark-prompter’ to ‘embark-completing-read-prompter’.


File: embark.info,  Node: Quitting the minibuffer after an action,  Next: Running some setup after injecting the target,  Prev: Selecting commands via completions instead of key bindings,  Up: Advanced configuration

3.3 Quitting the minibuffer after an action
===========================================

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’.  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:

     (setq embark-quit-after-action '((kill-buffer . t) (t . nil)))

   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, 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:

     (defun embark-act-noquit ()
       "Run action but don't quit the minibuffer afterwards."
       (interactive)
       (let ((embark-quit-after-action nil))
         (embark-act)))


File: embark.info,  Node: Running some setup after injecting the target,  Next: Running hooks before or after an action,  Prev: Quitting the minibuffer after an action,  Up: Advanced configuration

3.4 Running some setup after injecting the target
=================================================

You can customize what happens after the target is inserted at the
minibuffer prompt of an action.  There are
‘embark-target-injection-hooks’, that are run by default after injecting
the target into the minibuffer.  The variable
‘embark-target-injection-hooks’ is an alist associating commands to
their setup hooks.  There are two special keys: if no setup hook is
specified for a given action, the hook associated to ‘t’ is run; and the
hook associated to ‘:always’ is run regardless of the action.  (This
variable used to have the less explicit name of
‘embark-setup-action-hooks’, so please update your configuration.)

   For example, consider using ‘shell-command’ as an action during file
completion.  It would be useful to insert a space before the target file
name and to leave the point at the beginning, so you can immediately
type the shell command to run on that file.  That’s why in Embark’s
default configuration there is an entry in
‘embark-target-injection-hooks’ associating ‘shell-command’ to a hook
that includes ‘embark--shell-prep’, a simple helper function that quotes
all the spaces in the file name, inserts an extra space at the beginning
of the line and leaves point to the left of it.

   Now, the preparation that ‘embark--shell-prep’ does would be useless
if Embark did what it normally does after it inserts the target of the
action at the minibuffer prompt, which is to “press ‘RET’” for you,
accepting the target as is; if Embark did that for ‘shell-command’ you
wouldn’t get a chance to type in the command to execute!  That is why in
Embark’s default configuration the entry for ‘shell-command’ in
‘embark-target-injection-hooks’ also contains the function
‘embark--allow-edit’.

   Embark used to have a dedicated variable ‘embark-allow-edit-actions’
to which you could add commands for which Embark should forgo pressing
‘RET’ for you after inserting the target.  Since its effect can also be
achieved via the general ‘embark-target-injection-hooks’ mechanism, that
variable has been removed to simply Embark.  Be sure to update your
configuration; if you had something like:

     (add-to-list 'embark-allow-edit-actions 'my-command)

   you should replace it with:

     (push 'embark--allow-edit
           (alist-get 'my-command embark-target-injection-hooks))

   Also note that while you could abuse ‘embark--allow-edit’ so that you
have to confirm “dangerous” actions such as ‘delete-file’, it is better
to implement confirmation by adding the ‘embark--confirm’ function to
the appropriate entry of a different hook alist, namely,
‘embark-pre-action-hooks’.

   Besides ‘embark--allow-edit’, Embark comes with another function that
is of general utility in action setup hooks: ‘embark--ignore-target’.
Use it for commands that do prompt you in the minibuffer but for which
inserting the target would be inappropriate.  This is not a common
situation but does occasionally arise.  For example it is used by
default for ‘shell-command-on-region’: that command is used as an action
for region targets, and it prompts you for a shell command; you
typically do _not_ want the target, that is the contents of the region,
to be entered at that prompt!


File: embark.info,  Node: Running hooks before or after an action,  Next: Creating your own keymaps,  Prev: Running some setup after injecting the target,  Up: Advanced configuration

3.5 Running hooks before or after an action
===========================================

Embark has two variables, ‘embark-pre-action-hooks’ and
‘embark-post-action-hooks’, which are alists associating commands to
hooks that should run before or after the command is used as an action.
As with, ‘embark-target-injection-hooks’, there are two special keys for
the alists: ‘t’ designates the default hook to run when no specific hook
is specified for a command; and the hook associated to ‘:always’ runs
regardless.

   The default values of those variables are fairly extensive, adding
creature comforts to make running actions a smooth experience.  Embark
comes with several functions intended to be added to these hooks, and
used in the default values of ‘embark-pre-action-hooks’ and
‘embark-post-action-hooks’.

   For pre-action hooks:

‘embark--confirm’
     Prompt the user for confirmation before executing the action.  This
     is used be default for commands deemed “dangerous”, or, more
     accurately, hard to undo, such as ‘delete-file’ and ‘kill-buffer’.

‘embark--mark-target’
     Mark the target as an active region.  Most targets at point outside
     the minibuffer report which region of the buffer they correspond to
     (this is the information used by ‘embark-highlight-indicator’ to
     know what portion of the buffer to highlight); this function marks
     that region.  It is useful as a pre action hook for commands that
     expect a region to be marked, for example, it is used by default
     for ‘indent-region’ so that it works on s-expression targets, or
     for ‘fill-region’ so that it works on paragraph targets.

‘embark--unmark-target’
     Unmark the active region.  Use this for commands you want to act on
     the region contents but without the region being active.  The
     default configuration uses this function as a pre-action hook for
     ‘occur’ and ‘query-replace’, for example, so that you can use them
     as actions with region targets to search the whole buffer for the
     text contained in the region.  Without this pre-action hook using
     ‘occur’ as an action for a region target would be pointless: it
     would search for the the region contents _in the region_,
     (typically, due to the details of regexps) finding only one match!

‘embark--beginning-of-target’
     Move to the beginning of the target (for targets that report
     bounds).  This is used by default for backward motion commands such
     as ‘backward-sexp’, so that they don’t accidentally leave you on
     the current target.

‘embark--end-of-target’
     Move to the end of the target.  This is used similarly to the
     previous function, but also for commands that act on the last
     s-expression like ‘eval-last-sexp’.  This allow you to act on an
     s-expression from anywhere inside it and still use ‘eval-last-sexp’
     as an action.

‘embark--narrow-to-target’
     Narrow buffer to current target.  Use this as a pre-action hook to
     localize the effect of actions that don’t already work on just the
     region.  In the default configuration it is used for
     ‘repunctuate-sentences’.

‘embark--xref-push-markers’
     Push the current location on the xref marker stack.  Use this for
     commands that take you somewhere and for which you’d like to be
     able to come back to where you were using ‘xref-pop-marker-stack’.
     This is used by default for ‘find-library’.

   For post-action hooks:

‘embark--restart’
     Restart the command currently prompting in the minibuffer, so that
     the list of completion candidates is updated.  This is useful as a
     post action hook for commands that delete or rename a completion
     candidate; for example the default value of
     ‘embark-post-action-hooks’ uses it for ‘delete-file’,
     ‘kill-buffer’, ‘rename-file’, ‘rename-buffer’, etc.


File: embark.info,  Node: Creating your own keymaps,  Next: Defining actions for new categories of targets,  Prev: Running hooks before or after an action,  Up: Advanced configuration

3.6 Creating your own keymaps
=============================

All internal keymaps are defined with a helper macro
‘embark-define-keymap’ that you can use to define your own keymaps,
whether they are for new categories in ‘embark-keymap-alist’ or for any
other purpose!  For example a simple version of the file action keymap
could be defined as follows:

     (embark-define-keymap embark-file-map
       "Example keymap with a few file actions"
       ("d" delete-file)
       ("r" rename-file)
       ("c" copy-file))

   Remember also that these action keymaps are perfectly normal Emacs
keymaps, and do not need to be created with this helper macro.  You can
use the built-in ‘define-key’, or your favorite external package such as
‘bind-key’ or ‘general.el’ to manage them.


File: embark.info,  Node: Defining actions for new categories of targets,  Prev: Creating your own keymaps,  Up: Advanced configuration

3.7 Defining actions for new categories of targets
==================================================

It is easy to configure Embark to provide actions for new types of
targets, either in the minibuffer or outside it.  I present below two
very detailed examples of how to do this.  At several points I’ll
explain more than one way to proceed, typically with the easiest option
first.  I include the alternative options since there will be similar
situations where the easiest option is not available.

* Menu:

* New minibuffer target example - tab-bar tabs::
* New target example in regular buffers - short Wikipedia links::


File: embark.info,  Node: New minibuffer target example - tab-bar tabs,  Next: New target example in regular buffers - short Wikipedia links,  Up: Defining actions for new categories of targets

3.7.1 New minibuffer target example - tab-bar tabs
--------------------------------------------------

As an example, take the new tab bars
(https://www.gnu.org/software/emacs/manual/html_node/emacs/Tab-Bars.html)
from Emacs 27.  I’ll explain how to configure Embark to offer
tab-specific actions when you use the tab-bar-mode commands that mention
tabs by name.  The configuration explained here is now built-in to
Embark (and Marginalia), but it’s still a good self-contained example.
In order to setup up tab actions you would need to: (1) make sure Embark
knows those commands deal with tabs, (2) define a keymap for tab actions
and configure Embark so it knows that’s the keymap you want.

  1. Telling Embark about commands that prompt for tabs by name

     For step (1), it would be great if the ‘tab-bar-mode’ commands
     reported the completion category ‘tab’ when asking you for a tab
     with completion.  (All built-in Emacs commands that prompt for file
     names, for example, do have metadata indicating that they want a
     ‘file’.)  They do not, unfortunately, and I will describe a couple
     of ways to deal with this.

     Maybe the easiest thing is to configure Marginalia
     (https://github.com/minad/marginalia) to enhance those commands.
     All of the ‘tab-bar-*-tab-by-name’ commands have the words “tab by
     name” in the minibuffer prompt, so you can use:

          (add-to-list 'marginalia-prompt-categories '("tab by name" . tab))

     That’s it!  But in case you are ever in a situation where you don’t
     already have commands that prompt for the targets you want, I’ll
     describe how writing your own command with appropriate ‘category’
     metadata looks:

          (defun my-select-tab-by-name (tab)
            (interactive
             (list
              (let ((tab-list (or (mapcar (lambda (tab) (cdr (assq 'name tab)))
                                          (tab-bar-tabs))
                                  (user-error "No tabs found"))))
                (completing-read
                 "Tabs: "
                 (lambda (string predicate action)
                   (if (eq action 'metadata)
                       '(metadata (category . tab))
                     (complete-with-action
                      action tab-list string predicate)))))))
            (tab-bar-select-tab-by-name tab))

     As you can see, the built-in support for setting the category
     meta-datum is not very easy to use or pretty to look at.  To help
     with this I recommend the ‘consult--read’ function from the
     excellent Consult (https://github.com/minad/consult/) package.
     With that function we can rewrite the command as follows:

          (defun my-select-tab-by-name (tab)
            (interactive
             (list
              (let ((tab-list (or (mapcar (lambda (tab) (cdr (assq 'name tab)))
                                          (tab-bar-tabs))
                                  (user-error "No tabs found"))))
                (consult--read tab-list
                               :prompt "Tabs: "
                               :category 'tab))))
            (tab-bar-select-tab-by-name tab))

     Much nicer!  No matter how you define the ‘my-select-tab-by-name’
     command, the first approach with Marginalia and prompt detection
     has the following advantages: you get the ‘tab’ category for all
     the ‘tab-bar-*-bar-by-name’ commands at once, also, you enhance
     built-in commands, instead of defining new ones.

  2. Defining and configuring a keymap for tab actions

     Let’s say we want to offer select, rename and close actions for
     tabs (in addition to Embark general actions, such as saving the tab
     name to the kill-ring, which you get for free).  Then this will do:

          (embark-define-keymap embark-tab-actions
            "Keymap for actions for tab-bar tabs (when mentioned by name)."
            ("s" tab-bar-select-tab-by-name)
            ("r" tab-bar-rename-tab-by-name)
            ("k" tab-bar-close-tab-by-name))

          (add-to-list 'embark-keymap-alist '(tab . embark-tab-actions))

     What if after using this for a while you feel closing the tab
     without confirmation is dangerous?  You have a couple of options:

       1. You can keep using the ‘tab-bar-close-tab-by-name’ command,
          but have Embark ask you for confirmation:
               (push #'embark--confirm
                     (alist-get 'tab-bar-close-tab-by-name
                                embark-pre-action-hooks))

       2. You can write your own command that prompts for confirmation
          and use that instead of ‘tab-bar-close-tab-by-name’ in the
          above keymap:
               (defun my-confirm-close-tab-by-name (tab)
                 (interactive "sTab to close: ")
                 (when (y-or-n-p (format "Close tab '%s'? " tab))
                   (tab-bar-close-tab-by-name tab)))

          Notice that this is a command you can also use directly from
          ‘M-x’ independently of Embark.  Using it from ‘M-x’ leaves
          something to be desired, though, since you don’t get
          completion for the tab names.  You can fix this if you wish as
          described in the previous section.


File: embark.info,  Node: New target example in regular buffers - short Wikipedia links,  Prev: New minibuffer target example - tab-bar tabs,  Up: Defining actions for new categories of targets

3.7.2 New target example in regular buffers - short Wikipedia links
-------------------------------------------------------------------

Say you want to teach Embark to treat text of the form
‘wikipedia:Garry_Kasparov’ in any regular buffer as a link to Wikipedia,
with actions to open the Wikipedia page in eww or an external browser or
to save the URL of the page in the kill-ring.  We can take advantage of
the actions that Embark has preconfigured for URLs, so all we need to do
is teach Embark that ‘wikipedia:Garry_Kasparov’ stands for the URL
‘https://en.wikipedia.org/wiki/Garry_Kasparov’.

   You can be as fancy as you want with the recognized syntax.  Here, to
keep the example simple, I’ll assume the link matches the regexp
‘wikipedia:[[:alnum:]_]+’.  We will write a function that looks for a
match surrounding point, and returns an improper list of the form ‘'(url
actual-url-of-the-page beg . end)’ where ‘beg’ and ‘end’ are the buffer
positions where the target starts and ends, and are used by Embark to
highlight the target (if you have ‘embark-highlight-indicator’ included
in the list ‘embark-indicators’).

     (defun my-short-wikipedia-link ()
       "Target a link at point of the form wikipedia:Page_Name."
       (save-excursion
         (let* ((beg (progn (skip-chars-backward "[:alnum:]_:") (point)))
                (end (progn (skip-chars-forward "[:alnum:]_:") (point)))
                (str (buffer-substring-no-properties beg end)))
           (save-match-data
             (when (string-match "wikipedia:\\([[:alnum:]_]+\\)" str)
               `(url
                 (format "https://en.wikipedia.org/wiki/%s"
                         (match-string 1 str))
                 ,beg . ,end))))))

     (add-to-list 'embark-target-finders 'my-short-wikipedia-link)


File: embark.info,  Node: How does Embark call the actions?,  Next: Embark Marginalia and Consult,  Prev: Advanced configuration,  Up: Top

4 How does Embark call the actions?
***********************************

Embark actions are normal Emacs commands, that is, functions with an
interactive specification.  In order to execute an action, Embark calls
the command with ‘call-interactively’, so the command reads user input
exactly as if run directly by the user.  For example the command may
open a minibuffer and read a string (‘read-from-minibuffer’) or open a
completion interface (‘completing-read’).  If this happens, Embark takes
the target string and inserts it automatically into the minibuffer,
simulating user input this way.  After inserting the string, Embark
exits the minibuffer, submitting the input.  (The immediate minibuffer
exit can be disabled for specific actions in order to allow editing the
input; this is done by adding the ‘embark--allow-edit’ function to the
appropriate entry of ‘embark-target-injection-hooks’).  Embark inserts
the target string at the first minibuffer opened by the action command,
and if the command happens to prompt the user for input more than once,
the user still interacts with the second and further prompts in the
normal fashion.  Note that if a command does not prompt the user for
input in the minibuffer, Embark still allows you to use it as an action,
but of course, never inserts the target anywhere.  (There are plenty of
examples in the default configuration of commands that do not prompt the
user bound to keys in the action maps, most of the region actions, for
instance.)

   This is how Embark manages to reuse normal commands as actions.  The
mechanism allows you to use as Embark actions commands that were not
written with Embark in mind (and indeed almost all actions that are
bound by default in Embark’s action keymaps are standard Emacs
commands).  It also allows you to write new custom actions in such a way
that they are useful even without Embark.

   Staring from version 28.1, Emacs has a variable
‘y-or-n-p-use-read-key’, which when set to ‘t’ causes ‘y-or-n-p’ to use
‘read-key’ instead of ‘read-from-minibuffer’.  Setting
‘y-or-n-p-use-read-key’ to ‘t’ is recommended for Embark users because
it keeps Embark from attempting to insert the target at a ‘y-or-n-p’
prompt, which would almost never be sensible.  Also consider this as a
warning to structure your own action commands so that if they use
‘y-or-n-p’, they do so only after the prompting for the target.

   Here is a simple example illustrating the various ways of reading
input from the user mentioned above.  Bind the following commands to the
‘embark-symbol-map’ to be used as actions, then put the point on some
symbol and run them with ‘embark-act’:

     (defun example-action-command1 ()
       (interactive)
       (message "The input was `%s'." (read-from-minibuffer "Input: ")))

     (defun example-action-command2 (arg input1 input2)
       (interactive "P\nsInput 1: \nsInput 2: ")
       (message "The first input %swas `%s', and the second was `%s'."
                (if arg "truly " "")
                input1
                input2))

     (defun example-action-command3 ()
       (interactive)
       (message "Your selection was `%s'."
                (completing-read "Select: " '("E" "M" "B" "A" "R" "K"))))

     (defun example-action-command4 ()
       (interactive)
       (message "I don't prompt you for input and thus ignore the target!"))

     (define-key embark-symbol-map "X1" #'example-action-command1)
     (define-key embark-symbol-map "X2" #'example-action-command2)
     (define-key embark-symbol-map "X3" #'example-action-command3)
     (define-key embark-symbol-map "X4" #'example-action-command4)

   Also note that if you are using the key bindings to call actions, you
can pass prefix arguments to actions in the normal way.  For example,
you can use ‘C-u X2’ with the above demonstration actions to make the
message printed by ‘example-action-command2’ more emphatic.  This
ability to pass prefix arguments to actions is useful for some actions
in the default configuration, such as ‘embark-shell-command-on-buffer’.

* Menu:

* Non-interactive functions as actions::


File: embark.info,  Node: Non-interactive functions as actions,  Up: How does Embark call the actions?

4.1 Non-interactive functions as actions
========================================

Alternatively, Embark does support one other type of action: a
non-interactive function of a single argument.  The target is passed as
argument to the function.  For example:

     (defun example-action-function (target)
       (message "The target was `%s'." target))

     (define-key embark-symbol-map "X4" #'example-action-function)

   Note that normally binding non-interactive functions in a keymap is
useless, since when attempting to run them using the key binding you get
an error message similar to “Wrong type argument: commandp,
example-action-function”.  In general it is more flexible to write any
new Embark actions as commands, that is, as interactive functions,
because that way you can also run them directly, without Embark.  But
there are a couple of reasons to use non-interactive functions as
actions:

  1. You may already have the function lying around, and it is
     convenient to simply reuse it.

  2. For command actions the targets can only be simple string, with no
     text properties.  For certain advanced uses you may want the action
     to receive a string _with_ some text properties, or even a
     non-string target.


File: embark.info,  Node: Embark Marginalia and Consult,  Next: Resources,  Prev: How does Embark call the actions?,  Up: Top

5 Embark, Marginalia and Consult
********************************

Embark cooperates well with the Marginalia
(https://github.com/minad/marginalia) and Consult
(https://github.com/minad/consult) packages.  Neither of those packages
is a dependency of Embark, but Marginalia is highly recommended, for
reasons explained in the rest of this section.

   Embark comes with actions for symbols (commands, functions, variables
with actions such as finding the definition, looking up the
documentation, evaluating, etc.)  in the ‘embark-symbol-map’ keymap, and
for packages (actions like install, delete, browse url, etc.)  in the
‘embark-package-keymap’.

   Unfortunately Embark does not automatically offers you these keymaps
when relevant, because many built-in Emacs commands don’t report
accurate category metadata.  For example, a command like
‘describe-package’, which reads a package name from the minibuffer, does
not have metadata indicating this fact.

   In an earlier Embark version, there were functions to supply this
missing metadata, but they have been moved to Marginalia, which augments
many Emacs command to report accurate category metadata.  Simply
activating ‘marginalia-mode’ allows Embark to offer you the package and
symbol actions when appropriate again.  Candidate annotations in the
Embark collect buffer are also provided by the Marginalia package.

   • If you install Marginalia and activate ‘marginalia-mode’, the list
     view in Embark Collect buffers will use the Marginalia annotations
     automatically.

   • If you don’t install Marginalia, you will see only the annotations
     that come with Emacs (such as key bindings in ‘M-x’, or the unicode
     characters in ‘C-x 8 RET’).

   • If you have Consult installed and call ‘embark-collect-snapshot’
     from ‘consult-line’, ‘consult-mark’ or ‘consult-outline’, you will
     notice the Embark Collect buffer starts in list view by default.
     Similarly, you’ll notice that the ‘consult-yank’ family of commands
     start out in list view with zebra stripes, so you can easily tell
     where multi-line kill-ring entries start and end.

   • The function ‘embark-open-externally’ has been removed following
     the policy of avoiding overlap with Consult.  If you used that
     action, add the small function
     (https://github.com/minad/consult/blob/373498acb76b9395e5e590fb8e39f671a9363cd7/consult.el#L707)
     to your configuration or install Consult and use
     ‘consult-file-externally’.


File: embark.info,  Node: Resources,  Next: Contributions,  Prev: Embark Marginalia and Consult,  Up: Top

6 Resources
***********

If you want to learn more about how others have used Embark here are
some links to read:

   • Fifteen ways to use Embark
     (https://karthinks.com/software/fifteen-ways-to-use-embark/), a
     blog post by Karthik Chikmagalur.
   • Protesilaos Stavrou’s dotemacs (https://protesilaos.com/dotemacs/),
     look for the section called “Extended minibuffer actions and more
     (embark.el and prot-embark.el)”

   And some videos to watch:

   • Embark and my extras
     (https://protesilaos.com/codelog/2021-01-09-emacs-embark-extras/)
     by Protesilaos Stavrou.
   • Embark – Key features and tweaks (https://youtu.be/qpoQiiinCtY) by
     Raoul Comninos on the Emacs-Elements YouTube channel.
   • Livestreamed: Adding an Embark context action to send a stream
     message (https://youtu.be/WsxXr1ncukY) by Sacha Chua.
   • System Crafters Live!  - The Many Uses of Embark
     (https://youtu.be/qk2Is_sC8Lk) by David Wilson.
   • Marginalia, Consult and Embark by Mike Zamansky.


File: embark.info,  Node: Contributions,  Next: Acknowledgments,  Prev: Resources,  Up: Top

7 Contributions
***************

Contributions to Embark are very welcome.  There is a wish list
(https://github.com/oantolin/embark/issues/95) for actions, target
finders, candidate collectors and exporters.  For other ideas you have
for Embark, feel free to open an issue on the issue tracker
(https://github.com/oantolin/embark/issues).  Any neat configuration
tricks you find might be a good fit for the wiki
(https://github.com/oantolin/embark/wiki).

   Code contributions are very welcome too, but since Embark is now on
GNU ELPA, copyright assignment to the FSF is required before you can
contribute code.


File: embark.info,  Node: Acknowledgments,  Prev: Contributions,  Up: Top

8 Acknowledgments
*****************

While I, Omar Antolín Camarena, have written most of the Embark code and
remain very stubborn about some of the design decisions, Embark has
received substantial help from a number of other people which this
document has neglected to mention for far too long.  In particular,
Daniel Mendler has been absolutely invaluable, implementing several
important features, and providing a lot of useful advice.

   Code contributions:

   • Daniel Mendler (https://github.com/minad)
   • Clemens Radermacher (https://github.com/clemera/)
   • José Antonio Ortega Ruiz (https://codeberg.org/jao/)
   • Itai Y.  Efrat (https://github.com/iyefrat)
   • a13 (https://github.com/a13)
   • jakanakaevangeli (https://github.com/jakanakaevangeli)
   • mihakam (https://github.com/mihakam)
   • Brian Leung (https://github.com/leungbk)
   • Karthik Chikmagalur (https://github.com/karthink)
   • Roshan Shariff (https://github.com/roshanshariff)
   • condy0919 (https://github.com/condy0919)
   • Damien Cassou (https://github.com/DamienCassou)
   • JimDBh (https://github.com/JimDBh)

   Advice and useful discussions:

   • Daniel Mendler (https://github.com/minad)
   • Protesilaos Stavrou (https://gitlab.com/protesilaos/)
   • Clemens Radermacher (https://github.com/clemera/)
   • Howard Melman (https://github.com/hmelman/)
   • Augusto Stoffel (https://github.com/astoff)
   • Bruce d’Arcus (https://github.com/bdarcus)
   • JD Smith (https://github.com/jdtsmith)
   • Karthik Chikmagalur (https://github.com/karthink)
   • jakanakaevangeli (https://github.com/jakanakaevangeli)
   • Itai Y.  Efrat (https://github.com/iyefrat)
   • Mohsin Kaleem (https://github.com/mohkale)



Tag Table:
Node: Top206
Node: Overview1418
Node: Acting on targets1700
Node: The default action on a target7203
Node: Working with sets of possible targets9110
Node: Switching to a different command without losing what you've typed12993
Node: Quick start15567
Node: Advanced configuration19016
Node: Showing information about available targets and actions19543
Node: Selecting commands via completions instead of key bindings22152
Node: Quitting the minibuffer after an action23756
Node: Running some setup after injecting the target26209
Node: Running hooks before or after an action29815
Node: Creating your own keymaps34017
Node: Defining actions for new categories of targets35004
Node: New minibuffer target example - tab-bar tabs35773
Ref: Telling Embark about commands that prompt for tabs by name36676
Ref: Defining and configuring a keymap for tab actions39539
Node: New target example in regular buffers - short Wikipedia links41293
Node: How does Embark call the actions?43325
Node: Non-interactive functions as actions47661
Node: Embark Marginalia and Consult49014
Node: Resources51707
Node: Contributions52851
Node: Acknowledgments53561

End Tag Table


Local Variables:
coding: utf-8
End:
