Skip to content

Capf transformers

Wrap one or multiple Capfs in a Cape to get a Capf of different flavor!

Cape provides a set of additional Capf transformation functions, which are mostly meant to used by experts to fine tune the Capf behavior and Capf interaction. These can either be used as advices (‘cape-wrap-*)’ or to create a new Capf from an existing Capf (‘cape-capf-*’). You can bind the Capfs created by the Capf transformers with ‘defalias’ to a function symbol.

In the following we show a few example configurations, which have come up on the Cape or Corfu issue tracker or the Corfu wiki. I use some of these tweaks in my personal configuration.

emacs-lisp
;; Example 1: Configure a merged Capf with a trigger prefix character.
(setq-local corfu-auto-trigger "/"
            completion-at-point-functions
            (list (cape-capf-trigger (cape-capf-super #'cape-abbrev #'tempel-complete) ?/)))

;; Example 2: Configure a Capf with a specific auto completion prefix length.
(setq-local completion-at-point-functions
            (list (cape-capf-prefix-length #'cape-dabbrev 2)))

;; Example 3: Create a Capf with debugging messages.
(setq-local completion-at-point-functions (list (cape-capf-debug #'cape-dict)))

;; Example 4: Named Capf.
(defalias 'cape-dabbrev-min-2 (cape-capf-prefix-length #'cape-dabbrev 2))
(setq-local completion-at-point-functions (list #'cape-dabbrev-min-2))

;; Example 5: Define a defensive Dabbrev Capf, which accepts all inputs.  If you
;; use Corfu and `corfu-auto=t', the first candidate won't be auto selected if
;; `corfu-preselect=valid', such that it cannot be accidentally committed when
;; pressing RET.
(defun my-cape-dabbrev-accept-all ()
  (cape-wrap-accept-all #'cape-dabbrev))
(add-hook 'completion-at-point-functions #'my-cape-dabbrev-accept-all)

;; Example 6: Define interactive Capf which can be bound to a key.  Here we wrap
;; the `elisp-completion-at-point' such that we can complete Elisp code
;; explicitly in arbitrary buffers.
(keymap-global-set "C-c p e" (cape-capf-interactive #'elisp-completion-at-point))

;; Example 7: Ignore :keywords in Elisp completion.
(defun ignore-elisp-keywords (sym)
  (not (keywordp sym)))
(setq-local completion-at-point-functions
            (list (cape-capf-predicate #'elisp-completion-at-point
                                       #'ignore-elisp-keywords)))

;; Example 8: Catch errors with `cape-wrap-silent'.
(advice-add 'dabbrev-capf :around #'cape-wrap-silent) ;; Was necessary on Emacs 30
(advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent) ;; Was necessary on Emacs 28