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 :: - +dabbrev ::
Enable and configure [[doom-package:dabbrev]] as a close-to-universal CAPF Enable and configure [[doom-package:dabbrev]] as a close-to-universal CAPF
fallback. fallback.
- +individual :: - +on-ret +on-ret-pt ::
Add bindings for specific CAPFs under the [[kbd:][C-x]] prefix.
- +on-type +on-ret +on-ret-pt +direction +tab ::
Enable corresponding completion-style features. See [[*Usage]]. Enable corresponding completion-style features. See [[*Usage]].
** Packages ** Packages
@ -64,9 +62,8 @@ words. Snippets may also appear in the candidate list if available.
** Code completion ** Code completion
By default, completion gets triggered after typing 2 non-space consecutive 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 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 indentation. Many styles of completion are documented below, which can be
module flags to suit the user; they are described in subsections. The following composed to suit the user. The following keybindings are generally available:
keybindings are generally available:
| Keybind | Description | | Keybind | Description |
|---------+---------------------------------------------| |---------+---------------------------------------------|
@ -84,17 +81,30 @@ keybindings are generally available:
| [[kbd:][C-SPC]] | (when not completing) Complete | | [[kbd:][C-SPC]] | (when not completing) Complete |
| [[kbd:][C-M-i]] | (emacs) (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 Bindings in the following sections are additive, and get enabled by including
corresponding module flags. Additionally, for users of evil [[kdb:][C-SPC]] is smart the corresponding ~config.el~ snippets or via flags. Additionally, for users of
regarding your state. In normal-like states, enter insert then start corfu; in evil, [[kdb:][C-SPC]] is smart regarding your state. In normal-like states, enter insert
visual-like states, perform [[help:evil-change][evil-change]] (which leaves you in insert state) then then start corfu; in visual-like states, perform [[help:evil-change][evil-change]] (which leaves you
start corfu; in insert-like states, start corfu immediatelly. in insert state) then start corfu; in insert-like states, start corfu
immediatelly.
** Commit on type (~+on-type~) ** Commit preview on type
When the completion popup is visible and the current candidate is previewed into When the completion popup is visible, by default the current candidate is
the buffer, further input commits that candidate as previewed. Note it does not previewed into the buffer, and further input commits that candidate as previewed
perform candidate exit actions, such as expanding snippets. This is intended for (note it does not perform candidate exit actions, such as expanding snippets).
people who prefer to leave [[kbd:][RET]] free. 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~) ** Commit on [[kbd:][RET]] (~+on-ret~)
Some people prefer to use [[kbd:][RET]] to commit, so here we bind it to Corfu's insertion 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 | | [[kbd:][RET]] | Insert candidate or quit and pass-through |
** Cycle directionally (~+direction~) ** Cycle directionally
If you'd rather think in directions rather than next/previous, enable arrow keys If you'd rather think in directions rather than next/previous, arrow keys and vi
and vi movements to control the selection and documentation view. movements to control the selection and documentation view are bound by default.
A snippet to unbind them is included after the table.
| Keybind | Description | | 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-j]] | (evil) Go to next doc line |
| [[kbd:][C-S-k]] | (evil) Go to previous doc line | | [[kbd:][C-S-k]] | (evil) Go to previous doc line |
** Cycle with [[kbd:][TAB]] (~+tab~) #+begin_src emacs-lisp
Binds [[kbd:][TAB]]-based cycling alternatives. (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 | | Keybind | Description |
|---------+--------------------------| |---------+--------------------------|
| [[kbd:][TAB]] | Go to next candidate | | [[kbd:][TAB]] | Go to next candidate |
| [[kbd:][S-TAB]] | Go to previous 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~) ** Searching with multiple keywords (~+orderless~)
If the [[doom-module::completion corfu +orderless]] flag is enabled, users can 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 perform code completion with multiple search keywords by use of space as the
@ -156,29 +194,50 @@ backslash, including the space in the search term, and pressing it with an
already escaped separator before point deletes it. Thus, you can cycle back if already escaped separator before point deletes it. Thus, you can cycle back if
you accidentaly press more than needed. you accidentaly press more than needed.
| Keybind | Description | | Keybind | Description |
|---------+------------------------------------------------------| |---------+-------------------------------------------------|
| [[kbd:][C-SPC]] | (when completing) Insert separator DWIM | | [[kbd:][C-SPC]] | (evil) (when completing) Insert separator DWIM |
| [[kbd:][SPC]] | Quit autocompletion or insert space after a wildcard | | [[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 Completion at point functions have the property that, when called interactively
via their symbol, they work as a call to ~completion-at-point~ where 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 [[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 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 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 look through). As an example, set the these binds with the following snippet:
~+individual~ module flag. They are listed below:
| Keybind | Description | | Keybind | Description |
|---------+---------------------------------| |---------+------------------|
| [[kbd:][C-x]] [[kbd:][C-l]] | (insert-state) ~cape-line~ | | [[kbd:][C-x]] [[kbd:][C-l]] | ~cape-line~ |
| [[kbd:][C-x]] [[kbd:][C-k]] | (insert-state) ~cape-keyword~ | | [[kbd:][C-x]] [[kbd:][C-k]] | ~cape-keyword~ |
| [[kbd:][C-x]] [[kbd:][C-f]] | (insert-state) ~cape-file~ | | [[kbd:][C-x]] [[kbd:][C-f]] | ~cape-file~ |
| [[kbd:][C-x]] [[kbd:][s]] | (insert-state) ~cape-dict~ | | [[kbd:][C-x]] [[kbd:][s]] | ~cape-dict~ |
| [[kbd:][C-x]] [[kbd:][C-s]] | (insert-state) ~yasnippet-capf~ | | [[kbd:][C-x]] [[kbd:][C-s]] | ~yasnippet-capf~ |
| [[kbd:][C-x]] [[kbd:][C-n]] | (insert-state) ~cape-dabbrev~ | | [[kbd:][C-x]] [[kbd:][C-n]] | ~cape-dabbrev~ |
| [[kbd:][C-x]] [[kbd:][C-p]] | (insert-state) ~cape-history~ | | [[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 ** Exporting to the minibuffer
The entries shown in the completion popup can be exported to another 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]] :: - [[var:corfu-preselect]] ::
Configures startup selection, choosing between the first candidate or the Configures startup selection, choosing between the first candidate or the
prompt. prompt.
- [[var:corfu-preview-current]] ::
Configures current candidate preview.
- [[var:+corfu-buffer-scanning-size-limit]] :: - [[var:+corfu-buffer-scanning-size-limit]] ::
Sets the maximum buffer size to be scanned by ~cape-dabbrev~. Defaults to 1 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. 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 see ~add-hook!~'s documentation for additional ways to call it. ~add-hook~ only
accepts the quoted arguments form above. 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 ** Adding CAPFs to a key
To add other CAPFs to keys, adapt the snippet below into your ~config.el~: To add other CAPFs to keys, adapt the snippet below into your ~config.el~:
#+begin_src emacs-lisp #+begin_src emacs-lisp

View file

@ -38,21 +38,4 @@
(save-excursion (backward-char 1) (save-excursion (backward-char 1)
(insert-char ?\\))) (insert-char ?\\)))
(t (t
;; Without this corfu quits immediately.
(setq this-command #'corfu-insert-separator)
(call-interactively #'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 'completion-category-overrides `(lsp-capf (styles ,@completion-styles)))
(add-to-list 'corfu-auto-commands #'lispy-colon) (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-move-to-minibuffer)
(add-to-list 'corfu-continue-commands #'+corfu-smart-sep-toggle-escape)
(add-hook 'evil-insert-state-exit-hook #'corfu-quit) (add-hook 'evil-insert-state-exit-hook #'corfu-quit)
(when (modulep! +icons) (when (modulep! +icons)

View file

@ -162,26 +162,32 @@
(:when (modulep! :completion corfu) (:when (modulep! :completion corfu)
(:after corfu (:after corfu
(:map corfu-mode-map (:map corfu-mode-map
:e "C-M-i" #'completion-at-point :i "C-SPC" #'completion-at-point
(:unless (modulep! :completion corfu +tng) :n "C-SPC" (cmd! (call-interactively #'evil-insert-state)
:i "C-SPC" #'completion-at-point (call-interactively #'completion-at-point))
:n "C-SPC" (cmd! (call-interactively #'evil-insert-state) :v "C-SPC" (cmd! (call-interactively #'evil-change)
(call-interactively #'completion-at-point)) (call-interactively #'completion-at-point)))
:v "C-SPC" (cmd! (call-interactively #'evil-change)
(call-interactively #'completion-at-point))))
(:map corfu-map (:map corfu-map
"C-SPC" #'corfu-insert-separator
"C-k" #'corfu-previous
"C-j" #'corfu-next
"C-u" (cmd! (let (corfu-cycle) "C-u" (cmd! (let (corfu-cycle)
(funcall-interactively #'corfu-next (- corfu-count)))) (funcall-interactively #'corfu-next (- corfu-count))))
"C-d" (cmd! (let (corfu-cycle) "C-d" (cmd! (let (corfu-cycle)
(funcall-interactively #'corfu-next corfu-count))))) (funcall-interactively #'corfu-next corfu-count)))))
(:after corfu-popupinfo (:after corfu-popupinfo
:map corfu-popupinfo-map :map corfu-popupinfo-map
"C-h" #'corfu-popupinfo-toggle
;; Reversed because popupinfo assumes opposite of what feels intuitive ;; Reversed because popupinfo assumes opposite of what feels intuitive
;; with evil. ;; with evil.
(:when (modulep! :completion corfu +direction) "C-S-k" #'corfu-popupinfo-scroll-down
"C-S-k" #'corfu-popupinfo-scroll-down "C-S-j" #'corfu-popupinfo-scroll-up
"C-S-j" #'corfu-popupinfo-scroll-up) "C-<up>" #'corfu-popupinfo-scroll-down
"C-h" #'corfu-popupinfo-toggle))) "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) ;;; :completion (separate)
(map! (:when (modulep! :completion ivy) (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-p" #'corfu-previous
"C-n" #'corfu-next "C-n" #'corfu-next
(:when (modulep! :completion corfu +orderless) (:when (modulep! :completion corfu +orderless)
[remap completion-at-point] #'+corfu-smart-sep-toggle-escape) [remap corfu-insert-separator] #'+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))))
(when-let ((cmds-del (when-let ((cmds-del
`(menu-item "Reset completion" corfu-reset `(menu-item "Reset completion" corfu-reset
:filter ,(lambda (cmd) :filter ,(lambda (cmd)
@ -517,8 +503,8 @@ Continues comments if executed from a commented line. Consults
:gi "RET" cmds-ret-pt) :gi "RET" cmds-ret-pt)
(:unless (or (modulep! :completion corfu +on-ret) (:unless (or (modulep! :completion corfu +on-ret)
(modulep! :completion corfu +on-ret-pt)) (modulep! :completion corfu +on-ret-pt))
[return] nil :gi [return] nil
"RET" nil))) :gi "RET" nil)))
;; Smarter C-a/C-e for both Emacs and Evil. C-a will jump to indentation. ;; 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 ;; Pressing it again will send you to the true bol. Same goes for C-e, except