dev: merge branch 'pr7002' into emenel

This commit is contained in:
Matt Nish-Lapidus 2024-03-04 09:48:38 -05:00
commit afe9fa896f
5 changed files with 143 additions and 82 deletions

View file

@ -25,9 +25,7 @@ and highly non-native, but has some extra features and more maturity.
- +dabbrev ::
Enable and configure [[doom-package:dabbrev]] as a close-to-universal CAPF
fallback.
- +individual ::
Add bindings for specific CAPFs under the [[kbd:][C-x]] prefix.
- +on-type +on-ret +on-ret-pt +direction +tab ::
- +on-ret +on-ret-pt ::
Enable corresponding completion-style features. See [[*Usage]].
** Packages
@ -64,9 +62,8 @@ words. Snippets may also appear in the candidate list if available.
** Code completion
By default, completion gets triggered after typing 2 non-space consecutive
characters, by means of [[kbd:][C-SPC]] at any moment or [[kbd:][TAB]] on a line with proper
indentation. Many styles of completion are offered, which can be composed with
module flags to suit the user; they are described in subsections. The following
keybindings are generally available:
indentation. Many styles of completion are documented below, which can be
composed to suit the user. The following keybindings are generally available:
| Keybind | Description |
|---------+---------------------------------------------|
@ -84,17 +81,30 @@ keybindings are generally available:
| [[kbd:][C-SPC]] | (when not completing) Complete |
| [[kbd:][C-M-i]] | (emacs) (when not completing) Complete |
Bindings in the following sections are additive, and get enabled by the
corresponding module flags. Additionally, for users of evil [[kdb:][C-SPC]] is smart
regarding your state. In normal-like states, enter insert then start corfu; in
visual-like states, perform [[help:evil-change][evil-change]] (which leaves you in insert state) then
start corfu; in insert-like states, start corfu immediatelly.
Bindings in the following sections are additive, and get enabled by including
the corresponding ~config.el~ snippets or via flags. Additionally, for users of
evil, [[kdb:][C-SPC]] is smart regarding your state. In normal-like states, enter insert
then start corfu; in visual-like states, perform [[help:evil-change][evil-change]] (which leaves you
in insert state) then start corfu; in insert-like states, start corfu
immediatelly.
** Commit on type (~+on-type~)
When the completion popup is visible and the current candidate is previewed into
the buffer, further input commits that candidate as previewed. Note it does not
perform candidate exit actions, such as expanding snippets. This is intended for
people who prefer to leave [[kbd:][RET]] free.
** Commit preview on type
When the completion popup is visible, by default the current candidate is
previewed into the buffer, and further input commits that candidate as previewed
(note it does not perform candidate exit actions, such as expanding snippets).
If neither ~+on-ret~ or ~+on-ret-pt~ are enabled, this becomes the only default
way to commit a candidate ([[kbd:][RET]] is unbound in that case).
The feature is in line with other common editors, but if you prefer the preview
to be only visual or for there to be no preview, configure
[[var:corfu-preview-current]].
#+begin_src emacs-lisp
;; Non-inserting preview
(setq corfu-preview-current t)
;; No preview
(setq corfu-preview-current nil)
#+end_src
** Commit on [[kbd:][RET]] (~+on-ret~)
Some people prefer to use [[kbd:][RET]] to commit, so here we bind it to Corfu's insertion
@ -120,9 +130,10 @@ first candidate from the start prevents the pass-through.
|---------+-------------------------------------------|
| [[kbd:][RET]] | Insert candidate or quit and pass-through |
** Cycle directionally (~+direction~)
If you'd rather think in directions rather than next/previous, enable arrow keys
and vi movements to control the selection and documentation view.
** Cycle directionally
If you'd rather think in directions rather than next/previous, arrow keys and vi
movements to control the selection and documentation view are bound by default.
A snippet to unbind them is included after the table.
| Keybind | Description |
|----------+---------------------------------|
@ -135,14 +146,41 @@ and vi movements to control the selection and documentation view.
| [[kbd:][C-S-j]] | (evil) Go to next doc line |
| [[kbd:][C-S-k]] | (evil) Go to previous doc line |
** Cycle with [[kbd:][TAB]] (~+tab~)
Binds [[kbd:][TAB]]-based cycling alternatives.
#+begin_src emacs-lisp
(map! (:after corfu
:map corfu-map
"<up>" nil
"<down>" nil
;; Evil
"C-k" nil
"C-j" nil)
(:after corfu-popupinfo
:map corfu-popupinfo-map
"C-<up>" nil
"C-<down>" nil
;; Evil
"C-S-k" nil
"C-S-j" nil))
#+end_src
** Cycle with [[kbd:][TAB]]
You may wish to bind the following [[kbd:][TAB]]-based cycling alternatives with the
snippet below the table:
| Keybind | Description |
|---------+--------------------------|
| [[kbd:][TAB]] | Go to next candidate |
| [[kbd:][S-TAB]] | Go to previous candidate |
#+begin_src emacs-lisp
(map! :after corfu
:map corfu-map
[tab] #'corfu-next
"TAB" #'corfu-next
[backtab] #'corfu-previous
"S-TAB" #'corfu-previous)
#+end_src
** Searching with multiple keywords (~+orderless~)
If the [[doom-module::completion corfu +orderless]] flag is enabled, users can
perform code completion with multiple search keywords by use of space as the
@ -157,28 +195,49 @@ already escaped separator before point deletes it. Thus, you can cycle back if
you accidentaly press more than needed.
| Keybind | Description |
|---------+------------------------------------------------------|
| [[kbd:][C-SPC]] | (when completing) Insert separator DWIM |
| [[kbd:][SPC]] | Quit autocompletion or insert space after a wildcard |
|---------+-------------------------------------------------|
| [[kbd:][C-SPC]] | (evil) (when completing) Insert separator DWIM |
| [[kbd:][M-SPC]] | (emacs) (when completing) Insert separator DWIM |
| [[kbd:][SPC]] | (when completing) Quit autocompletion |
| [[kbd:][SPC]] | (when completing with separators) Self-insert |
** Manually call generic CAPFs (~+individual~)
** 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 those who enable the
~+individual~ module flag. They are listed below:
look through). As an example, set the these binds with the following snippet:
| 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~ |
|---------+------------------|
| [[kbd:][C-x]] [[kbd:][C-l]] | ~cape-line~ |
| [[kbd:][C-x]] [[kbd:][C-k]] | ~cape-keyword~ |
| [[kbd:][C-x]] [[kbd:][C-f]] | ~cape-file~ |
| [[kbd:][C-x]] [[kbd:][s]] | ~cape-dict~ |
| [[kbd:][C-x]] [[kbd:][C-s]] | ~yasnippet-capf~ |
| [[kbd:][C-x]] [[kbd:][C-n]] | ~cape-dabbrev~ |
| [[kbd:][C-x]] [[kbd:][C-p]] | ~cape-history~ |
#+begin_src emacs-lisp
;; `corfu-mode-map' is not tied to the popup being visible, whereas `corfu-map'
;; is only active while completing.
(map! :map corfu-mode-map
:prefix "C-x"
"C-l" #'cape-line
"C-k" #'cape-keyword
"C-f" #'cape-file
"s" #'cape-dict
"C-s" #'yasnippet-capf
"C-n" #'cape-dabbrev
"C-p" #'cape-history)
#+end_src
** Exporting to the minibuffer
The entries shown in the completion popup can be exported to another
~completion-in-region~ minibuffer, giving access to all the manipulations those
suites allow. Using Vertico 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.
** Exporting to the minibuffer
The entries shown in the completion popup can be exported to another
@ -209,6 +268,8 @@ A few variables may be set to change behavior of this module:
- [[var:corfu-preselect]] ::
Configures startup selection, choosing between the first candidate or the
prompt.
- [[var:corfu-preview-current]] ::
Configures current candidate preview.
- [[var:+corfu-buffer-scanning-size-limit]] ::
Sets the maximum buffer size to be scanned by ~cape-dabbrev~. Defaults to 1
MB. Set this if you are having performance problems using the CAPF.
@ -230,6 +291,30 @@ 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.
For programming modes where you want a CAPF to be active only in documentation
and comments, define the following function and use it as a Cape predicate. It
fixes the issue Cape's implementation has with tree-sitter.
#+begin_src emacs-lisp
;;;###autoload
(defun +corfu-in-doc-or-comment-p (&optional _sym)
"Return non-nil if point is in a docstring or comment."
(or (nth 4 (syntax-ppss))
(when-let ((faces '(font-lock-comment-face
font-lock-doc-face
tree-sitter-hl-face:doc
tree-sitter-hl-face:comment))
(fs (get-text-property (point) 'face)))
(if (listp fs)
(cl-loop for f in fs
if (memq f faces)
return t)
(memq fs faces)))))
;; Use this as #'some-capf above
(cape-capf-predicate #'another-capf #'+corfu-in-doc-or-comment-p)
#+end_src
** Adding CAPFs to a key
To add other CAPFs to keys, adapt the snippet below into your ~config.el~:
#+begin_src emacs-lisp

View file

@ -38,21 +38,4 @@
(save-excursion (backward-char 1)
(insert-char ?\\)))
(t
;; Without this corfu quits immediately.
(setq this-command #'corfu-insert-separator)
(call-interactively #'corfu-insert-separator))))
;;;###autoload
(defun +corfu-in-doc-or-comment-p (_sym)
"Return non-nil if point is in a docstring or comment."
(or (nth 4 (syntax-ppss))
(when-let ((faces '(font-lock-comment-face
font-lock-doc-face
tree-sitter-hl-face:doc
tree-sitter-hl-face:comment))
(fs (get-text-property (point) 'face)))
(if (listp fs)
(cl-loop for f in fs
if (memq f faces)
return t)
(memq fs faces)))))

View file

@ -58,6 +58,7 @@ use the minibuffer such as `query-replace'.")
(add-to-list 'completion-category-overrides `(lsp-capf (styles ,@completion-styles)))
(add-to-list 'corfu-auto-commands #'lispy-colon)
(add-to-list 'corfu-continue-commands #'+corfu-move-to-minibuffer)
(add-to-list 'corfu-continue-commands #'+corfu-smart-sep-toggle-escape)
(add-hook 'evil-insert-state-exit-hook #'corfu-quit)
(when (modulep! +icons)

View file

@ -162,26 +162,32 @@
(:when (modulep! :completion corfu)
(:after corfu
(:map corfu-mode-map
:e "C-M-i" #'completion-at-point
(: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))))
(call-interactively #'completion-at-point)))
(:map corfu-map
"C-SPC" #'corfu-insert-separator
"C-k" #'corfu-previous
"C-j" #'corfu-next
"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
"C-h" #'corfu-popupinfo-toggle
;; Reversed because popupinfo assumes opposite of what feels intuitive
;; with evil.
(:when (modulep! :completion corfu +direction)
"C-S-k" #'corfu-popupinfo-scroll-down
"C-S-j" #'corfu-popupinfo-scroll-up)
"C-h" #'corfu-popupinfo-toggle)))
"C-S-j" #'corfu-popupinfo-scroll-up
"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)))))
;;; :completion (separate)
(map! (:when (modulep! :completion ivy)

View file

@ -475,21 +475,7 @@ Continues comments if executed from a commented line. Consults
"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 +tab)
:gi [tab] #'corfu-next
:gi "TAB" #'corfu-next
:gi [backtab] #'corfu-previous
:gi "S-TAB" #'corfu-previous))
(:after corfu-popupinfo
:map corfu-popupinfo-map
(:when (modulep! :completion corfu +direction)
"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))))
[remap corfu-insert-separator] #'+corfu-smart-sep-toggle-escape)))
(when-let ((cmds-del
`(menu-item "Reset completion" corfu-reset
:filter ,(lambda (cmd)
@ -517,8 +503,8 @@ Continues comments if executed from a commented line. Consults
:gi "RET" cmds-ret-pt)
(:unless (or (modulep! :completion corfu +on-ret)
(modulep! :completion corfu +on-ret-pt))
[return] nil
"RET" nil)))
:gi [return] nil
:gi "RET" nil)))
;; 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