Monday, January 31, 2011

Bash, Readline and Emacs

I've known for a while that there are some good bash keyboard shortcuts.

Ctrl-A - cursor to the beginning of the line
Ctrl-E - cursor to the end of the line
Ctrl-R - reverse search for a historical command


Cool, those are great, but recently I realized that bash, by default, uses Emacs key mappings. (You can change it to vi with set -o vi, but this post is about Emacs keys). That opens up a whole new world. Whatever works in Emacs you can try in bash:

Alt-F - forward 1 word
Alt-B - backward 1 word
Alt-Backspace - delete 1 word backwards
Alt-d - delete 1 word forwards
Alt-8 Alt-B - move 8 words backwards


During a search (Ctrl-R), once you have a match, you can hit Ctrl-R to search backwards to the next match, Ctrl-S to search forward to the next match. Any navigation key will drop you out of the search and into editing the command line your search matched.

All of these are standard Emacs behaviors, and I'm sure there is more to be discovered.

Only in the last couple days have I realized that this awesome editing functionality is a product of the readline library from GNU, not a product of bash. Which means, you get all this stuff in any product that uses readline. For example, the mysql command line tool, the python interpreter, the ruby interpreter, the Octave interpreter, Postgresql interpreter. I'm sure there are many more as readline is widely used. Why I never made this connection before, I have no idea.

NOTE: Some keys get intercepted by your OS or terminal. For example, I use Gnome terminal, which, with a default configuration, has a menu bar, and Alt-1 - Alt-0 are configured as hot keys for selecting tab 1 - 10. I edited the keyboard shortcuts (Edit -> Keyboard Shortcuts) and removed the key mappings for selecting a tab with Alt-. Then I right clicked in the terminal and deactivated the Show Menubar setting. I would much rather have the hot keys than the menus that I never use.