While using the Unix command line, I often want to find a command I previously typed, e.g. the last "ssh" command I typed. Using the up and down arrows or "Ctrl-p" and "Ctrl-n" to go through each line is often very tedious because there's lots of other cruft in the history since the last time I typed "ssh".
tcsh, the first "real" Unix shell I used, has a nice history search mechanism: type "ssh" then "ESC-p". It'll go back through your history and find the last time you typed "ssh". Hit "ESC-p" again , and it'll go to the one before that. Hit "ESC-n" and it'll go forward to the next one. Thus using "ESC-p" and "ESC-n" allows you to interactively go up and down through your history, like the up and down arrow keys, but only matching what you have typed so far. Also, "ESC" is an alias for the "META" key, which is mapped to "ALT" in most GUI terminal programs. Thus, you can just use "ALT-p" and "ALT-n".
My current shell is
zsh, which I switched to maybe four years ago. By default,
zsh doesn't have key bindings for "ESC-p" and "ESC-n". Since this was one of my favorite
tcsh features, figuring out how to do this was a requirement for me to stick with
zsh. Luckily, it has functions to do this, the key bindings just need to be setup. Here's the snippet from my
# "^[" is what the "ESC" key looks like to zsh bindkey "^[p" history-beginning-search-backward bindkey "^[n" history-beginning-search-forward
Now, I've had my
zsh setup like this for a very long time. But occasionally I'm forced to use
bash or, more likely, some other program which uses GNU
readline. The default GNU
readline bindings for "ESC-p" or "ESC-n" do not behave like
tcsh, so I lose one of my favorite features. I've tried using "Ctrl-r" to interactively search backward through history, however I find it's behavior annoying for a few reasons. First, it matches anywhere in the the command string, not just the start of a command. I find this matches many history commands that are irrelevant. Second, it only starts matching after you type "Ctrl-r". Finally, I always seem to hit "Ctrl-r" one too many times, and there doesn't seem to be a way to search forward in history. And again, luckily
readline has functions to do history the way I like, the key bindings just need to be setup.
readline looks in
~/.inputrc for customization, so I put these lines in there to get what I want:
# "\e" is what the "ESC" key looks like to readline "\ep": history-search-backward "\en": history-search-forward
Now, I can finally be (somewhat) happy in
bash or any