Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: carriage return (<enter> key) behavior during menu completion

On Dec 13,  1:42pm, Linus Arver wrote:
} Subject: carriage return (<enter> key) behavior during menu completion
} If I do "cd <tab>", zsh will list all the directories in a menu.
} However, after <tab>-ing to a directory I want, I have to press the
} <enter> key twice -- once to exit the menu, and once more to execute
} the cd command with the selected directory. Is there a way to make it
} so that I only have to press <enter> _once_ to execute the command
} whenever the completion menu is running?

The manual for the zsh/complist module says this:


All movement functions wrap around at the edges; any other zle function
not listed leaves menu selection and executes that function.  It is
possible to make widgets in the above list do the same by using the
form of the widget with a `.' in front.  For example, the widget
`.accept-line' has the effect of leaving menu selection and accepting
the entire command line.

During this selection the widget uses the keymap menuselect.  Any key
that is not defined in this keymap or that is bound to undefined-key is
looked up in the keymap currently selected.  This is used to ensure
that the most important keys used during selection (namely the cursor
keys, return, and TAB) have sensible defaults.  However, keys in the
menuselect keymap can be modified directly using the bindkey builtin
command (see *Note The zsh/zle Module::). For example, to make the
return key leave menu selection without accepting the match currently
selected one could call

     bindkey -M menuselect '^M' send-break

after loading the zsh/complist module.


That's a little muddled, but what it all means is that you can do

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

to get the behavior you're asking for.  One other thing the doc ought to
mention is that you can't call a user-defined widget from the menuselect
keymap; it behaves as "any other zle function" in the first paragraph I
quoted above.  Therefore

     bindkey -M menuselect '^M' undefined-key

causes <enter> to FIRST look in, e.g., the "main" keymap to find the
binding for ^M as accept-line, and then execute that still in menu
selection context.  It thus behaves as if ^M is were always bound in
menuselect.  Conversely

     bindkey -M menuselect ^M any-user-defined-widget

causes <enter> to first exit menu selection and THEN find ^M in the main
keymap and execute the binding.

} Interestingly, <enter> behaves like I want it to without menus
} (without the 'zstyle' line above), but with the menus, it's different
} for some reason.

Also per the same section of documentation ...


The following zle functions have special meaning during
menu selection:

accept-line, accept-search
     accept the current match and leave menu selection (but do not
     cause the command line to be accepted)


Messages sorted by: Reverse Date, Date, Thread, Author