Is it possible to use different zsh menu selection behaviour for different commands?

13

4

I'm using the menu select behaviour in zsh, which invokes a menu below the cursor where you can see the various possibilities. The .zshrc option i have set for this is

zstyle ':completion:*' menu select=2

By default, pressing Return to select a possibility in this menu only completes the word — it does not actually send the command. For example, I might get a menu like this

~ % cd de<TAB>
completing directory:
[Desktop/]  Development/

Pressing Return here will result in

~ % cd Desktop/

I then have to press Return a second time to actually send the command.

I can modify this behaviour to make it so that pressing Return both selects the completion and sends the command by doing this

bindkey -M menuselect '^M' .accept-line

However, there's a problem with this: sometimes I need to complete a file or directory without sending the command. For example, I might need to do ln -s Desktop Desktop2 — with this bindkey behaviour, trying to complete Desktop will result in ln -s Desktop/ being sent as the command, and obviously I don't want that.

I'm aware that just pressing space will let me get on with the command, but it's now a habit.
Given this, is there a way to make it so that only some commands let you press Return once (like cd), but all other commands require pressing it twice?

kine

Posted 2011-10-19T22:22:37.373

Reputation: 1 669

If the .zshrc file doesn't allow you to do so then the answer is simply going to be no, unless you adjust the source code yourself to support command-based behavior. But then you still have to define for which commands to do this, which on its own is way more tedious than just pressing an additional enter... – Tamara Wijsman – 2012-10-10T20:43:13.870

Answers

3

If you really need this, theoretically you could set a function that checks the command you're executing, and complete or send the line.

Try something like this (untested):

commands=(ls cd)
# define widget function
function check-command {
    zle beginning-of-line
    zle forward-word
    RBUFFER=" $RBUFFER"
    if [[ ${commands[(r)$LBUFFER]} == $LBUFFER ]] ; then ; zle accept-line ; else; zle     end-of-line ; fi
}

# create widget from function
zle -N check-command

# bind widget
bindkey -M menuselect '^M' check-command

Source: using custom command from old .inputrc in zsh?

balkian

Posted 2011-10-19T22:22:37.373

Reputation: 684

0

Technically its not possible in the way you are asking. Don't know if there is any other way out

Aexyn

Posted 2011-10-19T22:22:37.373

Reputation: 121