Many people bounce off Vim because they try to memorize shortcuts without learning the underlying composition rules. Vim is not “ a bag of hotkeys ”; it ’ s modal editing + a small set of motions and operators that combine into a workflow you can repeat across files, languages, and machines. This post focuses on the 80% you ’ ll actually use daily, then shows you how to scale to the remaining 20% by composing patterns rather than hunting for one-off commands.
The core idea: modes + composable operations
Vim is built around a simple loop:
- Move to what you want to change (motion)
- Select the scope (implicitly by the motion, or explicitly via Visual mode)
- Apply an action (operator) like delete/change/yank
If you learn the grammar, you stop “ remembering keys ” and start “ speaking Vim ”.
The essential modes
- Normal mode: navigation and commands (default when Vim starts)
- Insert mode: typing text
- Visual mode: selecting text (character/line/block)
- Command-line mode:
:commands (save, search/replace, settings, etc.) - Replace mode: overwrite characters
(
R)
Rule of thumb: spend most time in Normal mode; treat Insert as a temporary detour.
To return to Normal mode from anywhere: press Esc.
Operators and motions (the “ Vim grammar ”)
Common operators:
ddeletecchange (delete + enter Insert)yyank (copy)
Motions / text objects define “ how much ”:
wnext word,bprevious word0start of line,^first non-blank,$end of lineggtop of file,Gend of file,{number}Ggo to line- text objects:
iwinner word,ipinner paragraph,i"inside quotes, etc.
Examples you should internalize:
dwdelete wordd$delete to end of lineciwchange inner wordyipyank paragraph
File operations (save, quit, open)
These are command-line mode (:) commands:
:wsave (write):qquit:wq/:xsave and quit:q!quit without saving:e filenameopen/edit another file:saveas filenamesave as a new file (similar to:w <path>)
Movement and scrolling (fast navigation)
Basic cursor movement:
h/j/k/l: left/down/up/right (use this only when learning)w/b: next/previous word0,^,$: line start / first non-blank / line endgg,G,{number}G: top / bottom / go to line
Screen/page movement:
Ctrl+f/Ctrl+b: page forward/backCtrl+d/Ctrl+u: half-page down/up
Practical tip: combine search with motion. Most movement should be “ jump ” not “ crawl ”.
Delete, yank, paste, undo/redo
Delete
xdelete character under cursordddelete current lined{motion}delete a range defined by a motion (dw,d$,dG, etc.)
Yank (copy)
yyyank current liney{motion}yank a motion-defined range (yw,y$, etc.)
Paste
ppaste after cursor (or below the line)Ppaste before cursor (or above the line)
If you paste large blocks and auto-indentation/comments get in the way, consider temporarily enabling paste mode:
1 | :set paste |
Turn it off after:
1 | :set nopaste |
Undo/redo
uundoCtrl+rredo
Cut (move text) as “ delete then paste ”
There is no separate “ cut ” command: it ’ s just delete + paste.
Example: move a line elsewhere:
dd(delete the line — it goes into a register)- move cursor
pto paste
Useful command-line mode settings
These help daily use and debugging:
:set numbershow line numbers:set relativenumberrelative numbers (great for5j,10k):nohclear search highlight:map/:verbose mapinspect key mappings (useful for conflicts):!<cmd>run a shell command (e.g.,:!ls)
Windows, splits, and tabs (work on multiple views)
Splits:
:split/:sphorizontal split:vsplit/:vspvertical split- move between windows:
Ctrl+wthenh/j/k/l :closeclose current split:onlyclose all other splits
Tabs:
:tabnewopen a new tabgt/gTnext/previous tab
The swap file (.swp)
warning
If Vim detects that a file is already open (or the last session crashed), it may warn you about a swap file. You can choose to recover, open read-only, or abort.

If you don ’ t need recovery, deleting the .swp file
resolves the warning; if you do, follow Vim ’ s recovery prompt first,
then clean up the swap file.
Macros: automate repetitive edits
Macros are the highest-ROI “ advanced ” feature because they turn repetition into a one-time recording.
q{register}start recording (e.g.qarecords into registera)- perform edits (moves, deletes, inserts, etc.)
qstop recording@{register}replay (e.g.@a)@@repeat the last macro{number}@{register}repeat N times (e.g.10@a)
Example workflow:
1 | qa (start recording) |
Code folding (focus on the part that matters)
Fold commands:
zRopen all foldszMclose all foldszatoggle fold under cursorzcclose foldzoopen fold
Folding is extremely useful for large config files or long functions when you want to work locally.
Search and replace (with ranges)
Basic patterns:
:s/old/new/replace the first match on the current line:s/old/new/greplace all matches on the current line:%s/old/new/greplace across the whole file
Target a line range:
:10,20s/foo/bar/greplace only between lines 10–20
Tip: start with a narrow range, verify, then expand. Search/replace is powerful and easy to misuse.
Customization: a minimal,
safe .vimrc
Vim becomes comfortable once you set a few defaults:
1 | set number |
If you use Neovim, the equivalent config often lives at
~/.config/nvim/init.vim (or init.lua).
A practical practice plan (how to actually get fluent)
- Spend one week using only:
hjkl,w/b,0/^/$,dd,dw,ciw,/search,:%s. - Add macros (
qa,@a) for repetitive edits. - Add a few text objects (
iw,ip,i",i)) to reduce “ manual selection ”. - Only then start customizing keymaps — avoid early over-customization.
Once these are muscle memory, Vim stops feeling “ hard ” and starts feeling “ fast ”.
Advanced text objects (precision editing without Visual mode)
Text objects let you operate on semantic units (words, sentences, paragraphs, blocks) without manually selecting boundaries.
Inner vs "a" (around)
i(inner): excludes delimitersa(around): includes delimiters
Examples:
ciwchange inner word (cursor anywhere in the word)ci"change inside quotes (cursor must be inside"...")ca"change around quotes (includes the quotes themselves)dipdelete inner paragraphdi(delete inside parenthesesda{delete around braces (includes{and})
Common text objects
| Text object | Meaning | Example |
|---|---|---|
iw / aw |
inner/around word | ciw change word |
is / as |
inner/around sentence | dis delete sentence |
ip / ap |
inner/around paragraph | yip yank paragraph |
i" / a" |
inside/around "..." |
ci" change string |
i' / a' |
inside/around '...' |
di' delete single-quoted |
i( / a( |
inside/around (...) |
da( delete with parens |
i{ / a{ |
inside/around {...} |
ci{ change block |
i[ / a[ |
inside/around [...] |
di[ delete array |
it / at |
inside/around HTML tag | cit change tag content |
Why this matters: You stop thinking "select then act" and start thinking "act on semantic unit".
Registers: where deleted/yanked text goes
When you delete or yank, the text goes into a register (a clipboard-like slot).
Common registers
- Unnamed register (
""): last delete/yank - Named registers (
"ato"z): manual storage - Numbered registers (
"0to"9): yank history - System clipboard (
"+or"*on Linux/Mac,"+on Windows): share with OS
How to use registers
Yank into a named register:
1 | "ayy " yank line into register a |
Paste from a named register:
1 | "ap " paste from register a |
View all registers:
1 | :reg |
Copy to system clipboard (if Vim compiled with
+clipboard):
1 | "+yy " yank line to system clipboard |
Pro tip: Use named registers to collect multiple snippets before pasting them in sequence.
Marks: bookmarks for fast jumps
Marks let you jump back to specific positions in a file (or across files).
How to set marks
m{letter}set a mark (e.g.,masets markaat current cursor position)- lowercase (
a-z): local to current file - uppercase (
A-Z): global across files
How to jump to marks
`{letter}jump to exact position (line and column)'{letter}jump to line (first non-blank character)
Example workflow:
1 | ma " mark current position as 'a' |
Special marks:
`.jump to last edit position`0jump to position when Vim last exited`"jump to position when last editing this file
Visual mode variants (character, line, block)
Visual mode has three variants:
- Character-wise (
v): select characters - Line-wise (
V): select whole lines - Block-wise (
Ctrl+v): select rectangular blocks (amazing for columnar edits)
Block mode examples
Use case 1: Comment out multiple lines
Ctrl+venter block modejjj...select linesI#insert#at the startEscapply to all selected lines
Use case 2: Delete a column
Ctrl+venter block mode- Select the column
ddelete
Use case 3: Append to multiple lines
Ctrl+venter block modejjj...select linesA;append;to the endEscapply to all
Why block mode is powerful: It solves "edit the same column on 20 lines" problems that would require regex or macros in other editors.
Buffers vs windows vs tabs (mental model)
Many Vim beginners confuse these three concepts:
| Concept | What it is | Commands |
|---|---|---|
| Buffer | A file loaded into memory | :ls, :b <name>, :bnext,
:bprev |
| Window | A viewport showing a buffer | :split, :vsplit, Ctrl+w
motions |
| Tab | A layout of windows | :tabnew, gt, gT |
Mental model:
- One file = one buffer (even if not visible)
- You can have multiple windows showing the same buffer
- Tabs organize window layouts
Common workflow:
1 | :e file1.py " open file1 in current buffer |
Search patterns and flags (find anything)
Basic search uses / (forward) or ?
(backward):
1 | /pattern " search forward |
Search flags
\ccase-insensitive (e.g.,/foo\c)\Ccase-sensitive\<word boundary start (e.g.,/\<foo\>matchesfoobut notfoobar)\>word boundary end
Highlight search results
1 | :set hlsearch " highlight matches |
Search and replace with confirmation
1 | :%s/old/new/gc " replace all with confirmation (y/n/a/q) |
Tips:
- Start with
/patternto verify what you're matching - Then run
:%s//new/g(empty pattern reuses last search)
Common pitfalls and how to fix them
Pitfall 1: Auto-indentation breaks paste
Symptom: Pasted code gets progressively indented.
Fix: Use paste mode:
1 | :set paste |
Or use "+p (system clipboard) which auto-detects.
Pitfall 2: Accidentally enter Replace mode
Symptom: Typing overwrites characters instead of inserting.
Cause: Pressed R or Insert
key.
Fix: Press Esc to return to Normal
mode.
Pitfall 3: Swap file warning on every open
Symptom: Vim always warns about .swp
files.
Cause: Previous session didn't exit cleanly.
Fix: Delete orphaned swap files:
1 | find . -name "*.swp" -delete |
Or disable swap files (not recommended for large edits):
1 | :set noswapfile |
Pitfall 4: Lost in a deep undo tree
Symptom: u doesn't undo what you
expect.
Cause: Vim has a tree-based undo, not linear.
Fix: Use :earlier / :later
to travel through time:
1 | :earlier 5m " go back 5 minutes |
Vim vs Neovim: should you switch?
Neovim is a fork of Vim with:
- Modern architecture (better plugin API, async support)
- Built-in LSP (Language Server Protocol) client
- Lua configuration (in addition to Vimscript)
- Active development and community
When to use Neovim:
- You want built-in LSP (autocomplete, go-to-definition, diagnostics)
- You prefer Lua over Vimscript for config
- You want the latest features
When to stick with Vim:
- Your system already has Vim (servers, containers)
- You prefer stable, widely-deployed software
- You don't need advanced features
Bottom line: Both are excellent. Start with Vim (it's everywhere), switch to Neovim if you need LSP or modern plugin ecosystems.
Learning resources (curated)
vimtutor: Run this command in your terminal. It's a 30-minute interactive tutorial built into Vim.Vim Adventures (vim-adventures.com): A game that teaches Vim motions.
Practical Vim (book by Drew Neil): The best book for intermediate users.
Vim Golf (vimgolf.com): Optimize keystrokes for specific editing tasks (great for learning advanced tricks).
ThePrimeagen (YouTube): Advanced Vim/Neovim tutorials and workflows.
Summary: Vim in 10 principles
- Modes are your friend: Normal mode is home base, Insert is temporary.
- Think "operator + motion":
d+w= delete word. - Use text objects:
ciw,di",yipbeat manual selection. - Search first, then act:
/pattern+n+cwis faster than scrolling. - Repeat with
.: For simple edits,.is the fastest macro. - Record macros for complex repetition:
qa+ edits +q+10@a. - Master a few motions deeply:
w/b,0/$,gg/G,{/}cover 90% of navigation. - Don't over-customize early: Learn the defaults first, then add keymaps.
- Use splits and buffers: Don't open 10 terminal
tabs; use
:splitand:bnext. - Practice deliberately: Spend 1 week forcing yourself to use only Vim for all editing.
Once you internalize the grammar, Vim becomes a text-editing language you speak fluently, not a tool you "operate".
- Post title:Vim Essentials: Modal Editing, Motions, and a Repeatable Workflow
- Post author:Chen Kai
- Create time:2023-01-05 00:00:00
- Post link:https://www.chenk.top/en/vim-essentials/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.