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.


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

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
  • What does bindkey '\e[A' show at the prompt? – Gilles 'SO- stop being evil' Apr 1 '14 at 23:12
  • Entering that at the command line returns "^[[A" history-beginning-search-backward – JHo Apr 2 '14 at 12:04
  • Did you upgrade anything other than oh-my-zsh? What happens when you press the Up key now? What is inserted if you press Ctrl+V and then Up? Do the arrow key work as expected in other circumstances? – Gilles 'SO- stop being evil' Apr 2 '14 at 12:36
  • @Gilles - Good questions. I did not upgrade anything else to my knowledge (nothing in brew, wget, etc.). Pressing the up arrow right now returns the last command. I am using a Mac, if I press Ctrl V and up arrow I get ^[OA. If I do V and paste gi, for example, then up arrow I get the last command. The arrow keys do work as expected. For example, in VIM they move the cursor. – JHo Apr 2 '14 at 13:04

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.

  • Thank you. I replaced my with your first suggested solution, sourced the .zshrc and it worked for me. I did not know there are different modes. For the record I use iTerm2. – JHo Apr 2 '14 at 19:58
  • thanks! learned something today. What is "application cursor mode"? also 'bind' works. – dashesy May 13 '20 at 18:21
  • 1
    @dashesy It's a terminal mode where some keys send different escape sequences. It's from the era of physical terminal on serial ports. I don't know why it exists, maybe at some point in the past one mode moved the cursor locally on the terminal and the other just sent the keys to applications? It's bindkey in zsh, bind in bash. – Gilles 'SO- stop being evil' May 13 '20 at 19:07

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.