From 70c327a4f17b1a8833505bde1b25f214e7906b4e Mon Sep 17 00:00:00 2001 From: Luigi Sartor Piucco Date: Sun, 4 Feb 2024 17:17:13 -0300 Subject: [PATCH] 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. --- modules/completion/corfu/README.org | 11 +++++------ modules/completion/corfu/autoload.el | 28 +++++++++++++++++++++++----- modules/completion/corfu/config.el | 2 ++ modules/completion/helm/config.el | 1 + 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/modules/completion/corfu/README.org b/modules/completion/corfu/README.org index 39633da9f..642d83cb2 100644 --- a/modules/completion/corfu/README.org +++ b/modules/completion/corfu/README.org @@ -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 start corfu; in insert-like states, start corfu immediatelly. -** Exporting to the minibuffer (requires [[doom-module::completion vertico]]) -When using the [[doom-module::completion vertico]] module, which pulls in the -[[doom-package:consult]] package, the entries shown in the completion popup can be -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. +** Exporting to the minibuffer +The entries shown in the completion popup can be exported to a ~completing-read~ +minibuffer, giving access to all the manipulations that suite allows. 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. ** Manually call generic CAPFs Completion at point functions have the property that, when called interactively diff --git a/modules/completion/corfu/autoload.el b/modules/completion/corfu/autoload.el index 841802596..195c49c4c 100644 --- a/modules/completion/corfu/autoload.el +++ b/modules/completion/corfu/autoload.el @@ -10,12 +10,30 @@ ;;;###autoload (defun +corfu-move-to-minibuffer () - ;; Taken from corfu's README. - ;; TODO: extend this to other completion front-ends. + "Move the current list of candidates to your choice of minibuffer completion UI." (interactive) - (let ((completion-extra-properties corfu--extra) - (completion-cycle-threshold completion-cycling)) - (apply #'consult-completion-in-region completion-in-region--data))) + (pcase completion-in-region--data + (`(,beg ,end ,table ,pred ,extras) + (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 (defun +corfu-smart-sep-toggle-escape () diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index d4bad1f24..41e54d945 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -32,6 +32,8 @@ tab-always-indent (if (modulep! +tng) 'complete tab-always-indent)) (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 (defun +corfu-enable-in-minibuffer () "Enable Corfu in the minibuffer if `completion-at-point' is bound." diff --git a/modules/completion/helm/config.el b/modules/completion/helm/config.el index 7f983f872..109c182fa 100644 --- a/modules/completion/helm/config.el +++ b/modules/completion/helm/config.el @@ -24,6 +24,7 @@ Can be negative.") (use-package! helm-mode :hook (doom-first-input . helm-mode) :config + (advice-add #'completion--in-region :around #'helm--completion-in-region) ;; helm is too heavy for `find-file-at-point' (add-to-list 'helm-completing-read-handlers-alist (cons #'find-file-at-point nil)))