Skip to content

Additional Configuration

Clemens Radermacher edited this page Oct 28, 2020 · 76 revisions

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.

Configuration for built-ins

Minibuffer default add function

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)))))))

Complete file names 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.

Shadowed pathes with file-name-shadow-mode

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))

Configuration for external packages

Sorting for M-x with amx

(setq amx-backend 'selectrum)

Filtering with orderless

(setq selectrum-refine-candidates-function #'orderless-filter)
(setq selectrum-highlight-candidates-function #'orderless-highlight-matches)
;; orderless isn't well suited for initial gathering of candidates by completion in region 
;; so you might want to add an advice to use other completion-styles to get a more accurate initial candidate set
(advice-add #'completion--category-override :filter-return
            (defun completion-in-region-style-setup+ (res)
              "Fallback to default styles for region completions with orderless."
              (or res
                  ;; Don't use orderless for initial candidate gathering.
                  (and completion-in-region-mode-predicate
                       (not (minibufferp))
                       (equal '(orderless) completion-styles)
                       '(basic partial-completion emacs22)))))

Correcting spelling errors with flyspell-correct

The default interface (flyspell-correct-dummy), already works with Selectrum. To ensure that you are using the default interface, you can do

(setq flyspell-correct-interface #'flyspell-correct-dummy)

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-p nil))
                  (apply func args))))

Working with projects in projectile

By default, Projectile uses Ido. To use completing-read instead, do

(setq projectile-completion-system 'default)

Display minibuffer in a child frame with mini-frame

;; 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)))

;; After configuring `mini-frame-show-parameters` adjust the height according to number of candidates 
(setf (alist-get
       'height mini-frame-show-parameters)
      (1+ selectrum-num-candidates-displayed))

Handle completion order for refs in magit with prescient

(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-p))
            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)))
Clone this wiki locally