Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

ZSH has a powerful menu select autocompletion e.g. for choosing a directory, choosing a process with kill (kill[tab][tab]). You can use arrows to navigate around the choices.

Is it possible to have the menu pop-up for the history search (CTRL+R) also? Such a way that the menu would allow the navigate the matches of current CTRL+R search bar?

share|improve this question

zsh-navigation-tools does something like this. If you use oh-my-zsh you just need to add zsh-navigation-tools to plugins=(...) in your .zshrc then ctrl-R will give you a scrolling history with up/down and search/filtering. You can use it without oh-my-zsh but the setup looks like more work.

share|improve this answer
  1. Not that I know of.

  2. Perhaps you wish to try predict-on, which does something related to what you are asking:

    autoload -U predict-on
    zle -N predict-on
    zle -N predict-off
    bindkey '^X1' predict-on
    bindkey '^X2' predict-off
share|improve this answer
Interesting function -- never heard of that one before. – mpy Mar 11 '13 at 13:47

That is possible; in principle I modified the _kill completion to work also for history events.

Here's an example; after selecting a entry you hit [ENTER] once to accept the event number (the command line reads then f. e. hc 780) and hit [ENTER] again to execute the command. (Use fc instead of hc if you want to modify the command line prior to execution).

$ hc Makefile[TAB]
history event
 1906  9.3.2013 18:10  vi Makefile
 1867  9.3.2013 17:26  less Makefile
  780  3.2.2013 17:54  cat Makefile                
  776  3.2.2013 17:51  cat ../Makefile     

To use it, put the appended files to a directory in your $fpath and add these lines into your ~/.zshrc:

zstyle ':completion:*:historyevent' command 'fc -dE -lr 1'
zstyle ':completion:*:historyevent' sort no

Finally, start a new zsh session.

Beware, that's a quick&dirty solution, but it worked well for some time now.



local out histevent list expl match desc listargs all nm ret=1

_tags historyevent || return 1


out=( "${(@f)$(_call_program historyevent fc -l 2>/dev/null)}" )
out=( "${(@M)out[2,-1]:#${~match}}" )

histevent=( "${(@)${(@M)out##[^0-9]#[0-9]#}##*[[:blank:]]}" )

if zstyle -T ":completion:${curcontext}:historyevent" verbose; then
  list=( "${(@Mr:COLUMNS-1:)out}" )
  desc=(-ld list)

_wanted processes expl 'history event' \
    compadd "$@" "$desc[@]" "$all[@]" -a - histevent && ret=0

if [[ -n "$all" ]]; then
  zstyle -s ":completion:${curcontext}:historyevent" insert-ids out || out=menu

  case "$out" in
  menu)   compstate[insert]=menu ;;
  single) [[ $compstate[nmatches] -ne nm+1 ]] && compstate[insert]= ;;
  *)      [[ ${#:-$PREFIX$SUFFIX} -gt ${#compstate[unambiguous]} ]] &&
              compstate[insert]=menu ;;

return ret


#compdef fc

local curcontext="$curcontext" line state ret=1

_arguments -C \
   '-e[editor command]' \
   '-l[list last history events]' \
   '-n[suppress numbers]' \
   '-r[reverse order]' \
   '*:history event:->historyevent' && ret=0

if [[ -n "$state" ]]; then
  _alternative \
    'historyevent:: _historyevent' && ret=0

return ret
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .