Fix Broken History Search After Oh-My-Zsh Upgrade

keyboard shortcutsoh-my-zshterminalzsh

I did the auto-upgrade of oh-my-zsh a few days ago. Now my filtered history (type a few letters and up arrow) no longer works. I did not realize how dependent I became on it.


EDIT:

For example, I used to type a few letters of the command and press up arrow to search my history:

➜  scratch git:(develop) up   # press ↑ arrow key

Prompt changes to:

➜  scratch git:(develop) upupdowndownleftrightleftrightbabastartselect # 3 key presses

I don't know how to what version I was running. Currently:

➜  scratch git:(develop) echo $ZSH_VERSION
5.0.2

Here are the lines I have in my .zshrc file that I thought were making the incremental search work:

# Set bindkeys to start search from last word
bindkey '\e[A' history-beginning-search-backward
bindkey '\e[B' history-beginning-search-forward

Best Answer

There are two de facto standard escape sequences for cursor keys; different terminals, or even the same terminal in different modes, can send one or the other. For example, xterm sends \eOA for Up in “application cursor mode” and \e[A otherwise. For Down you can encounter both \e[B and \eOB, etc.

One solution is to duplicate your bindings: whenever you bind one escape sequence, bind the other escape sequence to the same command.

bindkey '\eOA' history-beginning-search-backward
bindkey '\e[A' history-beginning-search-backward
bindkey '\eOB' history-beginning-search-forward
bindkey '\e[B' history-beginning-search-forward

Another approach is to always bind one escape sequence, and make the other escape sequence inject the other one.

bindkey '\e[A' history-beginning-search-backward
bindkey '\e[B' history-beginning-search-forward
bindkey -s '\eOA' '\e[A'
bindkey -s '\eOB' '\e[B'

I don't know why upgrading oh-my-zsh would have affected which escape sequence the shell receives from the terminal. Maybe the new version performs some different terminal initialization that enables application cursor mode.

Related Question