-
Notifications
You must be signed in to change notification settings - Fork 33
Additional Configuration
This page lists examples of additional configuration that might be useful with selectrum.
Examples which show how to integrate selectrum with other packages only present the basic configuration needed to make use of them. You will need to look at the respective projects READMEs to checkout their other configuration options.
Completion commands can bind minibuffer-default-add-function
to control which candidates a user gets offered when pressing M-n
. A good default is to offer the symbol or file name that where a point before entering the minibuffer:
(autoload 'ffap-guesser "ffap")
(setq minibuffer-default-add-function
(defun minibuffer-default-add-function+ ()
(with-selected-window (minibuffer-selected-window)
(delete-dups
(delq nil
(list (thing-at-point 'symbol)
(thing-at-point 'list)
(ffap-guesser)
(thing-at-point-url-at-point)))))))
When completing file names in shell/comint selectrum gives you the same interface as you get for find-file
. This means the completion does not exit after one path level like with other frameworks and you can conveniently navigate to the path you are interested in. If you want to be able to get this file completion mechanism globally you can use the following:
(autoload 'ffap-file-at-point "ffap")
(add-hook 'completion-at-point-functions
(defun complete-path-at-point+ ()
(let ((fn (ffap-file-at-point))
(fap (thing-at-point 'filename)))
(when (and (or fn
(equal "/" fap))
(save-excursion
(search-backward fap (line-beginning-position) t)))
(list (match-beginning 0)
(match-end 0)
#'completion-file-name-table)))) 'append)
With the above you can call the command completion-at-point
to get file completion with the point after a path name. See also the option tab-always-indent
.
The built-in file-name-shadow-mode
works with selectrum out of the box. For example if you want to use it to hide shadowed pathes you can use the following:
(setq file-name-shadow-properties
'(invisible t))
Sorting for M-x with amx
NOTE: It is recommend to use Prescient instead.
(setq amx-backend 'selectrum)
Filtering with orderless
Selectrum does support completion-styles
so when you configured them for orderless
filtering and highlighting is done by it already:
(setq completion-styles '(orderless))
However completion-styles
do filter and highlight in a single step, the approach of Selectrum to only highlight the actually displayed candidates is more efficient so it is recommended to also configure:
(setq orderless-skip-highlighting (lambda () selectrum-is-active))
(setq selectrum-highlight-candidates-function #'orderless-highlight-matches)
If you only want to sort with prescient you can omit calling selectrum-prescient-mode
and use:
(setq selectrum-prescient-enable-filtering nil)
Minibuffer-actions with embark
Embark now works out of the box with Selectrum. All you need to do is bind embark commands like embark-act
in minibuffer-local-map
, since Embark commands are not Selectrum-specific. Note that you might want to bind embark-act
even globally since it provides general context sensitive actions. For available commands and other embark configurations see the embark documentation and its wiki.
Correcting spelling errors with flyspell-correct
The default interface (flyspell-correct-completing-read
), already works with Selectrum. To ensure that you are using the default interface, you can do
(setq flyspell-correct-interface #'flyspell-correct-completing-read)
When flyspell-correct
provides candidates to completing-read
, it appends alternative actions ([SAVE]
, [ACCEPT (session)]
, [ACCEPT (buffer)]
, and [SKIP]
) to the list of possible spelling corrections. As of 2020 August 28, flyspell-correct-dummy
no longer allows these candidates to be sorted (meaning that the actions are now always at the end of the candidate list). If you are using an older version, you can achieve the same effect by advising flyspell-correct-dummy
like below.
;; Not needed for newer versions of `flyspell-correct'.
(advice-add 'flyspell-correct-dummy :around
(defun my--fsc-wrapper (func &rest args)
(let ((selectrum-should-sort nil))
(apply func args))))
Working with projects in projectile
NOTE: Since 2020-11-21 projectile auto-detects the active completion system. Therefore no additional configuration is necessary for Selectrum.
Display minibuffer in a child frame with mini-frame
Make sure you have
(mini-frame-mode +1)
;; Make sure you don't override the display action:
; (setq selectrum-display-action nil)
to enable mini-frame support. With more recent Emacs versions (27.2 and above), selectrum will use a mini-frame automatically when you don't have a custom selectrum-display-action
defined.
For older versions, you may also need the following fix, see #169:
;; workaround bug#44080, should be fixed in version 27.2 and above, see #169
(define-advice fit-frame-to-buffer (:around (f &rest args) dont-skip-ws-for-mini-frame)
(cl-letf* ((orig (symbol-function #'window-text-pixel-size))
((symbol-function #'window-text-pixel-size)
(lambda (win from to &rest args)
(apply orig
(append (list win from
(if (and (window-minibuffer-p win)
(frame-root-window-p win)
(eq t to))
nil
to))
args)))))
(apply f args)))
;; If you are using Gnome there are issues with dynamic resize set by `mini-frame-resize`:
;; https://github.com/muffinmad/emacs-mini-frame/commit/bac8ab2a1be8e1b2959f3d40ffa714cdf3c49a01
;; The following setting will fix that:
(setq x-gtk-resize-child-frames 'resize-mode) ; only for Gnome users
To use mini-frame for display at point you can make use of posframe handlers position calculation:
(setq mini-frame-show-parameters
(lambda ()
(let* ((info (posframe-poshandler-argbuilder))
(posn (posframe-poshandler-point-bottom-left-corner info))
(left (car posn))
(top (cdr posn)))
`((left . ,left)
(top . ,top)))))
Display candidates in a posframe
A simple example to show the use of posframes with selectrum-display-action
:
(setq selectrum-display-action '(display-buffer-show-in-posframe))
(defun display-buffer-show-in-posframe (buffer _alist)
(frame-root-window
(posframe-show buffer
:min-height 10
:min-width (frame-width)
:internal-border-width 1
:left-fringe 8
:right-fringe 8
:poshandler 'posframe-poshandler-frame-bottom-left-corner)))
(add-hook 'minibuffer-exit-hook 'posframe-delete-all)
Completion with magit
Without explicitly setting this the candidates won't be sorted with prescient if you have it enabled.
(setq magit-completing-read-function #'selectrum-completing-read)
See below for alternative approach.
(define-advice magit-list-refs (:around (orig &optional namespaces format sortby)
prescient-sort)
"Apply prescient sorting when listing refs."
(let ((res (funcall orig namespaces format sortby)))
(if (or sortby
magit-list-refs-sortby
(not selectrum-should-sort))
res
(prescient-sort res))))
Handle complete-symbol
with SLIME
SLIME is old enough that it doesn't obey the completion-in-region-function
API, this doesn't matter with company (see slime-company) but normally it won't use selectrum for completions. To fix this, use the following advice:
(advice-add 'slime-display-or-scroll-completions :around
(defun my--slime-completion-in-region (_ completions start end)
(completion-in-region start end completions)))
NOTE: This command is provided by Consult, see consult-multi-occur.
multi-occur
reads a list of buffers to search in. Unfortunately the default Emacs implementation does not interact well with selectrum, since it does not use completing-read-multiple
. Instead it reads each buffer separately.
By overwriting the default multi-occur
, this issue can be fixed:
(defun multi-occur (bufs regexp &optional nlines)
(interactive (cons
(mapcar #'get-buffer
(completing-read-multiple "Buffer: "
#'internal-complete-buffer))
(occur-read-primary-args)))
(occur-1 regexp nlines bufs))