Follow @learnvim for more Vim tips and tricks!
One of Vim's unique feature is its modality. Most editors have one mode (insert), where Vim has 6 modes (normal, visual, insert, command-line, select, and ex). I think the 3 important ones are normal, insert, and visual.
Correction: There are seven commands as of Vim8, the new one being Terminal-Job mode. Source: :h vim-modes-intro
In this article, I will explain what they do and how to become more productive with them.
At the end of the day, what matters is using whatever editor that makes you most productive. You may not even need Vim at all.
Normal mode: overview
Normal mode is Vim's default mode. Think of it like edit mode. You might ask, "Why not make insert mode default like most editors? Why would anyone put extra effort entering and exiting a mode just to write a text?"
If you have been programming for a while, you will realize that programmers spend most of their time editing, not writing, code. A text editor's default then, should be optimized for editing, not writing. I think this is where Vim got it right.
People may find normal mode confusing. I did too. However, after using Vim for a while, I realized that having a normal mode is a blessing.
Pro tip: if Vim is your default editor, you should train yourself to habitually rest in normal mode when not typing.
Normal mode: navigation
Normal mode can be used for navigating inside a file. Since most of our time is spent reading and searching, effective navigation is an indispensable skill. Vim navigation is a broad topic so I will only touch the basics here.
Vim allows you to move between different "objects". You can move between characters (h/l
), words (w/e/b
), lines (j/k
), sentences ()
), paragraphs (}
), code blocks, and more.
Vim allows you to jump between matches with %
. If you are inside a (...)
for example, you can quickly jump between parentheses with %
.
Often we want to jump to specific string, like function findUser(){...}
. You can get there quickly by searching for /findUser
(n
to go to next match). You can search inline with f
and t
.
Our navigation can be combined with quantifiers, too.
- To go forward 3 words, instead of
www
, we can do3w
. - To go down 10 lines, instead of
jjjjjjjjjj
, we can do10j
.
Someone might object that there are simply way too many motions to remember - but you don't need to remember them all at once. Learn only the ones you need at the moment. To this day, I don't remember all of them and I still consult :h
.
Pro Tip: When you are editing, keep a lookout for actions you often repeat. Look if there is a shorter way to do it. Do it until you can type without thinking.
You can reach any location in a file with very few keystrokes.
- Is your target approximately half the page of the entire file?
50%
. - Is your target close to the end of a line?
$
. - Is your target close to a unique character (like "z")?
fz
.
If you'd like to learn more, check out these resources:
Normal mode: grammar
Normal mode is not only useful for navigating, but also for editing. Vim has 16 operators, but you can go far with just 3:
c
(change)d
(delete/ cut)y
(yank/ copy)
The wrong approach to learn vim editing is to use memorize every single key combinations to learn all the commands, for example:
dw
to delete a worddd
to delete a word in a linediw
to... uh what was it again?
The best way to utilize operators is to learn Vim grammar.
Vim grammar has one rule: Verb + Noun
. A verb is vim operator. A noun is either a motion, text-object, or search.
For example:
- delete to end of line,
d$
, follows grammar rule: verb (d
) + noun ($
). - yanking a word
yiw
follows grammar rule: verb (y
) + noun (iw
) - changing to nearest
/foo
follows grammar rule: verb (c
) + noun/foo
.
Learning how to combine Vim verbs and nouns can save you from countless hours of memorization. It also allows you to compose powerful command on your own.
If you'd like to learn more, check out:
- Learn to speak vim — verbs, nouns, and modifiers!
- Grokking Vi
- Vim as a language
- Mastering Vim Grammar
Pro Tip: learning vim grammar allows you to synthesize powerful instructions while memorizing less commands.
Normal mode: change
Vim can repeat last change with dot command (.
).
What is a change? Any content update, addition, or subtraction counts as a change. Entering insert mode, typing texts, and exiting insert mode counts as a change. Navigating does not count as a change. For example:
dw
is a changeciw
is a change3j4w
is not a changeihello<Esc>
is a change
Dot command + vim grammar can boost productivity. If we do diw
(delete + a word) and we need to delete another word, you can just press .
instead of diw
.
Always think: "is this action repeatable?" For example, I need to delete the next 3 words. I can either do: d3w
(delete + 3 words) or 3dw
(delete + a word, do it 3 times). What's the difference?
- In the first case, a change is the deletion of three words (
d3w
). - In second case, a change is &deletion of a word* (
dw
), done three times.
How is this important? What if you decided you need to delete 2 more words? If we had done the first (d3w
), our change is d3w
, we can't do .
because it will delete 3 words. It is better if we had done the second (3dw
) where a change is dw
, and we can do ..
.
By the way, Vim's undo (u
) works similarly with change: it undoes one "change" (btw, redo is C-r
).
To learn more:
:h change.txt
- How to Undo and Redo in Vim/Vi
- The “dot” command in Vim Let's go to insert mode next.
- Neil, Drew, Practical Vim
Pro Tip: Always spot for opportunity to use .
because it is powerful, and could save you tons of keystrokes. Look for repeatable change.
Insert mode: ways to enter/exit insert mode
Let's talk about Vim's second mode: insert mode. Any key you press during this mode will be displayed on screen.
Entering normal mode can be done several ways. The standard is to use i
, but I personally use these 6:
i
- insert text before cursorI
- insert text before first non-blank character in same linea
- insert text after cursorA
- insert text at the end of lineo
- Start a new line below cursor, insert textO
- start new line above cursor, insert
You can also do gi
to insert text same position where the last insert mode was.
To exit insert mode, the standard is to use escape.
If you've programmed vim a while, you start feeling the Esc
button feels too far. Here is the keyboard Bill Joy (Vi creator) used:
Notice the key arrangements. His Esc
key was roughly where tab is today. I personally map Esc
to Caps
. Some people prefer Space
or kj
or jk
for their mapping. Vim also allows you to use C-[
to exit insert mode. Your preference may be different. Use whatever feels most natural.
Resource:
Pro Tip: remap your Escape to where it is easy to reach.
Insert mode: deletion
We all make typing mistakes. Sometimes we realize right away, sometimes it took a while. Should we switch to normal mode to delete our typing mistakes?
It depends where the mistake is.
- If it is less than 5 characters, you could probably stay in insert mode and start deleting them.
- If the mistake is a few words away, it might be faster to switch to normal mode and fix it.
- If you make mistake on the entire word/ line, insert mode allows you to do mass delete:
C-w
deletes whole wordC-u
deletes whole line.
Resource:
Pro Tip: when making big mistakes, do not get into the habit of repeatedly pressing Delete/Backspace button. Find quickest way to eliminate the mistake and continue writing.
Insert mode: yank text from register
Sometimes you need to paste from register. Instead of going to normal mode, paste, and go back to insert mode, you paste while staying in insert mode with C-r
.
- To yank latest text, do
C-r 0
(from 0 register) - To yank test from "a" register, do
C-r a
To read more about register, check out:
:h registers
- Vim Registers
- Advanced Vim registers
Visual mode: 3 ways to highlight
There are 3 ways to use visual modes:
v
- individual Visual modeC-v
- blockwise Visual modeV
- linewise Visual mode
You can use gv
to start Visual mode at previous location. Press Esc
to exit.
Resource:
:h visual-operators
Visual mode: basic usage
Visual mode works like most editors' highlights:
- Highlight a body of text
- Perform an action.
For a list of visual mode operators, check out :h visual-operators
.
The common 3 are:
- change (
c
) - delete (
d
) - yank (
y
).
I think these 3 are also useful:
- dedent (
<
) - indent (
>
) - command-line (
:
)
Let's do a quick demo on this body of text. My cursor is at the start of line "echo greetings"
.
#! /bin/sh
echo greetings
echo vim
echo padawans
Using visual mode:
- To delete all
"echo"
, highlight the entire line (V
), go down to lines (jj
), then delete (d
). - To change the first line, highlight the entire line (
V
), then change (c
). - To sort, highlight to the bottom (
V2j
), then sort (:sort
). - To indent the first two lines, highlight the entire line and the one after (
Vj
), then indent (>
).
Visual mode: good or bad?
There are discussions against using Visual mode because it is considered a smell.
The argument goes like: things used with visual mode (Vjd
) can also be done without it (dj
), so why do we add extra step going to visual mode?
On the flip side, visual mode has some practical uses: visual mode provides visual indicator for your partner if you are pairing (he/she can see what you are highlighting. We do pair-programming at work so this is relatable to me). Visual mode also provides better visual aid to see your motions before performing an action.
I personally try to limit my visual mode usage to minimum. Everything I have shown you in this article technically can be done without using visual mode. Ultimately it is up to you. Are you more productive with visual mode? Use it. Are you more productive without it? Don't use it. Try both approach, then decide.
Resource:
Visual mode: multiple texts insertion
Visual mode allows you to edit on multiple lines. You can do this normally with blockwise Visual mode (C-v
).
Let's say I have:
const one = 'something'
const two = {some: 'object'}
const three = [1,2,3]
And I want to add ;
at the end of every single one. Here is how you can use visual mode to do it:
C-v
to activate block-wise Visual mode2j
to go down$
to go to the endA
to go insert mode- type
;
Esc
to exit Visual mode.
After step 6, you'll see that ;
has been inserted into ALL three lines.
You can do multi-line visual mode block-wise insertion with eithe I
or A
. Operators (delete (d
), yank (y
), change (c
), etc) would work here as well.
Conclusion
Vim is a modal editor. Most text editors today are modeless editors. As programmers, we spend most of our time editing, not writing new code. The default text editor mode should be tailored for editing, not writing. The ability to switch between modes is an indispensable feature, in my opinion.
Thanks for reading this far. I hope you learned a bit more about Vim and why some people love it. At the end of the day, Vim is a tool. As programmer, we need to be versatile and use the best tool for the job.
Happy coding!
Resources
:help
:h vim-modes-intro
:h visual-operators
:h change.txt
:h motions
:h registers
- Ilic, Jovica, Mastering Vim Quickly
- Neil, Drew, Practical Vim
- Modeless vs Modal Editors
- Seven habits of effective text editing
- VIM Super Fast Navigation
- Moving around in Vim
- Learn to speak vim — verbs, nouns, and modifiers!
- Grokking Vi
- Vim as a language
- Mastering Vim Grammar
- How to Undo and Redo in Vim/Vi
- The “dot” command in Vim
- Vim Registers
- Advanced Vim registers
- How to quickly delete words in insert mode in vim
- Delete line in insert mode
- Mastering the vim language
- Is visual mode actually a smell? (discussion)