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

I'm uzing zsh and, because I'm an avid Vim user, I just switched to using Vim-style editing on the command line. (That means if I type ls foo/bar and decide I want to cd instead, I can hit Esc ^ to hop back to the beginning and cw cd to change ls to cd.

That's all dandy, but the problem is that I can no longer use Ctrl+R to do recursive history search. Is there another way to do it, or can I somehow override the Vim keybinding to get it back?

share|improve this question
A hard choice! garyjohn shows a Vim way to do it, and JdeBP shows how to get the keybinding for Ctrl+R back! I'm going to play with both methods and accept an answer later. I'll decide based on 1) which method seems easier to me and 2) which gets more upvotes. Thanks to both of you! – Nathan Long Aug 26 '11 at 18:59
up vote 6 down vote accepted

Of course you can no longer use Ctrl+R. If you consult the Z Shell manual you'll see that there's only a key binding for the history-incremental-search-backward widget in the emacs keymap. There are no key bindings for it in the vi keymaps.

But as you'll also find from reading the manual (It's chapter 18.), adding a key binding is a fairly simple exercise in the use of the bindkey command:

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

You don't even have to use the zle command to map the widget onto a shell function, since this is a standard widget.

If you consult the answer to this same question that is on the Z Shell wiki, you'll see the commands for specifically adding this to the vi "command" and "insert mode" keymaps:

bindkey -M viins '^R' history-incremental-search-backward
bindkey -M vicmd '^R' history-incremental-search-backward

Also note that, as garyjohn points out, in the vi "command" keymap, the / character is bound to the vi-history-search-backward widget. The difference between this widget and the history-incremental-search-backward widget is the widget behaviour that applies once one is in history search mode. Here are a couple of the differences that you will notice:

  • Switching vi modes:
    • The search mode in history-incremental-search-backward toggles between the main and vicmd keymaps when you invoke the vi-cmd-mode widget whilst still staying in search mode. i.e. from emacs mode presssing the Esc key or Ctrl+XCtrl+V keys toggles the search mode between the emacs and vicmd keymaps. (Invoking history-incremental-search-backward from the vicmd keymap is thus troublesome, unless you bind something to vi-cmd-mode in the vicmd keymap as well.)
    • The search mode in vi-history-search-backward treats the vi-cmd-mode widget as accept-line and will end the search, re-entering the command mode that you entered the search from. i.e. (with the default bindings) / enters search mode from command mode and Esc goes back to command mode.
  • Repeating a search:
    • In history-incremental-search-backward, both the history-incremental-search-backward and the vi-rev-repeat-search widgets are recognized. i.e. (presuming that you have altered the bindings as above) both Ctrl+R and N will search for a preceding matching line.
    • In vi-history-search-backward, only the vi-rev-repeat-search widget is recognized. i.e. (presuming that you have altered the bindings as above) Ctrl+R will cause a beep and be ignored.
share|improve this answer
My muscle memory blesses you! – Nathan Long Aug 26 '11 at 18:55

In bash's vi mode, typing <Esc>/<string><Enter> will search the command history for <string>. n will search further back in history; N will search forward. zshell may be the same.

share|improve this answer
Yes, zshell is the same. Thanks! – Nathan Long Aug 26 '11 at 18:54
That's interesting, though - I frequently use search as a movement in Vim. I guess I can't use it to move within the command I'm currently editing, since it's pegged to searching history, eh? – Nathan Long Aug 26 '11 at 19:03
Right. But you can (at least in bash) use the f, F, t, T, ';' (semicolon), and ',' (comma) commands to move forward and back to particular characters in the line. – garyjohn Aug 26 '11 at 20:05

I prefer to use:

bindkey -M vicmd '/' history-incremental-search-backward

This way I can type ESC /text and see the command line. If I want to go the next match I type ESC n

share|improve this answer

You must log in to answer this question.

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