DEV Community

Cover image for Vim A to Z - Literally
Omer Hamerman for ProdOps

Posted on • Edited on • Originally published at prodops.io

Vim A to Z - Literally

TL;DR - ish: This post is a list of options and keystrokes in Vim, if this is the first time you're getting to know them, take your time, read some, memorize and go back once you feel comfortable with taking more in. Vim is overwhelming if you're just getting started, but it's even more rewarding!

Vim has been one of the best adoptions and projects I took upon learning in the last several years. I've written quite a bit about it; an introductory post after reading the awesome Practical Vim and some advanced features.
I've been also collecting a long list of tips and notes which are open sourced,
but recently I felt there's an educational aspect to Vim that is being missed; Vim has phonetic logic to every keystroke, by understanding them and the logic behind them, one may feel much easier making their way through the steep learning curve.

The following list has both original intentions of Vim authors, and some additions I made up myself to help myself remember what I was doing when I first started. How is it going to work - Vim has a special and different meaning to each character, its lower or upper case, and obviously the motions it is combined with. The list will go through the alphabet mentioning each case with useful and notable tips.

Conventions: Vim keystroke sequences are in code blocks and from time to time are followed by <CTRL> or <ESC>, these are marked differently as they are mapped differently in different keyboards. There's also significance to where a sequence begins; so, an example would include [start: x] marking the character when the cursor is at before the sequence.


So, without further ado, here's my Vim A --> Z list...

A - Append, Amend

Lower case a will transition you into insert mode to the character on the right of the current location.
Example: [start: W] at WRD ("W"): use this sequence: aO<ESC>, the cursor will end up back in normal mode having WORD written; a starts editing to the right of W, O is inserted, and <ESC> throws back to normal mode.

Upper case A would have the same effect but in the end of a line, so if my text is TWO WORD and I run AS.<ESC> I'll end up with TWO WORDS..
Tip: its counterpart is I; the same effect as A but at the beginning of the line.

B - Backwards, Beginning

Lower case b will move to the beginning of the current word, if the cursor is already there, it'll go to the previous word's first character.
B would do the same but to the beginning of the line (starting to get the idea?). I like to think about the capital versions of the Vim keystrokes and strong stokes.
Tip: its counterpart stroke is e (end) or w (next word's beginning).

C - Change

c is usually followed by a motion; c combined with the listed above b, would take you to insert mode changing everything from the current location to the beginning of the word.
Example: [start: R] in WORD, hit cbX, you end up with XRD.
Since any Vim motion is relevant here, it can be run with some powerful combinations; e.g. ciw means "change in the word", deletes the word while transitioning to normal mode.
C in the case would change the entire line to its end from the current location.
Tip: D would do the same (as we'll see in a moment) but without the insert mode part.

D - Delete

d would delete any motion that would follow, so diw would be "delete in the word" which is similar to ciw but the end result is still normal mode.
Useful combinations:

  • dip "delete in paragraph"
  • dgg - "delete from here up"
  • dG - "delete from here down"
  • dd "delete the current line" Tip: has a small brother x that has roughly the same effect but on a single character.

E - End

e: you guessed it - takes you to the end of a word or the End of a line.

F - Find!

A very useful motion; f would find the character it's combined with; e.g. fX would find the next X appearance in a sentence. Using F would have the same effect but in a backward search.
Tip #1: combined with ; (next result), "find" becomes a very powerful motion in Vim to quickly find a character instead of moving towards it in slower or more keystrokes. ; works both backward and forward - depends on the original motion (f vs F).
Tip #2: f can be combined with other motions, to name a useful one - marking a visual block until a certain point including the point, one would use vfx where x is the character in question. Let's put this into a more solid example; consider the line "Here sleeps the hairy brown fox" [start: H], and the goal is to visually mark "Here sleeps the hairy", a sequence can be vfy as in "Visually mark until char y including." Sub-tip: if the end result wanted is the same but without the last char, use t as in vty to "Mark to y".


We're done with f - let's take a look on a visual that shows some of it:

Visual Vim motions in a line

G - Go

This is actually my own interpretation, g goes places but with a bit different motions, Vim authors did not provide a significance to it on its own. Useful combinations: gg to go the very beginning to the file, while G would do the same but to the end.
Tip: Find a comprehensive list of all the options with :help *g*.

H - An arrow replacement

h is one of the "special four" hjkl which are the basic arrows in Vim (sides, up & down), where h is used for left.
Addition suggested by Giuseppe Caruso:
H will take the cursor to the top of the page.

I - Insert

i is one of the most useful keystrokes in Vim, maybe only second to <ESC>. i transitions from normal mode to insert mode. In the same way I does the same but at the beginning of the line.
Useful (and advanced) Tip:
Since I edits the beginning of the line which is not a usual requirement of a user, I find myself requiring a prefix to a block or a number of lines. Using visual block (which we'll cover below with V) one can mark a visual block with <CTRL>v then when a block is marked, use I to start editing. When the edit is done hit <ESC> to
go back to normal mode but with the entire block prefixed with the change.

Example: [start: L] hit <CTRL>vjjI*<SPACE><ESC>:



Line one
Line two
Line twenty-two


Enter fullscreen mode Exit fullscreen mode

Can you guess the result?
Let's review the motions:

  1. Start a visual block (<CTRL>-v)
  2. Jump down twice (jj)
  3. Insert an asterisk followed by a space at the beginning of the line
  4. Go back to normal mode, and behold: MAGIC 😮


* Line one
* Line two
* Line twenty-two


Enter fullscreen mode Exit fullscreen mode

J - An arrow replacement

j is one of the "special four" hjkl which are the basic arrows in Vim (sides, up & down), where j is used for down.
Tip #1: j happens to be a rare English letter, and the key on a keyboard happens to be quite far considering its extensive use in the switch back to normal mode,
there's a convention of mapping jj to <ESC> and use the already-in-read key to make the transition.
Here's the mapping for your convenience: imap jj <Esc>. As with any other change (especially in Vim) it takes a while to get used to, but it's very much worth the wait.
Tip #2 suggested by the reader @argon2008aiti:
J (capital) joins the line below after the cursor, this is useful when the cursor is standing at the end of a line and the line below should be joined to the same point. Usually, a user would go down a line, find the beginning of a sentence and delete backward to the earlier location.

K - An arrow replacement

K is one of the "special four" hjkl which are the basic arrows in Vim (sides, up & down), where k is used for up.

L - An arrow replacement

L is one of the "special four" hjkl which are the basic arrows in Vim (sides, up & down), where l is used for right. (An absurd thinking about the concept of this post, one would expect "l" to be used for left :+1)... :trollface:

M - Mark

Vim supports a powerful marking feature. Using Registers, it can save locations in a document with m like so: ma would save the current location to the register a, go back to it from each other location with 'a (a can be replaced here with any other character that can represent a register).
Relevant tip: if you did not remember to mark your location, which we normally don't in the flow of work, '' will always jump back to the previous location.
Addition suggested by Giuseppe Caruso:
M will move the cursor to the middle of the page (same as zz).

N - Next

n will go to the next result of a search. Since this is a circular motion (next after the last result is the first), n is used to go forward and N to go back.
Relevant info: to those who are not familiar, search in Vim is triggered with / followed by search text. Beyond the obvious use-case of searching an appearance or a specific result, this is a useful motion; even if you already know and see the location of your target. Moving a cursor sometimes takes more keystrokes than just searching for the word (and maybe combining it with an n).

O - Open line

Not certain whether this was, in fact, the author's intention, o does exactly that: it opens a new line below the cursor. Using O would do the same but above.

Here's something I did not yet figure to a level I'm satisfied with: o opens a line and transitions to insert mode, there are many times I'd like to open a new line below or above the cursor without adding new text, I've tried different mappings and combinations, but ended up back where I started with o followed by <ECS>. I'll use this stage to ask - had anyone found a better solution to this very specific yet annoying problem?

P - Paste, Paragraph

p's most common usage is pasting something that has been yanked or cut (remember Vim treats delete as cut too). pasting is done after the cursor while P does it before.
Tip: Registers come in handy once again; paste from a register by combining it before the motion: with text saved into the a register, "adiw would "delete in word and save to the a register". Use the register's content and paste it using "ap ("paste after the cursor from register a").

Q - Quit (and Reqord macros)

This bad spelled word is how I initially memorized where macros are starting their way :)
q is used to quit Vim, either with :q which is the basic, :qw to quit and write, q! to quit even if work hasn't been saved and more.
Having that said, as a motion, q is used to record a sequence of operations and repeat them, or as this is called in the Vim terminology "macros", more on macros (A-lot more) in my next and very soon blog post.
For the time being here's a quick tip: Recording is done into registers just like yanking and cutting; use qq to record into register q, and do run a sequence of commands. Another hit on q would stop the record making it available for execution with @q.

R - Replace

While r is as simple as replacing the current character with another (ra will replace the current location with a), R is a powerful one yet rare; R would transition into the odd replace mode, which is essentially an insert mode that overrides characters. When block-width matters or there's an order of alignment, this small feature comes in very handy.

S - Substitute

Being honest here - s is the one motion of this entire list I did not recall and as such, I have never used it. I find it quite unnecessary having c motion that transitions into insert mode with the combined motion. s would do the same while editing "on the spot": substituting the current character and editing from thereon. Useful when the end result is a substitution of a single character, yet this could be achieved with x&i or r&<ESC>.
Using S would substitute the current block while keeping you in insert mode.
Tip: I personally map <leader>ss to toggle Vim's spell checker, (yes it has one), here's the mapping:



nnoremap <leader>ss :setlocal spell spelllang=en_us<CR>


Enter fullscreen mode Exit fullscreen mode

Another "s" map I have is ss to disable the highlight after searching a word resulting the highlights of all results, here it this map from my .vimrc:



nnoremap ss :noh<CR>

Enter fullscreen mode Exit fullscreen mode




T - To

Mentioned previously in the F section, t means "do something until" (or to); vtx means "visually mark to x" (without x). Or dtf (this is just a random example...) would be "delete to char f".

U - Undo

As simple as that, u would undo changes. It's big brother U has a rather strange result - undoing changes done in the same line since the cursor last moved into it.

V - Visual

v is your way to mark chars / words / lines / blocks in Vim in order to do something with it; deleting, yanking or maybe indenting (>>).

W - Word

This motion was mentioned multiple times above as it comes hand in hand with end & back; w is a motion that jumps to the next beginning of a word.
W is quite interesting: while w is the current word, W is the "word block", which means it includes all characters between two spaces.
Example: "some-name,still-no-space" is not one word, but Vim would consider it one if addresses as W.
How is this useful? With motions of course: viW is "visually mark a block in the Word" (between the two closest spaces). Obviously, this can be combined with any other motion in Vim.

X - Cross out?

The one letter in the English alphabet which I couldn't have found an actual phonetic resolution; x would remove a single character under the cursor. (Remember: s would do the same resulting in insert mode, x would not).
X would be the same but backward.

Y - Yank

One of the most useful and basic motions in Vim - y copies text, by default into the unnamed register, ready to be pasted back in another location. Its big brother Y would copy the entire line with one stroke (I'm used to doing the same with yy).

Z - Welcome it! Last and pretty useless on its own: "Z"

While on it's own z has no effect (:help z), it's in charge of a useful Vim feature called "folding", where the user can wrap text and fold into collapse & extendable blocks, read about it some more in my Vim notebook.
ZZ is the quick way to save and exit - yes, your complicated and physically challenging :wq! is way too much (on Vim and on your body).

Additions suggested by Giuseppe Caruso:

  • zz places the line in the middle of the buffer
  • zt cursor line at top of the window
  • zb cursor line at bottom of the window

And there it is! The list is complete.
Not covered (but will be in a soon-to-be-published piece): all other symbols available in a keyboard, featuring the powerful . command, the macros' @@, the regex family of $^..., the small but powerful % and many many more.

How to use this list? After reading it, I suggest trying to go through the alphabet and memorizing the phonetic meaning of each one, maybe even turn them to flashcards! After understanding them, combining motions, and utilizing the least-key-strokes concept in Vim, becomes and an arsenal of tools rather than mental combat.


Thank you for reading this far!
My name is Omer, and I am an engineer at ProdOps — a global consultancy that delivers software in a Reliable, Secure and Simple way by adopting the DevOps culture. Let me know your thoughts in the comments below, or connect with me directly on Twitter @omergsr. Clap if you liked it, it helps me focus my future writings.

Top comments (30)

Collapse
 
caruso profile image
Giuseppe Caruso • Edited

Tim Pope's Vim Unimpaired has a nice shortcut (among some other very useful ones) to add empty lines above or below current one:

There are linewise mappings. [<Space> and ]<Space> add newlines before and after the cursor line. [e and ]e exchange the current line with the one above or below it.

Collapse
 
omerxx profile image
Omer Hamerman

This is fantastic. That's why I love this community. Thanks buddy

Collapse
 
caruso profile image
Giuseppe Caruso

Thanks to you for taking the time to write this article. #vim rocks.

Collapse
 
worc profile image
worc

B and E might be custom commands on your end? on a completely unmodded version of vim on my mac those commands aren't working. but the regex-ish ^ and $ definitely work to move you to the beginning or end of the line in command mode.

stackoverflow.com/questions/105721...

Collapse
 
xexyl profile image
xexzy

They're not custom, no.

Try :help B' and:help E'.

Hint: WORD versus WORDS.

And 0 also takes you to the beginning of the line if you didn't know.

Collapse
 
caruso profile image
Giuseppe Caruso

A small but important clarification: 0 brings the cursor to the beginning of the line, while ^ brings it to the first character of the line. I.E. the first character, no matter if it's at column 1 or 1+n (that's is no matter what's the indentation of the line).

Collapse
 
worc profile image
worc

weird, they don't work on mac vim out of the box. there must be a setting that gets flipped or changed that's not mentioned here.

Thread Thread
 
omerxx profile image
Omer Hamerman

Hey @worc any chance for an exact version?

Thread Thread
 
worc profile image
worc

a vim --version prints this:

VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Jun 19 2019 19:08:44)
Included patches: 1-503, 505-680, 682-1283, 1365
Compiled by root@apple.com
Normal version without GUI.  Features included (+) or not (-):
+acl             +file_in_path    -mouse_sgr       +tag_old_static
-arabic          +find_in_path    -mouse_sysmouse  -tag_any_white
+autocmd         +float           -mouse_urxvt     -tcl
-balloon_eval    +folding         +mouse_xterm     -termguicolors
-browse          -footer          +multi_byte      -terminal
+builtin_terms   +fork()          +multi_lang      +terminfo
+byte_offset     -gettext         -mzscheme        +termresponse
+channel         -hangul_input    +netbeans_intg   +textobjects
+cindent         +iconv           +num64           +timers
-clientserver    +insert_expand   +packages        +title
-clipboard       +job             +path_extra      -toolbar
+cmdline_compl   +jumplist        -perl            +user_commands
+cmdline_hist    -keymap          +persistent_undo +vertsplit
+cmdline_info    +lambda          +postscript      +virtualedit
+comments        -langmap         +printer         +visual
-conceal         +libcall         -profile         +visualextra
+cryptv          +linebreak       +python/dyn      +viminfo
+cscope          +lispindent      -python3         +vreplace
+cursorbind      +listcmds        +quickfix        +wildignore
+cursorshape     +localmap        +reltime         +wildmenu
+dialog_con      -lua             -rightleft       +windows
+diff            +menu            +ruby/dyn        +writebackup
+digraphs        +mksession       +scrollbind      -X11
-dnd             +modify_fname    +signs           -xfontset
-ebcdic          +mouse           +smartindent     -xim
-emacs_tags      -mouseshape      +startuptime     -xpm
+eval            -mouse_dec       +statusline      -xsmp
+ex_extra        -mouse_gpm       -sun_workshop    -xterm_clipboard
+extra_search    -mouse_jsbterm   +syntax          -xterm_save
-farsi           -mouse_netterm   +tag_binary
   system vimrc file: "$VIM/vimrc"
     user vimrc file: "$HOME/.vimrc"
 2nd user vimrc file: "~/.vim/vimrc"
      user exrc file: "$HOME/.exrc"
       defaults file: "$VIMRUNTIME/defaults.vim"
  fall-back for $VIM: "/usr/share/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H   -DMACOS_X_UNIX  -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
Linking: gcc   -L/usr/local/lib -o vim        -lm -lncurses  -liconv -framework Cocoa
Collapse
 
xexyl profile image
xexzy

Good list; I've used vi since the 1990s and exclusively vim since the early 2000s and there were some I never considered like `dip'. A few comments though.

First of all: look at vimtutor(1) (or just try vimtutor at the command line).

Rather than use what would be in some contexts an anchor to get to beginning of line (i.e. '') you can just use `0' instead. No need to use shift that way.

G: You can also just do G to go to line .

Arrows: Do people actually use those? Interesting... I knew they worked but I've never used them. Started out with h j l k and never looked back. Maybe it wasn't even possible in vi but I've always felt it far more natural to use the same area as if you were typing than to have to move your hand away. As for the h j l k you can also specify a count (never tried with the arrow keys for the above reasons) e.g. 5j goes down five lines.

I: Actually I often enough do insert to the beginning of the line but I tend to use 0i instead. It's just as quick if not faster and it keeps in the theme of go here and do this.

Marks: just like in the pager less (and maybe more - I've not used that in decades now...)

N: But if you're searching backwards (?) it is the reverse: N goes forward, n goes back.

Opening a line without insert: If there is I'm unaware of it but I can say that's not what the O/`o' commands are designed to do - it's as you say to go into insert mode.

:qw: Another way is just ':x'

s: But surely you have however used :s? I rely on it very often. The fact it supports regular expressions (so too does searching for that matter) makes it immensely valuable.

:ZZ: Just like :x (I didn't know :ZZ)

Another you didn't mention (well - not as examples): de or 5de (etc.)

Collapse
 
a5537 profile image
A5537

Maybe it's just a typo, but since : denotes VIM command mode, the "save and quit" shortcut is ZZ in normal mode and not :ZZ. By the way, there's another normal mode combination ZQ which acts like :q! or "force quit without saving".

Collapse
 
omerxx profile image
Omer Hamerman

Thank you!
I'm honored to read such a comment from such an experienced use.

Re arrows: you'd be surprised.. people use custom settings to disable their kb arrows just for that.

Re "I" personally I use it when it comes up, and I always prefer least keystrokes, that's me..

Re Marks: I use it quite often, honestly, it's always ma and mb, rarely something else

Re: Correct! Will fix

Re s: nope, but that's why I do these posts, to learn or to be taught by the community ;)

With your permission, I'd like to add your corrections with the appropriate credit

Collapse
 
caruso profile image
Giuseppe Caruso

Finally, z doesn't take care only of folding, but also of the line position in the buffer by scrolling:

  • zz places the line in the middle of the buffer
  • zt to the top
  • zb to the bottom

Thanks again for the article! Keep on spreading the world about #vim! 🤓

Collapse
 
omerxx profile image
Omer Hamerman • Edited

Important clarification and additions, with your permission I'd like to add your comment with a credit :)

Collapse
 
caruso profile image
Giuseppe Caruso • Edited

Then, you can also add H for moving cursor, without scrolling the page, to the Head, T to the Tail and M (I am not sure by hearth, check this last out) to the Middle. 😉

Collapse
 
caruso profile image
Giuseppe Caruso

My pleasure.

Collapse
 
aminnairi profile image
Amin

Hey there, thanks for your article. A good refresher!

By the way, I may be wrong but I think that you can open a new line above by just pressing O instead of o. But maybe I didn't quite catch what you wanted to do.

Collapse
 
xexyl profile image
xexzy

They mean without going into insert mode. What is being said is both O' ando` take you into insert mode and often a new line without insert mode would be useful.

Probably it isn't that way because by adding a line you're technically inserting into the file itself.

Collapse
 
simonced profile image
simonced

Nice article.
Continuing with z, zf will create a fold on what is selected.
za will toggle folds. I use those all the time.

Also, zl will scroll right (good for long lines).
and zh goes left.
You can also scroll more than 1 character at a time like so:
z20l.

Happy Viming.

Collapse
 
omerxx profile image
Omer Hamerman

Thanks for the additions! Some stuff, like folds (which I also use from time to time) I left out to try and focus on things that matter and make phonetic logic. I linked to my Vim notebook on Github where it goes further to explain.

Collapse
 
winstoncodes profile image
winstonCodes

Great list! One correction: B and E move by word blocks (like W) and not to the beginning or end of the line.

Can't wait to see more of your Vim-related content. Learning Vim has been one of the funnest sagas in my development journey.

Collapse
 
omerxx profile image
Omer Hamerman

Thanks!
You are 100% correct, I think most / some Vim "flavors" (non-vanilla Vim configurations people start with) are already preconfigured with B / E actually targetting the end / beginning of the line. I'll double-check myself and fix, but as far as the docs go you are totally right!

Regarding the next posts: I have one waiting to be completed discussing macros. It would be much shorter though :)
If you've got any ideas / things you'd like me to cover let me know! I'm getting to learn so much myself doing these it's incredible

Collapse
 
argon2008aiti profile image
argon2008-aiti

J: Join line below cursor to current line.

I find myself using this often when refactoring code.

Collapse
 
omerxx profile image
Omer Hamerman

You're right! Using it myself quite often. Adding to the list.

Cheers

Collapse
 
jacobherrington profile image
Jacob Herrington (he/him)

This is awesome! Thanks 😁

Collapse
 
omerxx profile image
Omer Hamerman

You're welcome! :)

Collapse
 
hamidrezakp profile image
Kaveh

Hi. Very good list but you have a mistake:
dg - "delete from here up" must be dgg.

Collapse
 
omerxx profile image
Omer Hamerman

Thanks man!
Fixed