Skip to main content

Insert Mode Mastery

Most beginners only know i to enter Insert mode. In reality, there are 10+ entry points, each placing the cursor at a different position. Choosing the right entry point eliminates unnecessary navigation.

Learning Focus

The goal is to enter Insert mode exactly where you need to start typing — not to enter Insert and then navigate.

Insert Mode Entry Points​

KeyWhere you start typing
iBefore cursor
aAfter cursor (append)
IStart of line (first non-blank)
AEnd of line
oNew line below cursor
ONew line above cursor
sSubstitute: delete char, enter insert
SSubstitute: delete line, enter insert
c{motion}Change: delete motion, enter insert
CChange to end of line
giReturn to last insert position

Read the ruler — the ^ marks where the cursor sits when Insert mode begins:

hello world
^ ^
bi ea
  • bi → back to the start of the word, insert before it.
  • ea → to the end of the word, append after it.
getData(userId)
^
f(a
  • f(a → find (, then append after it.
oldVariable = 1
^^^^^^^^^^^
ciw
  • ciw → change the whole inner word, no matter where the cursor is inside it.

Choosing the Right Entry Point​

Scenario: Add a semicolon at end of line
❌ Wrong: hjklA;Esc (navigated manually)
✅ Right: A;Esc (jump to end, append)

Scenario: Add text after a word
❌ Wrong: wia (word jump, insert, then position)
✅ Right: ea (end of word, append)

Scenario: Add text before a word
❌ Wrong: biw (back, insert, word jump — unnecessary)
✅ Right: bi (back to word start, insert before it)

Scenario: Replace a whole line
❌ Wrong: 0d$i (start, delete to end, insert)
✅ Right: S (substitute line, enter insert)

Editing Inside Insert Mode​

You can do light editing without leaving Insert mode:

KeyAction
BackspaceDelete previous character
Ctrl+hDelete previous character (same as Backspace)
Ctrl+wDelete previous word
Ctrl+uDelete to beginning of line
Ctrl+j or EnterNew line
Ctrl+tIndent (add shiftwidth spaces)
Ctrl+dDe-indent (remove shiftwidth spaces)

The Ctrl+o Trick — One Normal Command​

Ctrl+o executes exactly one Normal mode command and returns to Insert mode.

In Insert mode:
Ctrl+o $ → jump to end of line, stay in Insert
Ctrl+o dd → delete line, return to Insert
Ctrl+o 0 → jump to line start, stay in Insert
Ctrl+o zz → center screen, return to Insert

This is invaluable for quick corrections without fully exiting Insert mode.

Inserting Special Characters and Registers​

Ctrl+r {register} → Insert contents of register
Ctrl+r " → Insert from unnamed (default) register
Ctrl+r + → Insert from system clipboard
Ctrl+r 0 → Insert from yank register
Ctrl+r a → Insert from named register 'a'
Ctrl+r = → Insert result of expression (e.g., 2+2 → 4)

Using the Expression Register​

Ctrl+r = 7 * 8 Enter → Inserts 56
Ctrl+r = system('date') Enter → Inserts current date

Digraphs — Typing Special Characters​

Insert special Unicode characters without leaving Insert mode:

Ctrl+k {char1} {char2} → Type a digraph

Examples:
Ctrl+k : e → ë (e umlaut)
Ctrl+k ' e → é (e acute)
Ctrl+k >> a → ⬇ (varies by config)

See all digraphs: :digraphs

Autocompletion in Insert Mode​

Neovim has built-in completion before any plugins:

KeyCompletion source
Ctrl+nKeyword completion (forward)
Ctrl+pKeyword completion (backward)
Ctrl+x Ctrl+fFilename completion
Ctrl+x Ctrl+lWhole-line completion
Ctrl+x Ctrl+]Tag file completion
Ctrl+x Ctrl+oOmni-completion (language-aware)
note

With nvim-cmp (covered in Module 8), this is replaced with a much better completion system. But the built-in completions always work, even without plugins.

Smart Insert Entry Patterns​

Pattern 1: Append After Matching Char​

For: let result = calculate(value
Goal: close the parenthesis

f(a) → find '(', append after one char → )
or:
A) → jump end of line, append ) (if ) belongs at end)

Pattern 2: Insert Before a Specific Word​

For: let result = calculate(value)
Goal: add `const` before `result`

b i const Esc → back to word start, insert before it

The counterpart to ea (end of word, append). Use b to reach the word start regardless of cursor position on the line.

Pattern 3: Change a Word in the Middle​

For: const oldVariable = getData()
Goal: rename oldVariable to newName

ciw newName → change inner word under cursor → type replacement
* ciw newName → if cursor is elsewhere, find the word first

Pattern 4: Create a Function Body​

For: function myFunc() {}
Goal: add body inside braces

f{a → find '{', append after
Enter → new line (auto-indented)
...code...
Esc → done

Practice​

Practice File

Open the step-by-step drills: practice-folder/nvim/02-modal-editing/insert-practice.md (also available via the shell alias n02-insert).

DrillWhat it trainsSteps
iInsert before the cursorCursor on the p of apple → i → type XX + Esc → aXXpple
IInsert at first non-blankCursor anywhere on cherry → I → type ZZ + Esc
a / AAppend after cursor / line endOn hello world → a after h; A after world
o / OOpen line below / aboveOn line one → o → type → Esc; O opens above
s / SDelete char / line, then InsertOn abcdefghij → s → X → Esc; S on a whole line
c{motion} / CChange motion / to end of linecw, ciw, c$/C, c0, cc on the fox/jug lines
Ctrl+oOne Normal cmd from InsertA → Ctrl+o j → keep typing; try Ctrl+o dd, Ctrl+o o
Quick fireEntry-point recapi, a, I, A, o, O on one line, undoing between each

In LazyVim​

LazyVim Context

Insert mode mastery is identical in LazyVim. Standard shortcuts like <C-w> (delete word) or <C-u> (delete line) work as expected. LazyVim also pre-configures snippet expansion and auto-completion via blink.cmp (or nvim-cmp in older setups) to speed up Insert mode typing.

AspectVanilla NeovimLazyVim
Insert Mode Entryi, I, a, A, o, OSame
Auto-completionBuilt-in omnifunc or manual setupblink.cmp pre-configured

What's Next​