I use zsh's menu-based tab completion. I press Tab once, and a list of possible completions appears. If I press Tab again, I can navigate this list with the arrow keys. However, is it possible to navigate them with the vi-like H, J, K, L keys instead?

I use emacs mode for command-line input, with bindkey -e in ~/.zshrc. I also use zim with zsh. If relevant, the commands that specify the tab-completion system are here.


Yes, you can by enabling menu select:

zstyle ':completion:*' menu select
zmodload zsh/complist
# use the vi navigation keys in menu completion
bindkey -M menuselect 'h' vi-backward-char
bindkey -M menuselect 'k' vi-up-line-or-history
bindkey -M menuselect 'l' vi-forward-char
bindkey -M menuselect 'j' vi-down-line-or-history
  • +1 This works well if I manually run the bindkey commands in the terminal, but it fails if I put them at the end of ~/.zshrc, with /home/sparhawk/.zshrc:bindkey:186: no such keymap `menuselect'. – Sparhawk Nov 15 '16 at 2:25
  • Did you enable the completions scripts? See the command before the ellipses... – jasonwryan Nov 15 '16 at 2:54
  • Do you mean the zstyle line? Yes, I had that in ~/.zshrc too. – Sparhawk Nov 15 '16 at 3:25
  • You have to enable it as well. See my .zshrc as an example. – jasonwryan Nov 15 '16 at 3:42
  • Adding autoload -Uz compinit and compinit didn't work, but I'm not sure if enabling it is the problem, because (a) menu select works fine in a general sense, and always has, and (b) I can manually run the bindkey lines later, which works. Also, I just realised (b) only works if I press tab first, presumably to initialise the completion system, then run bindkey…. Otherwise it fails as above (bindkey: no such keymap `menuselect'). – Sparhawk Nov 15 '16 at 3:54

The closest I've come to this is using CTRL-N and CTRL-P to move forward and backward through the list of possible completions, instead of Tab and Shift-Tab. This is more vi-like navigation.

In a config .zsh file I achieve this with:

bindkey '^n' expand-or-complete
bindkey '^p' reverse-menu-complete

And relatedly:

bindkey '^k' up-history
bindkey '^j' down-history
bindkey '^h' backward-delete-char
bindkey '^w' backward-kill-word
bindkey '^r' history-incremental-search-backward

Here are the docs for the bindings.

  • 2
    it is great, thanks. also, -M menuselect can be added to bindkey command to restrict the mode here. – user86041 Oct 9 '17 at 5:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.