- Published on
Learning VIM
- Authors
- Name
- Chris Postma
I'm finally fully committing to learning VIM. It's been a learning goal for the past year that I keep avoiding as other topics have taken priority. Recently, however, a close friend started teaching himself VIM and the excitement caught on. I could no longer resist.
I think it's also beneficial to learn as soon as possible because once you commit the basics to memory, you can continue to train it passively as you work. It's a skill that grows with you everyday while you work. Therefore, I plan to get myself to the same speed as my previous configuration with VIM as soon as possible so that I can begin training it passively while I take on new topics.
VIM stands for Vi IMproved, a vi-derivative text editor based on the original Vi editor that was released in 1976. VIM was written by Bram Moolenaar and released in 1991. VIM comes with Linux, BSD, and macOS. It's a small and fast program that can be run in a terminal.
Some of the main benefits of VIM are as follows:
- It is omnipresent -- available on most machines and bindings exist for most editors
- It has a low memory footprint and is fast
- Highly configurable via simple text files
- It uses commands that can be composed together to accomplish complex text-based tasks
VIM is also a modal editor as opposed to a modeless editor. Modal editors offer multiple types of interaction modes which are each optimized for specific tasks. The original intent of modal editors was to allow users to perform complex operations without the use of a mouse, which may not have been available at the time. This is still a primary benefit today, the ability to quickly move through and edit files without a mouse.
A few of the modes available are as follows:
- Normal mode - movement (default)
- Insert mode - editing
- Visual mode - selecting
- Visual line mode - selecting multiple lines
- Command mode - do things like write buffer, quit, etc.
- Replace mode - replace text at position
As part of my learning, I am following this video series by The Primeagen wherein he provides chunks of commands to get started so as to not be overwhelmed. Below are some notes from each video that I am taking to aid my learning.
Vim Learning Path (1 week practice minimum per chunk)
First Chunk
Command | Description |
---|---|
h/j/k/l | left/down/up/right directions |
w/b | forward/backward by word |
e | move to the end of the next word |
i | insert mode |
a | insert mode after cursor |
A | insert mode at end of line |
gi | insert mode at same position where insert mode was last used |
esc | exit insert/visual mode |
ctrl + c | exit insert mode |
crl + [ | exit insert mode |
yy | yanks a line |
p | paste line one line below |
dd | delete line current line |
u | undo last command |
x | delete under cursor, single char |
shift-v (V) | highlights a line |
j or k | to select lines up or down |
y | yank and save to register |
d | deletes and saves to register |
p/P | to paste register below/above cursor |
v | highlights current letter (use movement to continue selecting) |
:w | save your file (if in vim proper) |
:q | quit after saving |
:q! | quit without saving |
. | repeat last command |
Second Chunk
Command | Description |
---|---|
o/O | insert new line and enter insert mode below/above |
shift-p (P) | paste above |
i/a | insert mode left of cursor, right of cursor |
I/A | insert mode beginning/end of current line |
$/0 | go to end/beginning of current line, movement only |
/ | search for ie: /word |
* | next occurrence of whatever is under your cursor |
n/N | go to next/previous occurrence once set with * or /<search term> |
Third Chunk (Horizontal Speed)
Command | Description |
---|---|
fx/Fx | search forward/backward for x, land on result |
tx/Tx | search forward/backward for x, land one space before result |
; | after search, use to move forward to next instance |
, | after search, use to move backward to previous instance |
:/, | move forward/backward through search result from f/t |
x | delete single character |
s | delete single character + enter insert mode |
c | just like delete (d ) but goes into insert mode as well |
shift-d (D) | delete full line from current position |
shift-c (C) | delete full line and enter insert mode from current position |
shift-s (S) | delete full line and enter insert mode |
Some examples:
Command | Description |
---|---|
dt) | delete everything up until ) but not ) itself |
yt) | delete everything up until ) but not ) itself |
df) | delete everything up to and including the ) |
dT( | delete everything back to, but not including the ( |
dF( | delete everything back to and including the ( |
vf) | select everything up to ) |
ct) | delete everything up until ) and enter insert mode |
cf) | delete everything up to and including the ) and enter insert mode |
Fourth Chunk (Vertical Speed)
Command | Description |
---|---|
gg/G | go to top of document/bottom of document |
:100 | go to line number |
100G | go to line 100 |
{ or } | jump up/down to next empty line (paragraph) |
% | if on a bracket/brace, move to matching bracket/brace |
di} | delete inside } , such as if inside an if statement |
ci} | delete inside } and enter insert mode |
yi} | copy inside } |
cip | cut entire paragraph |
vi[ | copy everything inside square brackets |
va[ | copy everything inside square brackets and including brackets |
da{ | delete everything inside curly brackets including the brackets |
shift+i (I) | enter insert mode before first non-blank character in same line |
Some examples:
Command | Description |
---|---|
4j | jump down four lines |
12k | jump backward by 12 line |
4w | jump forward four words |
6b | jump backwards four words |
100G | go to line 100 |
ctrl+d , ctrl+u | page down, page up |
diw | delete word, cursor can be anywhere in word |
cip | delete paragraph and enter insert mode |
yi) | copy inside parenthesis |
d2i{ | delete most immediate plus surrounding content inside { |
Other commands
Command | Description |
---|---|
gq | on a visual selection, reflow and wordwrap blocks of text |
gb | add another cursor on the next word found that matches word under cursor |
gh | preview type definition (similar to hovering over a word) |
gd | jump to local definition |
gD | jump to global definition |
ctrl+e | move screen down one line without moving cursor |
ctrl+y | move screen up one line without moving cursor |
:100 | go to line number |
>> , << | indent line |
Marking text (visual mode)
Command | Description |
---|---|
v | start visual mode, mark lines, then do a command (like y-yank) |
V | start linewise visual mode |
ctrl+v | start visual block mode |
O or o | move to other corner of block |
aw | mark a word |
ab | a block with () |
aB | a block with {} |
at | a block with <> tags |
ib | inner block with () |
iB | inner block with {} |
it | inner block with <> tags |
Esc | exit visual model |
Helpful commands learned during week 3
Command | Description |
---|---|
g; | return to last edit made |
gv | return to last selection |
yib | yank inside brackets |
== | auto indent |
cs"' | change surrounding double quotes to single quotes |
cs]} | change surrounding brackets to parens |
vibS{ | select and replace surrounding motion with brackets |
gUib | change casing within brackets to uppercase |
:%s/foo/bar | replace all instances of foo with bar in file |
[{ | jump to above curly bracket (e.g. if inside function body) |
Helpful commands/ideas learned during week 4
Command | Description |
---|---|
ctrl+f | move forward in the document |
ctrl+b | move backward in the document |
shift+h | place cursor at top of screen |
shift+m | place cursor at middle of screen |
shift+l | place cursor at bottom of screen |
z enter | move screen down and keep cursor at some position |
10gg | same as :10 |
_ | move to first non-empty character in line |
ctrl+i | move cursor to previous position, newer |
ctrl+o | move cursor to previous position, older |
shift+r | enter replace mode |
r | replace a single character |
cc | change an entire line |
g~<motion> | switch case inside motion |
g~~ | switch case of entire line |
guu | change line to lowercase |
gUU | change line to uppercase |
gU<motion> | change motion to uppercase |
gJ | append below line to current line without space at end of first line |
* | forward search for word |
# | backward search for word |
This week I started to take the Udemy course called Vim Masterclass by Jason Cannon. Much of the course is reiterating what I've already learned so far but in much more detail and with the ideas behind each command explained better than they were on YouTube.
One idea Jason shares is the correct words to refer to each optional and required part of VIM commands, such as [count]operation[count]{motion}
. This is helpful in learning how to think in VIM.
The example he uses to teach this idea is delete a word:
dw
delete word is anoperation{motion}
dh
delete one character to the left is the same asX
dl
deleted one character to the right is the same asx
dk
delete current line and one above itd0
delete from cursor to start of lined$
delete from cursor to end of lineD
the same as above but an alterante3dd
delete line three timesd3w
delete 3 words2d3w
delete three words two times
linewise command - a command that operates on an entire line
characterwise command - a command that operates on a character
!
forces a command in vim!
can be used to execute external commands:help
opens vim help:help <COMMAND>
A register is a place where cut and copy text is stored, similar to the system clipboard. The unamed register is commonly referred to as the default register.
There are many types of registers in VIM:
- Unnamed
- Numbered
- Named
Registers are preceded by a "
.
- Unnamed register =
""
- Numbered registers =
"0
,"1
..."9
The unnamed register contains the last text from d
, c
, s
, x
, and y
operations.
"0
holds the last text yanked (y
)"1
holds the last text deleted (d
) or changed (c
)- Numbered registers shift with each
d
orc
To view registers, issue the command :reg
"_
is known as the blackhole register. Nothing happens when sent to this register.- There are 26 named registers, from a to z.
- The capital letter of the register name will append to the register.
We can type :reg <register>
to view a specific registers content.
We can use registers with the following patterns, [count][register]operator
or [register][count]operator
.
You can repeat insert commands any number of times, such as insert 80 asterisks, which would be 80i*
and then escape. Or create five new lines with a pound character, 5o#
and then escape.
Week 5
Command | Description |
---|---|
:s/foo/bar/ | replace foo with bar, one instance only |
:s/foo/bar/g | replace foo with bar, multiple times same line |
:1,5s/foo/bar/ | replace foo with bar, multiple lines as specified |
:%s/foo/bar/ | replace foo with bar, entire document |
at or it | when editing html tags, use text objects |
dit | delete inside tags |
>i{ | indent all text between { |
The pattern for search and replace is: :[range]s/old/new/[flags]
.
This week I am also focusing on macros.
VIM macros record keystrokes into a register. To begin recording a macro, press q<register>
. Then type in the commands for the macro to record. It is generally a nice idea to make the final command a movement down to the next line to make repeating the command more convenient.
To stop record, press q
.
To replay a macro, press @<register>
. To replay the last played macro, press @@
.
Best practices:
- Normalize the cursor position, e.g.
0
- Position cursor for next replay using
j
I can replay a macro [count] times, e.g. 5@a
. I can append to a register using the capital letter of the register. E.g. qa
and then later qA
.
I can hit ctrl+g
to get the line count of the file. This can be useful when wanting to apply a macro to the entire file when it is not possible to see the last line without scrolling down. I can then issue a command such as :27,35normal @a
or current line to end of file with :.,$ @a
.
To edit a macro, I can just put the contents of the register, modify it, then yank it back into the register.
It is also possible to save macros to the .vimrc
file.
Another focus is visual mode.
- Use
v
to start characterwise visual mode. - Use
V
to start linewise visual mode. - Use
ctrl+v
to start blockwise visual mode.
I can use motions to expand the visual area. I can also use text objects to expand the visual area.
I can use most regular VIM commands in visual mode, such as ~
, c
, d
, y
, r
, u
, I
, etc.
I can use gv
to start visual mode with the same area selected as the last area selected the last time I used visual mode.
o
allows me to switch from one side of a selection to the other, vetically.O
allows me to switch from one side to the other horizontally.
In blockwise visual mode, I can use $
to select to the end of all lines, even if they have varying lengths.
Update 2023-01-15
A few very useful discoveries:
ctrl + w + hjkl
will move between buffers in VSCode's VIM plugingt
andgT
will cycle between buffersctrl + a
is used for incrementingctrl + x
is used for decrementingg ctrl + a
can be used to increment an entire paragraph if used after entering visual mode, e.g.vap
- If at the beginning of a line that has something in quotation marks or backticks, you can change from there by using
ci'
, for example, which will jump to that single quote in the line.