-
-
Notifications
You must be signed in to change notification settings - Fork 59
Additional Configuration
This page lists example of additional configuration that might be useful to use with embark
.
The built-in embark-verbose-indicator
displays actions in a buffer along with their keybindings and the first line of their docstrings. Users desiring a more compact display can use which-key instead with the following configuration:
(defun embark-which-key-indicator (keymap targets)
"An embark indicator that displays KEYMAP with which-key.
The which-key help message will show the type and value of the
current target followed by an ellipsis if there are further
TARGETS."
(which-key--show-keymap
(if (eq (caar targets) 'embark-become)
"Become"
(format "Act on %s '%s'%s"
(caar targets)
(embark--truncate-target (cdar targets))
(if (cdr targets) "…" "")))
keymap
nil nil t)
(lambda (prefix)
(if prefix
(embark-which-key-indicator (lookup-key keymap prefix) targets)
(kill-buffer which-key--buffer))))
(setq embark-indicator #'embark-which-key-indicator)
Some actions, such as delete-file
, rename-file
or kill-buffer
can change the candidate list. To get the completion UI to refresh automatically use the following:
(add-hook 'embark-pre-action-hook #'completion--flush-all-sorted-completions)
(defun refresh-selectrum ()
(setq selectrum--previous-input-string nil))
(add-hook 'embark-pre-action-hook #'refresh-selectrum)
(add-hook 'embark-post-action-hook #'embark-collect--update-linked)
This produces an effect similar to (setq resize-mini-windows t)
for the minibuffer.
(add-hook 'embark-collect-post-revert-hook
(defun resize-embark-collect-window (&rest _)
(when (memq embark-collect--kind '(:live :completions))
(fit-window-to-buffer (get-buffer-window)
(floor (frame-height) 2) 1))))))
Because of the way embark-act works, @tarsius's excellent keycast package never finds out that Embark actions are commands nor what keys you pressed to run them. The following configuration fixes that:
(defun store-action-key+cmd (cmd)
(setq keycast--this-command-keys (this-single-command-keys)
keycast--this-command cmd))
(advice-add 'embark-keymap-prompter :filter-return #'store-action-key+cmd)
(defun force-keycast-update (&rest _)
(force-mode-line-update t))
(dolist (cmd '(embark-act embark-act-noexit embark-become))
(advice-add cmd :before #'force-keycast-update))
When live collect is active you may want to shrink the Selectrum minibuffer
in order to save some screen space. The shrink-selectrum
hook ensures
that Selectrum switches to horizontal mode, showing only a single candidate.
(defun shrink-selectrum ()
(when (eq embark-collect--kind :live)
(with-selected-window (active-minibuffer-window)
(setq-local selectrum-num-candidates-displayed 1)
(setq-local selectrum-display-style
'(horizontal :before-candidates "[" :after-candidates "]"
:more-candidates "" :candidates-separator "")))))
(add-hook 'embark-collect-mode-hook #'shrink-selectrum)
Ivy allows to associate commands with specific actions. The classification hooks embark provides allow you to easily
define actions which are useful for a wider range of contexts. But you can also define adhoc actions and actions which are specific to their
command by setting embark-overriding-keymap
. You can also use this variable to setup your own mappings for commands with custom actions by using something like this:
(defvar my-actions
(let ((map (make-sparse-keymap)))
(define-key map "d"
(defun example-action ()
(interactive)
(message "Do something with %s" (embark-target))))
map))
(defvar my-action-map-alist
'((example-command . my-actions)))
(add-hook 'minibuffer-setup-hook
(defun my-setup-actions ()
(when-let ((map (cdr (assoc this-command my-action-map-alist))))
(setq-local embark-overriding-keymap (symbol-value map)))))
(defun example-command ()
(interactive)
(completing-read "Check: " '("this" "out")))
Use the tab
key (change according to preference) to switch back and forth between the list of minibuffer candidates and the list of embark actions on the selected candidate, like in Helm. Works best with a completion system that shows candidates in a vertical list, like vertico
, selectrum
, icomplete-vertical
etc.
(defun with-minibuffer-keymap (keymap)
(lambda (fn &rest args)
(minibuffer-with-setup-hook
(lambda ()
(use-local-map
(make-composed-keymap keymap (current-local-map))))
(apply fn args))))
(defvar embark-completing-read-prompter-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "<tab>") 'abort-recursive-edit)
map))
(advice-add 'embark-completing-read-prompter :around
(with-minibuffer-keymap embark-completing-read-prompter-map))
(define-key vertico-map (kbd "<tab>") 'embark-act-with-completing-read)
(defun embark-act-with-completing-read (&optional arg)
(interactive "P")
(let* ((embark-prompter 'embark-completing-read-prompter)
(act (propertize "Act" 'face 'highlight))
(embark-indicator (lambda (_keymap targets) nil)))
(embark-act arg)))
Replace vertico-map
above with your completion system of choice's active minibuffer keymap. The default is minibuffer-local-completion-map
.
Similar to which-function-mode.
(defvar embark--target-mode-timer nil)
(defvar embark--target-mode-string "")
(defun embark--target-mode-update ()
(setq embark--target-mode-string
(if-let (targets (embark--targets))
(format "[%s%s] "
(propertize (symbol-name (caaar targets)) 'face 'bold)
(mapconcat (lambda (x) (format ", %s" (caar x)))
(cdr targets)
""))
"")))
(define-minor-mode embark-target-mode
"Shows the current targets in the modeline."
:global t
(setq mode-line-misc-info (assq-delete-all 'embark-target-mode mode-line-misc-info))
(when embark--target-mode-timer
(cancel-timer embark--target-mode-timer)
(setq embark--target-mode-timer nil))
(when embark-target-mode
(push '(embark-target-mode (:eval embark--target-mode-string)) mode-line-misc-info)
(setq embark--target-mode-timer
(run-with-idle-timer 0.1 t #'embark--target-mode-update))))
See also the Consult Wiki and the Vertico Wiki!