Modes, Navigation & Basic Editing
"Vim is like a language: once you learn the grammar, you can express anything."
If you have ever watched an experienced Vim user edit code, you may have noticed something almost musical about the way they work. Their fingers barely leave the home row, yet text seems to rearrange itself at the speed of thought. There is no frantic mouse-grabbing, no holding down arrow keys. Just short, deliberate keystrokes that compose into powerful editing actions. The secret behind that fluency is what this chapter teaches you: modes, navigation, and basic editing commands. These are the building blocks of everything you will do in Vim and Neovim. Master them, and the editor stops being a tool you fight against — it becomes an extension of how you think.
What you'll learn in this chapter:
Understand Vim's modal editing paradigm and switch between Normal, Insert, Visual, and Command modes
Navigate efficiently within lines, across words, and through files using motions and the jumplist
Use the dot command and the
cgnworkflow to repeat changes with minimal keystrokesLeverage the
zcommands, page navigation, andg-prefixed commands for advanced movementSave, quit, and manage files from Command mode
Understanding Vim Modes
Vim is a modal editor — it has different modes for different tasks. This is what makes Vim unique and powerful.
Most editors you have used before are modeless: every key you press inserts a character, and you need modifier keys or menus to do anything else. Vim turns this idea on its head. In Vim, your keyboard has different "personalities" depending on which mode you are in. In Normal mode, every key is a command — d deletes, w moves forward a word, p pastes. In Insert mode, keys type text just like any other editor. This separation is the core insight of modal editing: since you spend far more time navigating and manipulating text than actually typing new characters, it makes sense to give those actions first-class keybindings instead of burying them behind Ctrl and Alt combinations. Once this clicks, you will wonder how you ever edited text any other way.
Normal
Move around and change text
Esc
Insert
Type text
a, A, i, I, o, O
Command
Run commands
Esc:
Visual
Select text
Esc v V or Ctrl + v
Terminal
Interact with terminal (Neovim)
:terminal
Entering Insert Mode
You will frequently move between Normal and Insert mode, so Vim gives you many ways to enter Insert mode — each one placing your cursor exactly where you need it. Choosing the right entry point saves you from repositioning after the fact.
a
Start Insert Mode after current character
A
Start Insert Mode at the end of current line
i
Start Insert Mode before current character
I
Start Insert Mode at start of the line
o
Start Insert Mode one line below
O
Start Insert Mode one line above
cc
Delete current line and start Insert Mode
S
Delete current line and start Insert Mode
gi
Restart Insert Mode from the last insert point
Neovim: Neovim adds Terminal mode accessed via
:terminal. Press Ctrl+\ Ctrl+n to return to Normal mode from Terminal mode.
The $MYVIMRC Environment Variable
Before we dive deeper into navigation, let's take a quick detour into configuration. As you learn new commands in this chapter, you will want a place to save your settings and customizations. That place is your configuration file, and Vim makes it easy to find through a single environment variable.
The environment variable $MYVIMRC is the main config file of Vim/Neovim. It changes accordingly with your system:
Vim
Linux/macOS
~/.vimrc
Vim
Windows
$HOME/vimfiles/vimrc
Neovim
Linux/macOS
~/.config/nvim/init.vim or ~/.config/nvim/init.lua
Neovim
Windows
~/AppData/Local/nvim/init.vim or init.lua
Tip: Using
$MYVIMRCin your mappings and commands is more portable than hardcoding the path.
How to Get Help
Every great craftsperson knows how to consult the manual, and Vim's built-in help system is one of the best you will ever encounter. Before you reach for a web search, try :help first — the answer is almost always there, and often more precise than what you will find online.
:help gR
Help for gR in normal mode
:help v_r
Help for r in visual mode
:help i_CTRL-W
Help for Ctrl+w in insert mode
:help :quit
Help for :quit in command mode
:help c_CTRL-R
Help for Ctrl+r in command line editing
:help togg<TAB>
Help for all topics containing 'togg'
Tip: You can abbreviate the word help:
:h :help— in the vim help you seeh[elp], the part between brackets is optional.
Tip: After opening the vim help you will see some "links" in different colors. When you are over any of these links you can type Ctrl+] to jump to a topic, and Ctrl+o or Ctrl+t to get back.
Navigation: Moving on the Line
Now we arrive at the heart of this chapter: movement. In Vim, navigation is not just a way to get somewhere — it is half of the editing language itself. When you combine a motion like $ (end of line) with an operator like d (delete), you get d$ — "delete to end of line." Learning motions well is therefore learning to edit well.
Let's start with moving within a single line. Vim has four native keybindings to jump to specific positions in the line:
0
Go to the first column of the line
^
Go to the first non-blank character
$
Go to the end of the line
g_
Go to the last non-blank character

Tip: You can be at the middle of the line and want to delete until the first non-blank character — just type: d^
Word Motions
Jumping to the beginning or end of a line is useful, but most of the time you want to move in smaller, more precise increments. Word motions let you hop forward and backward through text one word at a time — and they are the motions you will use most often in everyday editing.
w
Move to the beginning of the next word
W
Move to the beginning of the next WORD
b
Move to the beginning of the previous word
B
Move to the beginning of the previous WORD
e
Move to the end of the current/next word
E
Move to the end of the current/next WORD
Note: word vs WORD — A word is a sequence of letters, digits, and underscores (or a sequence of other non-blank characters). A WORD is any sequence of non-blank characters separated by whitespace. For example,
my-variableis three words but one WORD. See:help word.
These motions combine with operators: dw deletes to the next word, cW changes to the end of the current WORD, d2w deletes the next two words (see Text Objects & Motions for a complete guide to combining operators with text objects).
F{chars}: Jumping to Characters
Now that you know how to move by words, let's learn how to jump to specific characters. Imagine your cursor is at the beginning of a long line and you need to get to a comma halfway through it. You could press w several times, but there is a faster way.
The f{char} motions are one of those Normal Mode commands that make people fall in love with Vim. They let you jump directly to any character on the current line.
f{char}
f,
Jump to the next comma
F{char}
F,
Jump to the previous comma
t{char}
t)
Jump until before close parenthesis
T{char}
T)
Jump back until after open parenthesis
df{char}
df.
Delete until dot (included)
vt{char}
vt"
Select until before quotes
Tip: The uppercase versions
FandTjump in the opposite direction. Use;to repeat the last f/t motion forward, and,to repeat it backward.
Neovim: Plugins like flash.nvim, leap.nvim, or vim-sneak extend this concept to jump anywhere on the screen with just 2-3 keystrokes. vim-sneak works in both Vim and Neovim, while flash.nvim and leap.nvim are Neovim-only.
The "z" Commands: Page View
So far, all our motions have moved the cursor. But sometimes the cursor is exactly where you want it — the problem is that the surrounding context has scrolled off screen. The z commands solve this by repositioning the viewport around your cursor without moving the cursor itself.
zt
Move current line to the top of the window
zz
Move current line to the middle of the window
zb
Move current line to the bottom of the window
Tip: Set
scrolloffto keep some lines visible above/below the cursor::set scrolloff=8
Moving Around: Jumplist & Changelist
When you work on real code, you rarely stay in one place. You jump to a function definition, check a variable somewhere else, then need to get back to where you started. Vim quietly tracks all of these movements for you in two lists — the jumplist and the changelist — so you can always retrace your steps.
The Jumplist
Vim maintains a list of all your jumps. This is incredibly useful for navigating back and forth:
Ctrl+o
Jump to older position in jumplist
Ctrl+i
Jump to newer position in jumplist
:jumps
Show the jumplist
''
Toggle between last two positions
Note:
''vsCtrl+o— These two are often confused.''toggles between exactly two positions — pressing it twice returns you to the same place.Ctrl+owalks backward through the entire jumplist (which can contain many positions across files). Use''for quick back-and-forth between two spots, andCtrl+owhen you need to retrace your steps through multiple jumps.
The Changelist
Similar to the jumplist, Vim tracks where you made changes:
g;
Go to older position in changelist
g,
Go to newer position in changelist
'.
Jump to last modification
:changes
Show the changelist
Page Navigation
Beyond the jumplist and changelist, you will often need to scroll through a file quickly. These commands move you by pages or half-pages, and let you jump to any line by number.
Ctrl+f
Page forward
Ctrl+b
Page backward
Ctrl+d
Half page down
Ctrl+u
Half page up
gg
Go to first line
G
Go to last line
{count}G
Go to line {count}
Neovim: Plugins like vim-smoothie (Vim/Neovim) or Neovim's built-in
vim.opt.smoothscroll = true(Neovim 0.10+) add animated scrolling to Ctrl+d/u/f/b, making it easier to maintain context when jumping.
The Dot Command
If you take away only one thing from this chapter, let it be the dot command. Ask any long-time Vim user what their favorite feature is, and many will answer . without hesitation. The reason is simple: the dot command repeats your last change. That single key turns any edit — no matter how complex — into a repeatable action. Delete a word? Press . to delete the next one. Change a function argument? Press . to make the same change somewhere else. The dot command rewards you for thinking in composable edits: the better you structure your initial action, the more mileage you get from repeating it.
In Normal mode, the dot command . repeats your last action. This is one of the most powerful concepts in Vim.
Example: Adding --> between the last two words on multiple lines:
Literal Inserting
When using the dot command with paste operations, you need to paste literally to ensure the dot command replays the correct content.
If you use ciw to change a word, type replacement text, and then try to repeat with . on another word — it works. But if you paste from a register during the change, the dot command will paste the same text again.
To fix this, paste your register literally with Ctrl+r Ctrl+o" instead of Ctrl+r". Now the dot command will paste the current content of the register.
The site vimgolf.com has Vim challenges where the goal is to solve editing problems with the fewest keystrokes possible. Many of these challenges require understanding literal inserting to use the dot command effectively with cgn-style workflows.

Normal Commands That Stand Out
Vim has a collection of commands prefixed with g that don't fit neatly into the categories above but are too useful to overlook. Think of them as Vim's utility belt — once you discover them, you will reach for them constantly.
gd
Go to local definition
gD
Go to global definition
gf
Go to the file under the cursor
gi
Enter insert mode at last insertion point
gv
Repeat last visual selection
gx
Open URL under cursor in browser
ga
Show ASCII/Unicode value for character under cursor
gJ
Join lines with no space in between
gu{motion}
Make text lowercase
gU{motion}
Make text UPPERCASE
gn
Search forward and select the match (useful with cgn)
gR
Start virtual replace mode
The cgn Workflow
cgn WorkflowHere is a scenario every programmer knows: you have renamed a variable in your head, and now you need to update it in fifteen places across a file. You could use :%s/old/new/g, but what if some of those instances should stay the same? Maybe user appears as a variable name in some lines but as part of a comment or string in others, and you only want to change certain occurrences. This is the exact problem cgn solves. It combines searching, changing, and the dot command into a workflow that lets you step through matches one by one, applying or skipping each change with a single keystroke.
The gn command is a game-changer for search-and-replace workflows:
Search for a word:
/patternPress
cgnto change the matchType your replacement
Press Esc
Press
.to repeat on the next match, ornto skip
This is often faster and more flexible than :%s/old/new/g because you can selectively apply changes. See the excellent Vimcasts episode on gn for a visual walkthrough.
Tip:
gfonly works properly if you enable::set hiddenand:set path+=**
The Ex put Command
put CommandStepping briefly into Command mode, the :put command is a handy way to insert text without entering Insert mode at all. It is especially powerful when combined with expressions, letting you generate content programmatically right inside your editor.
The :put command inserts text from a register or expression after a given line:
This puts the string after line zero (before the first line). You can combine put with Vim's scripting to generate content programmatically:
Note: We use
|to separate commands on the same line.
To add a blank line at the end of your document: :$put _ — the $ represents the last line and _ is the black hole register.
Leaving the File
Every editing session has to end at some point. Vim offers several ways to save your work and exit — and yes, knowing how to quit Vim is a rite of passage. Here are the commands you need.
:q
Quit (fails if unsaved changes)
:q!
Quit without saving
:w
Save (write)
:wq or ZZ
Save and quit
:x
Save only if changed, then quit
ZQ
Quit without saving (same as :q!)
:qa
Quit all windows
:wa
Save all windows
Tip: For custom keybindings to streamline saving, quitting, and other frequent operations, see Mappings.
Summary
This chapter covered the core mechanics of working in Vim: its modal editing paradigm, the full spectrum of navigation commands from single-character jumps to page-level scrolling, and essential editing workflows like the dot command and the cgn pattern. Together, these building blocks form the foundation for everything that follows in this book.
Key takeaways:
Vim's modal design separates navigation from text entry, giving every key a command in Normal mode and freeing you from modifier-key gymnastics
Line motions (
0,^,$,g_), word motions (w,b,e), and character jumps (f,t) compose with operators (d,c,y) to form a powerful editing languageThe jumplist (Ctrl+o / Ctrl+i) and changelist (
g;/g,) let you retrace your steps across files and editsThe dot command (
.) repeats your last change, and thecgnworkflow combines search, change, and repeat into a selective find-and-replaceThe
g-prefixed commands (gd,gf,gv,gn,gU,gu) provide advanced navigation and text manipulation
Exercises
Mode switching drill — Open a file and practice entering Insert mode with each of the entry commands:
i,I,a,A,o,O,cc, andgi. After each insertion, return to Normal mode with Esc. Pay attention to where the cursor lands for each command.Navigate with word and character motions — Given the line
const user = getUser(id, { includeProfile: true });, start at the beginning and reach the wordtrueusing onlyw,W,f, andtmotions. Try multiple approaches and count keystrokes.Jumplist navigation — Open three different files (or use
:helpto jump around). Navigate between them using Ctrl+o and Ctrl+i. Then use:jumpsto view your jumplist.The
cgnworkflow — Create a buffer with this content:foo bar foo baz foo qux. Use thecgnworkflow to replace only the first and third occurrences offoowithhello, skipping the second.Combine motions with operators — On a line like
delete [everything] inside these {curly braces} please, delete the content inside the square brackets and then inside the curly braces using the fewest keystrokes.
Last updated
Was this helpful?