78

I use vim for essentially all my editing needs, so I decided to once again try vi-mode for my shell (currently ZSH w/ oh-my-zsh on OS X), but I find myself trying (and failing) to use Ctrl-R constantly. What's the equivalent key-binding? And for future reference, how would I figure this out myself? I'm pretty sure I could use bind -P in bash.

Hank Gay
  • 3,549
  • 2
    According to 'man zshzle', history-incremental-search-backward is not bound in Vi modes (vicmd, viins) by default. – paul Jul 27 '12 at 13:45

3 Answers3

81

You can run bindkey with no arguments to get a list of existing bindings, eg:

# Enter vi mode
chopper:~> bindkey -v

# Search for history key bindings
chopper:~> bindkey | fgrep history
"^[OA" up-line-or-history
"^[OB" down-line-or-history
"^[[A" up-line-or-history
"^[[B" down-line-or-history

In emacs mode, the binding you want is history-incremental-search-backward, but that is not bound by default in vi mode. To bind Ctrl-R yourself, you can run this command, or add it to your ~/.zshrc:

bindkey "^R" history-incremental-search-backward

The zshzle manpage (man zshzle) has more information on zsh's line editor, bindkey, and emacs/vi modes.

mrb
  • 10,288
  • 4
    Thanks, particularly for zshzle. That is quite informative and useful. – Hank Gay Jul 27 '12 at 15:27
  • 1
    I love you. Seriously. After upgrading to OSX El Capitan reverse search was gone and I missed it more than everything else in my daily workflow. – Christian Oct 17 '15 at 18:09
  • 1
    esc / seems like the right answer however, not so much just rebinding one emacs mode keybinding into vi mode. – dlamblin Sep 27 '22 at 16:54
67

This is an ancient question, but the only (and accepted) answer basically tells one how to transplant the “emacs-like” history-incremental-search-backward to vi mode. Whilst this is perfectly doable and may be the right solution for you, it’s a little strange that no one has mentioned the “vi way” of searching history.

vi mode in zsh supports searching history using the standard vi/vim keys: / and ?, both available in command mode. (Hit <Esc> to switch from insert to command mode, just like in vi or vim.)

Their sense is reversed, though: Since you usually want to search your shell’s history in reverse, / does a reverse search whereas ? does a forward search.

Once the first hit is displayed, you can (just like in vi/vim) use n to continue finding more hits in the same direction, or N to reverse the direction of the search.

The relevant default keybindings in the vicmd keymap are:

"/" vi-history-search-backward
"?" vi-history-search-forward
"n" vi-repeat-search
"N" vi-rev-repeat-search
wjv
  • 1,231
  • 8
    It's also good to use "^P" history-beginning-search-backward and "^N" history-beginning-search-forward for vim-like autocompletion (you start typing, then press ctrl+p or ctrl+n). – cprn Oct 31 '16 at 20:45
  • For me, ? brings up bck-i-search, which is exactly what I was looking for. Thank you. – geowa4 Dec 02 '16 at 01:40
  • @wjv the advantage of history-incremental-search-backward is that is supports glob patterns. The default / or `?' doesnt: https://coderwall.com/p/-jvcag/zsh-reverse-history-search-with-regex – alpha_989 Apr 15 '18 at 16:12
  • @alpha_989 The blog post you reference is incorrect. It may be that the author has some zsh “framework” installed that overloads the ^R keybinding. The only “regex-like” character supported by both history-search-backward and history-incremental-search-backward is ^, to anchor the search string to the start of the line. The real power of history-incremental-search-backward is that it does an incremental search, as its name suggests. I can imagine that one might want to bind it in the vicmd keymap for that reason. – wjv Apr 17 '18 at 06:23
  • @wjv, you are right.. I should have written history-incremental-pattern-search-backward, not history-incremental-search-backward. history-incremental-pattern-search-backwards maybe a widget.. but I think it comes installed by default in zsh. It supports glob patterns not regex as you correctly pointed out: http://zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-Operators. There is indeed a mistake in the post.. – alpha_989 Apr 17 '18 at 15:29
  • Are you aware of any method to use extended regex search through zsh history? The only method I can think of is to use vim-8s term mode.. to search through zsh history..using vim-regex. I find the ctrl-R and / to be rather limited, since I work fully in the terminal. – alpha_989 Apr 17 '18 at 15:30
  • I think this answer is superior to the currently accepted answer because it points out the n, N bindings. This is intuitive to a vi user, but also nonintuitive in a way because I had no idea it was there. Thank you. – Dan Lowe Feb 04 '23 at 19:03
1

Add the following at the bottom of ~/.zshrc, then source ~/.zshrc

bindkey -M vicmd '/' history-incremental-search-backward
j3ffyang
  • 151