Bash provides two modes for command line editing - emacs and vi. Emacs editing mode is the default and I already wrote an article and created a cheat sheet for this mode.
This time I am going to introduce you to bash’s vi editing mode and give out a detailed cheat sheet with the default keyboard mappings for this mode.
The difference between the two modes is what command each key combination (or key) gets bound to. You may inspect your current keyboard mappings with bash’s built in bind command:
$ bind -P abort can be found on "\C-g", "\C-x\C-g", "\M-\C-g". accept-line can be found on "\C-j", "\C-m". alias-expand-line is not bound to any keys ...
To get into the vi editing mode type
$ set -o vi
in your bash shell (to switch back to emacs editing mode, type set -o emacs).
If you are used to a vi text editor you will feel yourself at home.
The editing happens in two modes - command mode and insert mode. In insert mode everything you type gets output to the terminal, but in the command mode the keys are used for various commands.
Here are a few examples with screenshots to illustrate the vi editing mode.
Let ‘[i]‘ be the position of cursor in insert mode in all the examples and ‘[c]‘ be the position of cursor in command mode.
Examples:
Once you have changed the readline editing mode to vi (by typing set -o vi), you will be working in insert mode.
The example will be performed on this command:
$ echo arg1 arg2 arg3 arg4[i]
Example 1:
Suppose you have typed a command with a few arguments and want to insert another argument before an argument which is three words backward.
$ echo arg1 (want to insert arg5 here) arg2 arg3 arg4[i]
Hit ‘ESC‘ to switch to command mode and press ‘3‘ followed by ‘B‘:
$ echo arg1 [c]arg2 arg3 arg4
Alternatively you could have hit ‘B‘ three times: ‘BBB‘.
Now, enter insert mode by hitting ‘i‘ and type ‘arg5 ‘
$ echo arg1 arg5 [i]arg2 arg3 arg4
Example 2:
Suppose you wanted to change arg2 to arg5:
$ echo arg1 [c]arg2 arg3 arg4
To do this, you can type ‘cw‘ which means ‘change word’ and just type out ‘arg5‘:
$ echo arg1 arg5[c] arg3 arg4
Or even quicker, you can type ‘f2r5‘, where ‘f2‘ moves the cursor right to next occurrence of character ‘2‘ and ‘r5‘ replaces the character under the cursor with character ‘5‘.
Example 3:
Suppose you typed a longer command and you noticed that you had made several mistakes, and wanted to do the correction in the vi editor itself. You can type ‘v‘ to edit the command in the editor and not on the command line!
Example 4:
Suppose you typed a long command and remembered that you had to execute another one before it. No need to erase the current command! You can switch to command mode by hitting ESC and then type ‘#‘ which will send the current command as a comment in the command history. After you type the command you had forgotten, you may go two commands back in history by typing ‘kk‘ (or ‘2k‘), erase the ‘#‘ character which was appended as a comment and execute the command, this makes the whole command look like ‘ESC 2k0x ENTER‘.
These are really basic examples, and it doesn’t get much more complex than this. You should check out the cheat sheet for other tips and examples, and try them out!
To create the cheat sheet, I downloaded bash-2.05b source code and scanned through lib/readline/vi_keymap.c source code file and lib/readline/vi_mode.c to find all the default key bindings.
It turned out that the commands documented in vi_keymap.c were all documented in man 3 readline and I didn’t find anything new.
After that I checked bashline.c source file function initialize_readline to find how the default keyboard shortcuts were changed. I found that ‘CTRL-e‘ (which switched from vi mode to emacs) got undefined, ‘v‘ got defined which opens the existing command in the editor, and ‘@‘ which replaces a macro key (char) with the corresponding string.
The cheat sheet includes:
- Commands for entering input mode,
- Basic movement commands,
- Character finding commands,
- Character finding commands,
- Deletion commands,
- Undo, redo and copy/paste commands,
- Commands for history manipulation,
- Completion commands,
- A few misc. commands, and
- Tips and examples
PDF format (.pdf):
Download link: bash vi editing mode cheat sheet (.pdf)
Downloaded: 5510 times
ASCII .txt format:
Download link: bash vi editing mode cheat sheet (.txt)
Downloaded: 1957 times
LaTeX format (.tex):
Download link: bash vi editing mode cheat sheet (latex .tex)
Downloaded: 509 times
This cheat sheet is released under GNU Free Document License.
Discuss it on catonmat forums!
Did you like this post? Subscribe to my posts!

(5 votes, average: 4.6 out of 5)
|
|
|


January 8th, 2008 at 11:31 pm
[…] Read more Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages. […]
January 8th, 2008 at 11:40 pm
Thanks! It’s finally here after a long wait
It works equally well on ksh too.
January 9th, 2008 at 12:00 am
Ankush, yeah, it’s finally here
Great to hear that it works well on ksh, as well!
Next cheat sheets are going to be on Linux IPTables packet flow (which I created some 4 years ago), and I’ll have another one on bash’s history expansion.
January 9th, 2008 at 2:07 am
I had no idea this was possible! Thanks a lot!
January 9th, 2008 at 9:11 pm
Same loyal readers, great articles everytime.
No, u slona vse ravno …
Thanks, will test tonight
January 11th, 2008 at 10:54 pm
Hello Peteris,
Thanks for visiting and commenting on our blog! We are plesantly surprised that you came upon our blog.
Your video lectures are quite impressive! And we, at the EIC (www.thehnoeic.wordpress.com)in Maryland, hope you get into MIT
Thanks,
Shaj Mathew
January 18th, 2008 at 11:11 am
[…] tēmu par linux/unix vides konsoles tipa teksta redaktoriem, gribētots pieminēt Vi Cheat Sheet jeb vi komandu sarakstu, kā arī nelielu aprakstu ar piemēriem, ko ir sagatavojis Pēteris. Pirms kāda laika viņš ir […]
January 18th, 2008 at 5:40 pm
Is there a way to tell visually if you are in command mode or insert mode from the terminal in a visual way? Like in vim you can setup the INSERT to display when you are in insert mode. Thanks.
January 18th, 2008 at 5:55 pm
Brian, as far as I know it is not possible to visually tell whether you are in insert mode or command mode.
January 19th, 2008 at 12:40 pm
In the 1st example you don’t need to use capital B, it’s enough with just b.
January 20th, 2008 at 4:57 am
Martins, yup, I don’t need a capital B in this particular example but if argN, where N = 1, 2, …, was a more complex one like “(foo)”, then the the lowercase ‘b’ would treat ‘)’ and ‘(’ as separate words…
January 24th, 2008 at 2:33 am
[…] Working Productively in Bash’s Vi Command Line Editing Mode (with Cheat Sheet) - good coders code,… (tags: bash vi) […]
January 25th, 2008 at 12:14 pm
nice cheat sheet Peteris :),
i was wondering if it was possible to get visual feedback in what mode you currently are.
do you have any idea’s on that?
grtz
January 26th, 2008 at 3:47 am
Mischa, as far as I know that is not possible. But it’s not that confusing. I am mostly working in vi mode, and now have bound the most useful of emacs bindings to vi mode, so I got a mixed vi/emacs mode.
February 1st, 2008 at 8:13 pm
Really Helpful
February 1st, 2008 at 10:35 pm
[…] Using bash with vi bindings Filed under: Linux — 0ddn1x @ 2008-02-01 20:01:03 +0000 http://www.catonmat.net/blog/bash-vi-editing-mode-cheat-sheet/ […]
February 18th, 2008 at 11:26 pm
[…] working efficiently in bourne again shell. Previously I have written on how to work efficiently in vi and emacs command editing modes by using predefined keyboard shortcuts (both articles come with […]
February 23rd, 2008 at 3:00 am
Thanks for the guide
“… have bound the most useful of emacs bindings to vi mode, so I got a mixed vi/emacs mode.”
Can you give some tips on how to do this? Did you edit the readline source? I’d really love to have ^P in insert mode go up just as in normal mode.
February 29th, 2008 at 6:37 am
[…] of learning its ways, which are not always obvious or self-explanatory. Today I found a very good guide to increasing bash productivity using vi editing commands, and leveraging the command line history to save time and effort. Both of these articles have […]
February 29th, 2008 at 6:41 am
[…] of learning its ways, which are not always obvious or self-explanatory. Today I found a very good guide to increasing bash productivity using vi editing commands, and leveraging the command line history to save time and effort. Both of these articles have very […]
February 29th, 2008 at 6:42 am
[…] of learning its ways, which are not always obvious or self-explanatory. Today I found a very good guide to increasing bash productivity using vi editing commands, and leveraging the command line history to save time and effort. Both of these articles have very […]
May 5th, 2008 at 7:20 am
thanks for the cheats got them in time for a exam and was very helpful in remembering those syntax …. i bow to the great ones thanks a bunch keep ‘em coming see ya
June 11th, 2008 at 9:16 pm
Peteris,
Just what I needed. Thanks!
June 14th, 2008 at 12:54 am
This is killer !!!
I haven’t read anywhere about this bash’s feature
June 14th, 2008 at 8:55 pm
I toyed around with bash edit modes years ago and for some reason although I prefer vim wholeheartedly over emacs I have gotten to prefer the emacs edit mode at the commandline. I think it’s because, gnu readline is a widely used library, so therefore I can do ctrl-a to get to the front of the line in bash and in firefox text boxes and in etc etc.
The vi edit mode for bash would be nice, but like many people say it’s not really great for general computing. Since I log into over 10 different boxes for different things and get csh, bash or whatever depending, I’d rather have something that just works. On the systems I use a lot, I will customize my environment a bit, especially if my home is exported across different machines, but in general I go plain vanilla.
As long as I have a long merging history set, I’ll use whatever shell pops up by default.
Just my $0.08 or so… judging by the length.
June 14th, 2008 at 9:10 pm
Actually, where I said ‘vi edit mode for bash would be nice’ I meant, it would be nice with the following improvements.
1) easy way to switch between vi and emacs mode with a single keystroke
2) a way to see what mode I was in when in vi mode
I know there I times I would really like to be bouncing around the command line with /’s and n and hjkl and all those goodies, but I meant to say I just never have the time to switch to it and generally don’t need it.
June 14th, 2008 at 9:15 pm
Sweetness!
JT
Ultimate Anonymity
June 14th, 2008 at 10:14 pm
There is a link to the Emacs mode in the article, too. Both are very cool!
June 15th, 2008 at 5:00 am
Instead of using set -o vi you add ’set editing-mode vi’ to you $HOME/.inputrc file you have vi-keybinding-loveless in all applications that support readline. You can also set this to system wide by added this to /etc/inputrc.
Ummmmmmmm.
June 16th, 2008 at 6:24 pm
[…] Working Productively in Bash’s Vi Command Line Editing Mode (with Cheat Sheet) - good coders code,… (tags: bash cheatsheet howto Linux programming reference tips toread vi vim unix) […]
June 16th, 2008 at 9:33 pm
Hey -
Very interesting stuff. Is there any way to get this to support text objects like in vim? For example ciw for “change inner word.” This would also be great to edit command args in quotes, i.e. ci” or ci’.
June 22nd, 2008 at 6:23 am
pets head deliver frog tom university
June 22nd, 2008 at 6:24 am
look green australia me head deliver night we juicy we woman all night girl german
June 30th, 2008 at 4:30 am
[…] Working Productively in Bash’s Vi Command Line Editing Mode (with Cheat Sheet) - good coders code,… (tags: Bash Vi Vim Linux CheatSheet Reference Unix CLI Programming) […]
July 13th, 2008 at 5:46 am
australia english jhon bag bag red joke steven green
July 16th, 2008 at 5:18 pm
Looked at vi mode cheat sheet, text version. Is there an error under Basic Movement? Then, “h” s/b left and “l” s/b right. Thanks for well laid out easy to read cheat sheet.
cheers
July 22nd, 2008 at 6:28 pm
[…] Working Productively in Bash’s Vi Command Line Editing Mode (23,508 views) […]
July 23rd, 2008 at 2:38 pm
it works perfectly in cygwin !