fix(corfu): move binds to :config default

Bindings were moved to the `:config default` module and some keys were
adjusted to match Company/other modules. The changes were documented in
the README.
This commit is contained in:
Luigi Sartor Piucco 2023-12-11 19:12:54 -03:00
parent b3bd325000
commit 14a3eaaa02
No known key found for this signature in database
GPG key ID: 6FF1A01853A47A66
5 changed files with 150 additions and 74 deletions

View file

@ -72,7 +72,7 @@ characters, or by means of the [[kbd:][C-SPC]] keybinding at any moment. While t
is visible, the following relevant keys are available:
| Keybind | Description |
|----------+------------------------------------------------------------------|
|----------+-----------------------------------------------------------|
| [[kbd:][<down>]] | Go to next candidate |
| [[kbd:][<up>]] | Go to previous candidate |
| [[kbd:][C-n]] | Go to next candidate |
@ -86,10 +86,9 @@ is visible, the following relevant keys are available:
| [[kbd:][C-S-j]] | (evil) Go to next doc line |
| [[kbd:][C-S-k]] | (evil) Go to previous doc line |
| [[kbd:][C-h]] | Toggle documentation (if available) |
| [[kbd:][M-m]] | Export to minibuffer (if [[doom-module::completion vertico]]) |
| [[kbd:][M-j]] | (evil) Export to minibuffer (if [[doom-module::completion vertico]]) |
| [[kbd:][C-S-s]] | Export to minibuffer (if [[doom-module::completion vertico]]) |
| [[kbd:][RET]] | Insert candidate |
| [[kbd:][SPC]] | Quit autocompletion after a wildcard or pass-through |
| [[kbd:][SPC]] | Quit autocompletion or pass-through after a wildcard |
| [[kbd:][C-SPC]] | Complete (unless [[doom-module::completion corfu +tng]]) |
| [[kbd:][C-SPC]] | (when completing) Insert separator DWIM (see below) |
@ -129,9 +128,42 @@ exported to a consult minibuffer, giving access to all the manipulations the
Vertico suite allows. For instance, one could use this to export with
[[doom-package:embark]] via [[kbd:][C-c C-l]] and get a buffer with all candidates.
** Manually call generic CAPFs
Completion at point functions have the property that, when called interactively
via their symbol, they work as a call to ~completion-at-point~ where
[[var:completion-at-point-functions]] is bound to that CAPF alone. This allows to
assign generic functions to a binding and call as needed, leaving the default
value used for most completion tasks much leaner (thus, faster and easier to
look through). This module provides some such bindings for Evil users (see the
table below), and you're free map your own of course. Emacs users have to map it
themselves for now, due to the author's lack of knowledge on ergonomic
equivalents to the Evil ones. If you have suggestions, though, we'd be happy to
know!
| Keybind | Description |
|---------+---------------------------------|
| [[kbd:][C-x]] [[kbd:][C-l]] | (insert-state) ~cape-line~ |
| [[kbd:][C-x]] [[kbd:][C-k]] | (insert-state) ~cape-keyword~ |
| [[kbd:][C-x]] [[kbd:][C-f]] | (insert-state) ~cape-file~ |
| [[kbd:][C-x]] [[kbd:][s]] | (insert-state) ~cape-dict~ |
| [[kbd:][C-x]] [[kbd:][C-s]] | (insert-state) ~yasnippet-capf~ |
| [[kbd:][C-x]] [[kbd:][C-n]] | (insert-state) ~cape-dabbrev~ |
| [[kbd:][C-x]] [[kbd:][C-p]] | (insert-state) ~cape-history~ |
* Configuration
A few variables may be set to change behavior of this module:
- [[var:completion-at-point-functions]] ::
This is not a module/package variable, but a builtin Emacs one. Even so, it's
very important to how Corfu works, so we document it here. It contains a list
of functions that are called in turn to generate completion candidates. The
regular (non-lexical) value should contain few entries and they should
generally be context aware, so as to predict what you need. Additional
functions can be added as you get into more and more specific contexts. Also,
there may be cases where you know beforehand the kind of candidate needed, and
want to enable only that one. For this, the variable may be lexically bound to
the correct value, or you may call the CAPF interactively if a single function
is all you need.
- [[var:corfu-auto-delay]] ::
Number of seconds till completion occurs automatically. Defaults to 0.1.
- [[var:corfu-auto-prefix]] ::
@ -158,6 +190,20 @@ To add other CAPFs on a mode-per-mode basis, put either of the following in your
see ~add-hook!~'s documentation for additional ways to call it. ~add-hook~ only
accepts the quoted arguments form above.
** Adding CAPFs to a key
To add other CAPFs to keys, adapt the snippet below into your ~config.el~:
#+begin_src emacs-lisp
;; For binding inside `corfu-mode-map'. Line 1 ensures the binding only exists
;; after some-mode-hook runs. Line 2 is needed only if the binding can't leak
;; into other Corfu buffers. When neither of the above make sense, the `map!'
;; call is enough.
(add-hook! some-mode ; Only needed if the binding is mode-specific
(make-local-variable 'corfu-mode-map)
(map! :map corfu-mode-map
:prefix "C-x" ; C-x is usually used as prefix, but it's not required
"e" #'cape-emoji)) ; Evil users probably want :i to avoid this in other states
#+end_src
* Troubleshooting
[[doom-report:][Report an issue?]]

View file

@ -32,17 +32,6 @@
tab-always-indent (if (modulep! +tng) 'complete tab-always-indent))
(add-to-list 'completion-category-overrides `(lsp-capf (styles ,@completion-styles)))
(map! :map corfu-mode-map
:e "C-M-i" #'completion-at-point
:i "C-SPC" #'completion-at-point
:n "C-SPC" (cmd! (call-interactively #'evil-insert-state)
(call-interactively #'completion-at-point))
:v "C-SPC" (cmd! (call-interactively #'evil-change)
(call-interactively #'completion-at-point)))
(map! :unless (modulep! :editor evil)
:map corfu-mode-map
"C-M-i" #'completion-at-point)
(add-hook! 'minibuffer-setup-hook
(defun +corfu-enable-in-minibuffer ()
"Enable Corfu in the minibuffer if `completion-at-point' is bound."
@ -56,32 +45,9 @@
(when (modulep! +icons)
(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
(let ((cmds-del (cmds! (and (modulep! +tng)
(> corfu--index -1)
(eq corfu-preview-current 'insert))
#'corfu-reset)))
(map! :map corfu-map
[return] #'corfu-insert
"RET" #'corfu-insert
(:when (modulep! +orderless)
"<remap> <completion-at-point>" #'+corfu-smart-sep-toggle-escape)
(:when (modulep! +tng)
[tab] #'corfu-next
[backtab] #'corfu-previous
"TAB" #'corfu-next
"S-TAB" #'corfu-previous
[backspace] cmds-del
"DEL" cmds-del)))
(when (modulep! +orderless)
(after! orderless
(setq orderless-component-separator #'orderless-escapable-split-on-space)))
(after! vertico
(map! :map corfu-map
"M-m" #'+corfu-move-to-minibuffer
(:when (modulep! :editor evil)
"M-J" #'+corfu-move-to-minibuffer))))
(setq orderless-component-separator #'orderless-escapable-split-on-space))))
(use-package! cape
:defer t
@ -175,16 +141,4 @@
(use-package! corfu-popupinfo
:hook ((corfu-mode . corfu-popupinfo-mode))
:config
(setq corfu-popupinfo-delay '(0.5 . 1.0))
(map! :map corfu-map
"C-<up>" #'corfu-popupinfo-scroll-down
"C-<down>" #'corfu-popupinfo-scroll-up
"C-S-p" #'corfu-popupinfo-scroll-down
"C-S-n" #'corfu-popupinfo-scroll-up
"C-h" #'corfu-popupinfo-toggle)
(map! :when (modulep! :editor evil)
:map corfu-popupinfo-map
;; Reversed because popupinfo assumes opposite of what feels intuitive
;; with evil.
"C-S-k" #'corfu-popupinfo-scroll-down
"C-S-j" #'corfu-popupinfo-scroll-up))
(setq corfu-popupinfo-delay '(0.5 . 1.0)))

View file

@ -511,7 +511,7 @@
"C-x C-b" #'ibuffer
"C-x K" #'doom/kill-this-buffer-in-all-windows
;;; company-mode
;;; completion (in-buffer)
(:when (modulep! :completion company)
"C-;" #'+company/complete
(:after company
@ -537,6 +537,13 @@
"C-p" #'company-search-repeat-backward
"C-s" (cmd! (company-search-abort) (company-filter-candidates))))
(:when (modulep! :completion corfu)
:after corfu
(:map corfu-mode-map
"C-M-i" #'completion-at-point)
(:map corfu-popupinfo-map
"C-S-h" #'corfu-popupinfo-toggle))
;;; ein notebooks
(:after ein:notebook-multilang
:map ein:notebook-multilang-mode-map

View file

@ -43,7 +43,10 @@
#'yas-expand
(and (bound-and-true-p company-mode)
(modulep! :completion company +tng))
#'company-indent-or-complete-common)
#'company-indent-or-complete-common
(and (bound-and-true-p corfu-mode)
(modulep! :completion corfu +tng))
#'completion-at-point)
:m [tab] (cmds! (and (modulep! :editor snippets)
(evil-visual-state-p)
(or (eq evil-visual-selection 'line)
@ -127,7 +130,7 @@
;;
;;; Module keybinds
;;; :completion
;;; :completion (in-buffer)
(map! (:when (modulep! :completion company)
:i "C-@" (cmds! (not (minibufferp)) #'company-complete-common)
:i "C-SPC" (cmds! (not (minibufferp)) #'company-complete-common)
@ -156,7 +159,39 @@
"C-s" #'company-filter-candidates
[escape] #'company-search-abort)))
(:when (modulep! :completion ivy)
(:when (modulep! :completion corfu)
(:after corfu
(:map corfu-mode-map
:e "C-M-i" #'completion-at-point
(:prefix "C-x"
:i "C-l" #'cape-line
:i "C-k" #'cape-keyword
:i "C-f" #'cape-file
:i "s" #'cape-dict
:i "C-s" #'yasnippet-capf
:i "C-n" #'cape-dabbrev
:i "C-p" #'cape-history)
(:unless (modulep! :completion corfu +tng)
:i "C-SPC" #'completion-at-point
:n "C-SPC" (cmd! (call-interactively #'evil-insert-state)
(call-interactively #'completion-at-point))
:v "C-SPC" (cmd! (call-interactively #'evil-change)
(call-interactively #'completion-at-point))))
(:map corfu-map
"C-u" (cmd! (let (corfu-cycle)
(funcall-interactively #'corfu-next (- corfu-count))))
"C-d" (cmd! (let (corfu-cycle)
(funcall-interactively #'corfu-next corfu-count)))))
(:after corfu-popupinfo
:map corfu-popupinfo-map
;; Reversed because popupinfo assumes opposite of what feels intuitive
;; with evil.
"C-S-k" #'corfu-popupinfo-scroll-down
"C-S-j" #'corfu-popupinfo-scroll-up
"C-h" #'corfu-popupinfo-toggle)))
;;; :completion (separate)
(map! (:when (modulep! :completion ivy)
(:after ivy
:map ivy-minibuffer-map
"C-SPC" #'ivy-call-and-recenter ; preview file
@ -169,7 +204,8 @@
[C-return] #'+ivy/git-grep-other-window-action))
(:when (modulep! :completion helm)
(:after helm :map helm-map
(:after helm
:map helm-map
[remap next-line] #'helm-next-line
[remap previous-line] #'helm-previous-line
[left] #'left-char

View file

@ -458,6 +458,39 @@ Continues comments if executed from a commented line. Consults
'(evil-ex-completion-map)))
"C-s" command))
(map! :when (modulep! :completion corfu)
:after corfu
(:map corfu-map
[return] #'corfu-insert
"RET" #'corfu-insert
"C-S-s" #'+corfu-move-to-minibuffer
"C-p" #'corfu-previous
"C-n" #'corfu-next
(:when (modulep! :completion corfu +orderless)
[remap completion-at-point] #'+corfu-smart-sep-toggle-escape)
(:when (modulep! :completion corfu +tng)
[tab] #'corfu-next
"TAB" #'corfu-next
[backtab] #'corfu-previous
"S-TAB" #'corfu-previous))
(:after corfu-popupinfo
:map corfu-popupinfo-map
"C-<up>" #'corfu-popupinfo-scroll-down
"C-<down>" #'corfu-popupinfo-scroll-up
"C-S-p" #'corfu-popupinfo-scroll-down
"C-S-n" #'corfu-popupinfo-scroll-up
"C-S-u" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-down corfu-popupinfo-min-height))
"C-S-d" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-up corfu-popupinfo-min-height))))
(when-let ((cmds-del (and (modulep! :completion corfu +tng)
'(menu-item "Reset completion" corfu-reset
:enable (and (> corfu--index -1)
(eq corfu-preview-current 'insert))))))
(map! :after corfu
:map corfu-map
[backspace] cmds-del
"DEL" cmds-del))
;; Smarter C-a/C-e for both Emacs and Evil. C-a will jump to indentation.
;; Pressing it again will send you to the true bol. Same goes for C-e, except
;; it will ignore comments+trailing whitespace before jumping to eol.