Mastering Vim Basics

Why Use Vim?

Vim is a powerful, highly configurable text editor designed for efficient text manipulation. While it has a steep learning curve, mastering Vim can dramatically improve productivity for developers, system administrators, and power users.

If you’re new to Vim, consider starting with Vim emulation in Visual Studio Code (VSC) for a smoother transition:

  • Install the Vim extension in VSC.
  • Open the Command Palette (cmd + shift + p) and search for Preferences: Open Keyboard Shortcuts (JSON).
  • Add the following shortcut to toggle Vim mode:
{
  "key": "ctrl+shift+[IntlBackslash]", // macOS: "ctrl+shift+[Backquote]"
  "command": "toggleVim"
}

Vim’s Modes Explained

Vim operates in several distinct modes, each tailored for different tasks:

  • Normal Mode: The default “command” mode for navigation and text manipulation.
  • Insert Mode: For inserting and editing text (enter with i, I, a, A, o, O).
  • Visual Mode: For selecting text by character (v), line (V), or block (Ctrl+v).
  • Operator-Pending Mode: After pressing an operator (e.g., d, c, y), awaiting a motion or text object.
  • Command-Line Mode: For entering ex commands (:w, :q, :s, etc.) and searches (/, ?).

Understanding these modes is the foundation for efficient editing in Vim.

Essential Navigation

Horizontal Movement

  • 0: Go to beginning of line
  • ^: Jump to the first non-blank character
  • $: Jump to end of line

Vertical Movement

  • j / k: Move down / up one line
  • { / }: Move up / down by paragraph
  • Ctrl + D / Ctrl + U: Scroll half a page down / up

Screen Navigation

  • gg: Move cursor to first line
  • #G: Move cursor to numbered line (e.g., 10G moves to line 10)
  • GG: Move cursor to last line
  • Ctrl + f: Move forward a full page
  • Ctrl + b: Move backward a full page
  • Ctrl + u: Scroll up half a page
  • Ctrl + d: Scroll down half a page
  • zt: Move screen so cursor is at top
  • zb: Move screen so cursor is at bottom
  • zz: Center screen on cursor (very useful!)
  • H: Move cursor to top (“high up” or “home”) of window
  • M: Move to middle of window
  • L: Move to bottom (“low” or “last line”) of window
  • ZZ: Save document and quit (be careful!)

Word Navigation

  • w: Move to next word start
  • b: Move to previous word start
  • e: Move to next word end
  • 2w: Move forward two words

Fast Searching

  • /pattern: Search forward

    • n: Repeat search forward
    • N: Repeat search backward
  • ?pattern: Search backward

  • f<char>: Jump to next occurrence of <char>
  • t<char>: Jump right before <char>
  • ; / ,: Repeat or reverse last inline search

Advanced Movements

  • gd: Go to local definition
  • gf: Open file under cursor
  • G: Go to end of file
  • gg: Go to beginning of file
  • %: Jump between matching brackets (), {}, []
  • Ctrl + O / Ctrl + I: Navigate backward / forward in jump history

Basic Editing

  • yy: Yank (copy) current line
  • dd: Delete current line
  • p: Paste below
  • P: Paste above
  • u: Undo
  • Ctrl + R: Redo
  • xp: Swap two characters
  • ddp: Swap two lines
  • J: Join lines
  • r<char>: Replace character under cursor
  • ci(: Change inside parentheses
  • cs'": Change single quotes to double quotes
  • cis: Change inside sentence
  • ciw: Change inner word
  • ciW: Change inner WORD (includes punctuation)

Registers & Clipboard Integration

Vim provides multiple registers to store text. Key registers include:

  • Unnamed Register (""): Default for all yank/delete operations.

  • Named Registers ("a"z): Use "ayy or "ad to target register a.

  • Black Hole Register ("_): Discard text without yanking: e.g., "_daw.

  • System Clipboard:

    • "+y / "+p to yank/paste from the + register.
    • "*y / "*p for the * register (often the same as the system selection).
  • Small Delete Register ("-): Stores small deletes (e.g., x).

View all registers with :reg and clear with :let @a = '' for register a.

Tips: you can use :%y+ to yank the entire file to the system clipboard, or :let @+ = @0 to copy the last yanked text to the system clipboard.

Indentation and Commenting

  • Visual block mode: Ctrl + v → highlight → press I → type //Esc

  • Use gv to reselect the last visual selection, then < or > again to repeat indentation.

  • Indent multiple lines: > / <

  • <n>>> / <n><<: Indent or dedent multiple lines

  • Auto-indent inside {}:

    • =a{: Format around braces
    • =i{: Format inside braces
  • Ctrl + t in Insert mode: Increase indentation (tab).
  • Ctrl + d in Insert mode: Decrease indentation (untab).
  • << / >> in Normal mode: Un-indent or indent the current line.

Basic File & Session Commands

  • :w – Save current file
  • :q – Quit window (use :q! to discard changes)
  • :wq or :x – Save and quit
  • :e <file> – Open another file
  • :w <file> – Save as new file
  • :buffers or :ls – List open buffers
  • :bnext / :bprev – Cycle through buffers
  • :bd – Delete (close) a buffer
  • :mksession! session.vim – Save session to session.vim
  • vim -S session.vim – Restore a saved session

File Operations

  • :r <file>: Read and insert contents of another file

  • Save part of a file:

    :100,$w filename         " Save from line 100 to end  
    :100,$w >> filename      " Append from line 100 to another file  

Window Management

  • Open files in splits:

    • vim -o file1 file2: Horizontal split
    • vim -O file1 file2: Vertical split
  • Inside Vim:

    • :split file or Ctrl + w s
    • :vsplit file or Ctrl + w v
  • Navigation: Ctrl + w + h/j/k/l

  • Resize: Ctrl + w + >, <, +, -, =

  • Close window: Ctrl + w q

  • Rotate windows: Ctrl + w r

  • Swap windows: Ctrl + w x

  • Close all others: Ctrl + w o

Tabs

  • :tabnew: Open a new tab
  • :tabn / :tabp: Next / previous tab
  • :tabclose: Close current tab
  • :tabonly: Close all other tabs

Marks

  • m<char>: Set mark (e.g. ma)
  • 'a: Jump to line of mark
  • `a: Jump to exact position of mark

Folding

  • zf4j: Create a fold of 4 lines
  • zO / zc: Open / close fold
  • zd: Delete fold
  • zR / zM: Open all / close all folds

Line Number Configuration

  • :set number: Enable absolute line numbers
  • :set relativenumber: Enable relative line numbers

Recommended dynamic toggling for .vimrc:

syntax on
set number
augroup numbertoggle
  autocmd!
  autocmd BufEnter,FocusGained,InsertLeave,WinEnter * if &nu && mode() != "i" | set rnu | endif
  autocmd BufLeave,FocusLost,InsertEnter,WinLeave   * if &nu | set nornu | endif
augroup END
set incsearch
set mouse=a

Powerful Substitution

  • :%s/old/new/g: Replace all
  • :%s/old/new/gc: Confirm each replacement
  • :%s/HEY/<b>&<\/b>/g: Wrap “HEY” in HTML bold tags
  • :%s/[Hh]elp/\U&/g: Replace “Help” or “help” with uppercase

Integration with Shell

Use external commands on content (selected or full file):

:!jq

Advanced File Handling

  • vim -b <file>: Open in binary mode
  • vimdiff old new: Compare two files side-by-side
  • vim -R <file>: Open in read-only mode
  • vim -c /pattern <file>: Open and jump to pattern

Browser Integration

Enhance browser productivity with Vim-style navigation:

Practical Motion & Editing Combos

ActionCommand
Copy current paragraphyap or vip + y
Change text between quotesci" or ci'
Delete full HTML tagdat or vat + d
Copy full <form> tag contentsPlace cursor inside → vat
Delete inside parenthesesdi(
Change inside sentencecis
Change inner word / WORDciw / ciW
Auto-indent code block=a{ or =i{

Useful Resources

Conclusion

Vim is incredibly efficient once mastered. Consistent practice and gradual incorporation into your workflow can vastly improve your productivity.