Skip to content

Super-Capf - Merging multiple Capfs

Throw multiple Capfs under the Cape and get a Super-Capf!

Cape supports merging multiple Capfs using the function cape-capf-super. Due to technical details, not all Capfs can be merged successfully. Try to merge Capfs one by one and make sure that you get the desired outcome.

Note that cape-capf-super is not needed if multiple Capfs should be tried one after another, for example you can use cape-file together with programming mode Capfs by adding cape-file to the completion-at-point-functions list. File completion will then be available in comments and string literals, but not in normal code. cape-capf-super is only necessary if you want to combine multiple Capfs, such that the candidates from multiple sources appear together in the completion list at the same time.

Capf merging requires completion functions which are sufficiently well-behaved and completion functions which do not define completion boundaries. cape-capf-super has the same restrictions as completion-table-merge and completion-table-in-turn. As a simple rule of thumb, cape-capf-super works for static completion functions like cape-dabbrev, cape-keyword, cape-dict, etc., but not for multi-step completions like cape-file.

The results returned by the individual Capfs are listed after each other, where the the order of the completion candidates is preserved. In order to override this sorting behavior use cape-capf-sort, such that the completion UI can apply its own sorting.

emacs-lisp
;; Merge the dabbrev, dict and keyword capfs, display candidates together.
(setq-local completion-at-point-functions
            (list (cape-capf-super #'cape-dabbrev #'cape-dict)))

;; Let the UI (e.g. Corfu) sort the candidates by overriding the sort function.
(setq-local completion-at-point-functions
            (list (cape-capf-sort (cape-capf-super #'cape-dabbrev #'cape-dict))))

;; Trigger completion only after trigger character.
(setq-local corfu-auto-trigger "/"
            completion-at-point-functions
            (list (cape-capf-trigger (cape-capf-super #'cape-abbrev #'tempel-complete) ?/)))

;; Define named Capf instead of using the anonymous Capf directly.
(defun cape-dabbrev-dict ()
  (cape-wrap-super #'cape-dabbrev #'cape-dict))
(setq-local completion-at-point-functions (list #'cape-dabbrev-dict))

If you want to merge multiple Company backends, use the aforementioned company--multi-backend-adapter from Company. In order to combine multiple Capfs, such that each of the Capfs is tried one after another, use cape-capf-choose.