noctuid / general.el

More convenient key definitions in emacs
GNU General Public License v3.0
986 stars 43 forks source link

Vertico keybindings #488

Closed mclearc closed 3 years ago

mclearc commented 3 years ago

I have the following setup for vertico, which is a completion/narrowing framework build off of emacs' completing-read.

(use-package vertico
  :general
  (:states '(normal insert motion emacs) :keymaps 'vertico-map
   "<escape>" #'minibuffer-keyboard-quit
   "C-j"      #'vertico-next
   "C-k"      #'vertico-previous
   "M-RET"    #'vertico-exit)
  :hook (after-init . vertico-mode))

This works in GUI but not in terminal.

Nor does the evil rebinding command work (either in terminal or in GUI):

  (with-eval-after-load 'evil
    (evil-define-key 'motion vertico-map
      "C-j"      #'vertico-next
      "C-k"      #'vertico-previous))

The maintainer of Vertico said the following in response to my opening an issue:

Any ideas what might be going wrong? I didn't have this problem with selectrum or icomplete-vertical.

Vertico sets the keymap differently than the other packages.

  • In the minibuffer setup vertico--setup, Vertico does this:
(use-local-map vertico-map)
  • In contrast, Icomplete does this:
(use-local-map (make-composed-keymap icomplete-minibuffer-map (current-local-map)))
  • Selectrum does not replace the keymap, but sets it via read-from-minibuffer.

Maybe some evil user sees this and can help out, but it is more likely to get an answer if you ask on some evil issue tracker. I have no real clue about evil, but maybe (advice-add :vertico--setup :after 'evil-normalize-keymaps) helps.

The advice didn't change anything. Any ideas what might be going wrong?

noctuid commented 3 years ago

Like iyefrat says in the other thread, are you using evil in the minibuffer? If not, you can remove the :states ... section. If you are using evil in the minibuffer, maybe :vertico--setup should be 'vertico--setup.

mclearc commented 3 years ago

Thanks -- this works with respect to vertico in the minibuffer both in GUI and in tty:

(use-package vertico
  :general
  (:keymaps 'vertico-map
   "<escape>" #'minibuffer-keyboard-quit
   "C-j"      #'vertico-next
   "C-k"      #'vertico-previous
   "M-RET"    #'vertico-exit)
  :hook (after-init . vertico-mode))

However, I use vertico with a child frame in GUI, in that case I need to declare the states like so:

;; Pop up for vertico
(use-package mini-popup
  :straight (:host github :repo "minad/mini-popup")
  :if (display-graphic-p)
  :general
  (:states '(normal insert motion emacs) :keymaps 'vertico-map
   "<escape>" #'minibuffer-keyboard-quit
   "C-n"      #'vertico-next-group
   "C-p"      #'vertico-previous-group
   "C-j"      #'vertico-next
   "C-k"      #'vertico-previous
   "M-RET"    #'vertico-exit))

It seems a little surprising to me that two different keybinding declarations are needed here, since that wasn't true for other completion frameworks like selectrum or incomplete-vertical, but this seems to be because of the different ways those packages bind keys. Thanks for your help!

minad commented 3 years ago

@mclearc Regarding having to use a different configuration for mini-popup - I really wonder why this happens. mini-popup just visualizes the minibuffer candidates, but the actual focus is kept in the minibuffer.

mclearc commented 3 years ago

Yeah I don't know -- I didn't need to to do this for emacs-mini-frame. I can use a single setting in evil that seems to work everywhere (GUI minibuffer, child frame, terminal)---setting evil-want-minibuffer t. But this also makes the cursor do some weird things in terminal so I think I may stick with the multiple bindings.

minad commented 3 years ago

Interesting. But well - mini-popup is quite experimental. I let this to you and the evil guys to figure out. If mini-frame works well for you, why not use that? However I also had a few issues on the Consult issue tracker regarding mini-frame. So I cannot recommend it unreservedly.

mclearc commented 3 years ago

Yeah -- I had problems with mini-frame and vertico so I'm giving mini-popup a try, which is working well so far!