feat(corfu): general move-to-minibuffer impl

We previously implemented only consult/vertico as a target for export,
now we have all of them. It was necessary to use case-by-case
conditions, unfortunately, because other UIs have subtle quirks that
prevent a single generalized approach to work.

Ivy is almost compliant, but it needs beg and end to not be markers.

Helm doesn't replace `completion-in-region-function`, it expects to go
around the default `completion--in-region`, so a small addition was made
to its module, because we weren't doing that. This was likely an
oversight due to the non-standard usage. This was fixed here because we
need it working for this feature.

Ido doesn't implement `completion-in-region` and its `completing-read`
is retricted to a list of strings as table, so it's treated the same as
absence of a framework, because it lacks the needed features.
This commit is contained in:
Luigi Sartor Piucco 2024-02-04 17:17:13 -03:00
parent a5db530622
commit 70c327a4f1
No known key found for this signature in database
GPG key ID: 6FF1A01853A47A66
4 changed files with 31 additions and 11 deletions

View file

@ -144,12 +144,11 @@ 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 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. start corfu; in insert-like states, start corfu immediatelly.
** Exporting to the minibuffer (requires [[doom-module::completion vertico]]) ** Exporting to the minibuffer
When using the [[doom-module::completion vertico]] module, which pulls in the The entries shown in the completion popup can be exported to a ~completing-read~
[[doom-package:consult]] package, the entries shown in the completion popup can be minibuffer, giving access to all the manipulations that suite allows. Using
exported to a consult minibuffer, giving access to all the manipulations the Vertico for instance, one could use this to export with [[doom-package:embark]] via
Vertico suite allows. For instance, one could use this to export with [[kbd:][C-c C-l]] and get a buffer with all candidates.
[[doom-package:embark]] via [[kbd:][C-c C-l]] and get a buffer with all candidates.
** Manually call generic CAPFs ** 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

View file

@ -10,12 +10,30 @@
;;;###autoload ;;;###autoload
(defun +corfu-move-to-minibuffer () (defun +corfu-move-to-minibuffer ()
;; Taken from corfu's README. "Move the current list of candidates to your choice of minibuffer completion UI."
;; TODO: extend this to other completion front-ends.
(interactive) (interactive)
(let ((completion-extra-properties corfu--extra) (pcase completion-in-region--data
(completion-cycle-threshold completion-cycling)) (`(,beg ,end ,table ,pred ,extras)
(apply #'consult-completion-in-region completion-in-region--data))) (let ((completion-extra-properties extras)
completion-cycle-threshold completion-cycling)
(cond ((and (modulep! :completion vertico)
(fboundp #'consult-completion-in-region))
(consult-completion-in-region beg end table pred))
((and (modulep! :completion ivy)
(fboundp #'ivy-completion-in-region))
(ivy-completion-in-region (marker-position beg) (marker-position end) table pred))
;; Helm is special and wants to _wrap_ `completion--in-region'
;; instead of replacing it in `completion-in-region-function'.
((and (modulep! :completion helm)
(fboundp #'helm--completion-in-region)
(advice-member-p #'helm--completion-in-region #'completion--in-region))
;; Important: `completion-in-region-function' is set to corfu at
;; this moment, so `completion-in-region' (single -) doesn't work.
(completion--in-region beg end table pred))
;; Ido doesn't implement `completion-in-region', and its
;; `completing-read' only accepts a plain list of strings as table,
;; so there's not much we can do with it.
(t (error "No minibuffer completion UI available for moving to!")))))))
;;;###autoload ;;;###autoload
(defun +corfu-smart-sep-toggle-escape () (defun +corfu-smart-sep-toggle-escape ()

View file

@ -32,6 +32,8 @@
tab-always-indent (if (modulep! +tng) 'complete tab-always-indent)) tab-always-indent (if (modulep! +tng) 'complete tab-always-indent))
(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-continue-commands #'+corfu-move-to-minibuffer)
(add-hook! 'minibuffer-setup-hook (add-hook! 'minibuffer-setup-hook
(defun +corfu-enable-in-minibuffer () (defun +corfu-enable-in-minibuffer ()
"Enable Corfu in the minibuffer if `completion-at-point' is bound." "Enable Corfu in the minibuffer if `completion-at-point' is bound."

View file

@ -24,6 +24,7 @@ Can be negative.")
(use-package! helm-mode (use-package! helm-mode
:hook (doom-first-input . helm-mode) :hook (doom-first-input . helm-mode)
:config :config
(advice-add #'completion--in-region :around #'helm--completion-in-region)
;; helm is too heavy for `find-file-at-point' ;; helm is too heavy for `find-file-at-point'
(add-to-list 'helm-completing-read-handlers-alist (cons #'find-file-at-point nil))) (add-to-list 'helm-completing-read-handlers-alist (cons #'find-file-at-point nil)))