minad / corfu

:desert_island: corfu.el - COmpletion in Region FUnction
GNU General Public License v3.0
1.14k stars 43 forks source link

consult-completion-in-region doesn't display annotations when invoked from marginalia #320

Closed ReggieMarr closed 1 year ago

ReggieMarr commented 1 year ago

Whats desired: I want to be able to switch from the "normal" corfu popup window to the minibuffer with annotations. Whats going on: I can switch to minibuffer and select completion candidates but annotations/metadata doesn't seem to translate.

I've tried a number of iterations on this but the simplest one is this:

(defun corfu-move-to-minibuffer ()
        (interactive)
                (let (completion-cycle-threshold completion-cycling)
                (apply #'consult-completion-in-region completion-in-region--data)))

(use-package! corfu
  ;; Optional customizations
  :custom
  (corfu-cycle t)                 ; Allows cycling through candidates
  (corfu-auto t)                  ; Enable auto completion
  (corfu-auto-prefix 3)
  (corfu-auto-delay 0.1)
  (corfu-preview-current 'insert) ; Do not preview current candidate
  (corfu-indexed-mode)
  (corfu-on-exact-match t)      ; auto expand tempel snippets

    :bind (:map corfu-map
              ("SPC"      . corfu-insert-separator)
              ("TAB"        . corfu-move-to-minibuffer)
              ([tab]        . corfu-move-to-minibuffer)
              ("<escape>"    . corfu-quit)
              ("M-d"    . corfu-info-documentation)
              ("M-l"    . corfu-info-location)
              ("S-TAB"      . corfu-previous)
              ([backtab]    . corfu-previous)
              ("S-<return>" . corfu-insert-separator)
              ("RET"        . corfu-insert)))

I know that consult-read takes the :annotate attribute and I imagine theres something I could leverage off of marginalia but I can't quite seem to figure out how.

minad commented 1 year ago

consult-completion-in-region supports annotations, also Marginalia. I suspect that the problem in your case is that either the annotation-function or the completion category is missing from the completion metadata. To test this you can go to an Elisp buffer:

  1. Type 'def M-TAB -> I see the built-in <f> annotations in Corfu (corfu-mode must be enabled).
  2. Move to minibuffer -> I see Marginalia symbol annotations (marginalia-mode must be enable)d.
  3. Cycle between annotations via marginalia-cycle -> I see either the Marginalia symbol annotations or the built-in <f> annotations.
ReggieMarr commented 1 year ago

Thanks for the quick response @minad . I guess I should have clarified. I also see annotations in corfu (with corfu-mode enabled) however when I move to minibuffer I don't see annotations (marginalia-mode is enabled). When I try to cycle between annotations I see "Marginalia: No Annotators Found". I think somehow during the move the corfu metadata goes to nil or I need to transfer it otherwise. I've attached a screenshots to provide context. Screenshot from 2023-04-18 10-41-11 Screenshot from 2023-04-18 10-45-58 Screenshot from 2023-04-18 10-46-14

minad commented 1 year ago

That's odd. consult-completion-in-region transfers the completion metadata, including the annotation function. See https://github.com/minad/consult/blob/41510b59f058d24708112acf4921f4cd61ca0ad9/consult.el#L2972-L2981. You can try to investigate there. Note that this has nothing to do with Marginalia. Can you create a minimal recipe starting from emacs -Q which shows this issue (only Vertico, Corfu and Consult)?

ReggieMarr commented 1 year ago

I'm struggling to create a init.el file that would work this is what I have

;; Enable package management
(require 'package)
(setq package-enable-at-startup nil)
(setq package-archives
      '(("gnu" . "https://elpa.gnu.org/packages/")
        ("melpa" . "https://melpa.org/packages/")))
(package-initialize)

;; Install required packages
(unless (package-installed-p 'vertico)
  (package-refresh-contents)
  (package-install 'vertico))
(unless (package-installed-p 'consult)
  (package-refresh-contents)
  (package-install 'consult))
(unless (package-installed-p 'evil)
  (package-refresh-contents)
  (package-install 'evil))
(unless (package-installed-p 'corfu)
  (package-refresh-contents)
  (package-install 'corfu))
(unless (package-installed-p 'prescient)
  (package-refresh-contents)
  (package-install 'prescient))
(unless (package-installed-p 'company-prescient)
  (package-refresh-contents)
  (package-install 'company-prescient))

;; Enable packages
(require 'vertico)
(vertico-mode)

(require 'consult)
(require 'evil)

(require 'corfu)
(global-corfu-mode)
(with-eval-after-load 'corfu
        (corfu-prescient-mode))

(require 'prescient)
(prescient-persist-mode)

;; Set up key bindings
(define-key global-map (kbd "M-x") #'consult-completing-read)
(define-key global-map (kbd "C-x b") #'consult-buffer)
(define-key global-map (kbd "C-x 4 f") #'consult-find-file-other-window)

;; Enable Evil mode
(evil-mode)

;; Add key bindings for Vertico
(define-key vertico-map (kbd "C-j") #'vertico-next)
(define-key vertico-map (kbd "C-k") #'vertico-previous)

;; Add key bindings for Corfu
(define-key corfu-map (kbd "C-j") #'corfu-next)
(define-key corfu-map (kbd "C-k") #'corfu-previous)
(define-key corfu-map (kbd "C-w") #'corfu-quit)
(define-key corfu-map (kbd "TAB") #'corfu-move-to-minibuffer)

;; Add additional key bindings for Evil
(define-key evil-normal-state-map (kbd "C-p") #'consult-lsp-symbols)
(define-key evil-normal-state-map (kbd "SPC") #'consult-line)
(define-key evil-normal-state-map (kbd "M-.") #'xref-find-definitions)

;; Customized settings for Corfu
(defun corfu-move-to-minibuffer ()
  (interactive)
  (let ((completion-extra-properties corfu--extra)
        completion-cycle-threshold completion-cycling)
    (apply #'consult-completion-in-region completion-in-region--data)))

(setq corfu-cycle t)
(setq corfu-auto t)
(setq corfu-auto-prefix 3)
(setq corfu-auto-delay 0.1)
(setq corfu-preview-current 'insert)
(setq corfu-indexed-mode t)
(setq corfu-on-exact-match t)

(define-key corfu-map (kbd "SPC") #'corfu-insert-separator)
(define-key corfu-map (kbd "<escape>") #'corfu-quit)
(define-key corfu-map (kbd "M-d") #'corfu-info-documentation)
(define-key corfu-map (kbd "M-l") #'corfu-info-location)
(define-key corfu-map (kbd "<backtab>") #'corfu-previous)
(define-key corfu-map (kbd "<S-tab>") #'corfu-previous)
(define-key corfu-map (kbd "<return>") #'corfu-insert)
(define-key corfu-map (kbd "<S-return>") #'corfu-insert-separator)

(defun corfu-send-shell (&rest _)
    "Send completion candidate when inside comint/eshell."
    (cond
        ((and (derived-mode-p 'eshell-mode) (fboundp 'eshell-send-input))
        (eshell-send-input))
        ((and (derived-mode-p 'comint-mode)  (fboundp 'comint-send-input))
        (comint-send-input))))

(setq tab-always-indent 'complete)

In the mean time I found something interesting: I added the following message print statements in consult-completion-in-region

             (completion-extra-properties
              `(,@(and ann-fun (list :annotation-function (consult--in-buffer ann-fun)))
                ,@(and aff-fun (list :affixation-function (consult--in-buffer aff-fun)))
                ;; Provide `:annotation-function' if `:company-docsig' is specified.
                ,@(and docsig-fun (not ann-fun) (not aff-fun)
                       (list :annotation-function
                             (consult--in-buffer
                              (lambda (cand)
                                (concat (propertize " " 'display '(space :align-to center))
                                        (funcall docsig-fun cand)))))))))
    (message "ann %s" ann-fun)
    (message "exit %s" aff-fun)
    (message "docsig %s" docsig-fun)
    (message "predicate: %s" predicate)
    (message "config: %s" config)

And I get the following response:

ann lsp-completion--annotate
exit nil
docsig nil
predicate: nil
config: nil

To me this indicates that the annotation function is setup correct but I can't get the config. I looked into the consult--customize-alist and found this:

((consult-theme :preview-key
                (list "C-SPC" :debounce 0.5 'any))
 (+default/search-emacsd :preview-key "C-SPC")
 (+default/search-notes-for-symbol-at-point :preview-key "C-SPC")
 (+default/search-other-cwd :preview-key "C-SPC")
 (+default/search-cwd :preview-key "C-SPC")
 (+default/search-project-for-symbol-at-point :preview-key "C-SPC")
 (+default/search-other-project :preview-key "C-SPC")
 (+default/search-project :preview-key "C-SPC")
 (consult-recent-file :preview-key "C-SPC")
 (consult-bookmark :preview-key "C-SPC")
 (consult-grep :preview-key "C-SPC")
 (consult-git-grep :preview-key "C-SPC")
 (consult-ripgrep :preview-key "C-SPC")
 (consult-buffer-other-frame :preview-key nil))

Am I meant to provide the customization to start ? I would have thought there was some default configuration.

ReggieMarr commented 1 year ago

Oh never mind, I'm dumb I guess calling ```consult-completion-in-region''' is meant to be creating the config on the fly. I'm confused why it's failing then

minad commented 1 year ago

Did you get any new insight on this issue?

ReggieMarr commented 1 year ago

No, it's still not working for me. I think it has to do with the config within consult-completion-in-region.