Skip to content
Published on

The Complete Vim Command Guide: Master Every Command of the Ultimate Text Editor

Authors
  • Name
    Twitter

1. Introduction to Vim

1.1 History: Vi to Vim to Neovim

Vi is a text editor written by Bill Joy for BSD Unix in 1976. It was a groundbreaking tool that enabled efficient editing using only the keyboard in terminal environments. Vi's core idea of Modal Editing lives on to this day.

Vim (Vi IMproved) is a greatly enhanced version of Vi released by Bram Moolenaar in 1991. Hundreds of features were added including syntax highlighting, a plugin system, multiple windows, macros, and regex substitution. Vim became the standard editor used daily by developers and system administrators worldwide, as it comes pre-installed on GNU/Linux servers.

Neovim is a refactored fork of Vim that began in 2014. It offers Lua-based configuration, a built-in LSP (Language Server Protocol), and an asynchronous plugin API, aiming to deliver a VS Code-level IDE experience within the terminal.

EditorReleasedKey Features
Vi1976Pioneer of modal editing, lightweight
Vim1991Plugins, syntax highlighting, macros
Neovim2014Lua API, built-in LSP, async support

1.2 Why Learn Vim

  • Available everywhere: Remote servers via SSH, Docker containers, embedded devices — Vi/Vim is installed on virtually every Unix environment.
  • Your hands never leave the keyboard: All operations are possible without a mouse, dramatically improving editing speed.
  • Powerful composable language: Complex operations can be expressed concisely with a verb+count+noun structure, such as d3w (delete 3 words) or ci" (change contents inside quotes).
  • Macros and automation: Record repetitive tasks as macros and transform thousands of lines in an instant.
  • Universal Vim keybindings: Dozens of tools support Vim keybindings including VS Code, IntelliJ, Obsidian, Jupyter, bash readline, and tmux copy mode. Learning Vim makes every tool faster.

2. Mode Concepts

The most important feature of Vim is modal editing. The behavior when you press a key changes completely depending on the current mode.

2.1 Major Modes and Transitions

ModeDescriptionHow to EnterHow to Exit
NormalNavigation, commands<Esc>, <C-c>— (default mode)
InsertText inputi, a, o, I, A, O, s, c<Esc>, <C-c>
VisualCharacter-wise selectionv<Esc>, v
Visual LineLine-wise selectionV<Esc>, V
Visual BlockBlock (column) selection<C-v><Esc>, <C-v>
Command-line: command input:, /, ?, !<Esc>, <CR>
ReplaceOverwrite charactersR<Esc>

2.2 Mode Transition Diagram

         ┌─────────────────────────────────────────┐
Normal Mode           (Default at startup / return via <Esc>)         └────┬───────┬───────┬────────────────────┘
              │       │       │
         i,a,o│    v,V   :,/,?              │       │       │
         ┌────▼──┐ ┌──▼────┐ ┌▼────────────┐
         │Insert │ │Visual │ │Command-line │
Mode  │ │ Mode  │ │    Mode         └───────┘ └───────┘ └─────────────┘

Rule: Pressing <Esc> at any time returns you to Normal Mode. Pressing <Esc> twice when you are lost is Vim survival rule number 1.


3. Navigation Commands

3.1 Basic Movement (hjkl)

KeyAction
hMove left one character
jMove down one line
kMove up one line
lMove right one character
5jMove down 5 lines (numeric prefix)
10kMove up 10 lines

3.2 Word-Level Movement

KeyAction
wMove to start of next word (punctuation delimited)
WMove to start of next WORD (whitespace delimited)
bMove to start of previous word
BMove to start of previous WORD
eMove to end of current/next word
EMove to end of current/next WORD
geMove to end of previous word

Lowercase (w, b, e) treats punctuation as word boundaries, while uppercase (W, B, E) only treats whitespace as boundaries. In hello_world, w requires 2 presses while W requires 1.

3.3 Line-Level Movement

KeyAction
0Move to beginning of line (column 0)
^Move to first non-whitespace character of line
$Move to end of line
g_Move to last non-whitespace character of line
ggMove to first line of file
GMove to last line of file
42GMove to line 42
:42Move to line 42 (command mode)
%Jump to matching parenthesis/brace/bracket

3.4 Screen Scrolling

KeyAction
<C-u>Scroll half screen up
<C-d>Scroll half screen down
<C-f>Scroll full screen down (Page Down)
<C-b>Scroll full screen up (Page Up)
HMove cursor to top of screen (High)
MMove cursor to middle of screen (Middle)
LMove cursor to bottom of screen (Low)
zzCenter current line on screen
ztAlign current line to top of screen
zbAlign current line to bottom of screen

3.5 Search Movement

KeyAction
/patternSearch forward for pattern
?patternSearch backward for pattern
nNext match in same direction
NNext match in opposite direction
*Search forward for word under cursor
#Search backward for word under cursor
f{char}Find char forward on current line, move to it
F{char}Find char backward on current line
t{char}Move to just before char (till)
T{char}Move to just after char (reverse direction)
;Repeat f/F/t/T in same direction
,Repeat f/F/t/T in opposite direction

3.6 Jump Movement

KeyAction
<C-o>Jump to previous cursor position (jump back)
<C-i>Jump to next cursor position (jump forward)
''Return to last jump position (two single quotes)
m{a-z}Set mark a-z at current position
'{a-z}Jump to mark
gdGo to local declaration
gDGo to global declaration

4. Editing Commands

4.1 Entering Insert Mode

KeyAction
iEnter Insert Mode before cursor
IEnter Insert Mode before first non-whitespace character
aEnter Insert Mode after cursor (append)
AEnter Insert Mode at end of line
oOpen new line below and enter Insert Mode
OOpen new line above and enter Insert Mode
giEnter Insert Mode at last edit position

4.2 Delete Commands

KeyAction
xDelete character under cursor
XDelete character before cursor (Backspace)
ddDelete current line
3ddDelete 3 lines starting from current line
DDelete from cursor to end of line (same as d$)
dwDelete from cursor to start of next word
deDelete from cursor to end of word
d0Delete from cursor to start of line
dGDelete from current line to end of file
dggDelete from current line to start of file

Deleted text is stored in a register and can be pasted with p. Vim's delete is equivalent to "Cut."

4.3 Change Commands

KeyAction
r{char}Replace character under cursor with char (stay in Normal Mode)
REnter Replace Mode (continuous overwrite)
sDelete character under cursor and enter Insert Mode
SDelete current line contents and enter Insert Mode (same as cc)
cwChange from cursor to end of word
ccChange current line contents
CChange from cursor to end of line (same as c$)
c0Change from cursor to start of line
~Toggle case of character under cursor
g~wToggle case of word
guwConvert word to lowercase
gUwConvert word to uppercase

4.4 Copy and Paste

KeyAction
yyYank (copy) current line
YYank current line (same as yy)
3yyYank 3 lines starting from current line
ywYank from cursor to end of word
y$Yank from cursor to end of line
y0Yank from cursor to start of line
pPaste after (below) cursor
PPaste before (above) cursor
gpSame as p but moves cursor to end of pasted text
"ayyYank current line to register a
"apPaste contents of register a

4.5 Undo / Redo

KeyAction
uUndo last change
3uUndo last 3 changes
<C-r>Redo (undo the undo)
UUndo all changes on current line

4.6 Indentation

KeyAction
>>Indent current line
<<Outdent current line
3>>Indent 3 lines
=Auto-indent (after Visual selection or == for current line)
==Auto-indent current line
gg=GAuto-indent entire file

5. Visual Mode

5.1 Visual Mode Types

KeyModeDescription
vVisual (char)Character-wise selection
VVisual LineLine-wise selection
<C-v>Visual BlockColumn-wise block selection
gvReselect previous Visual region

5.2 Operations Available in Visual Mode

KeyAction
d / xDelete selection
yYank selection
cDelete selection and enter Insert Mode
> / <Indent / outdent selection
=Auto-indent selection
~Toggle case of selection
uConvert selection to lowercase
UConvert selection to uppercase
:Apply command to selection (:'<,'>)
oMove cursor to opposite end of selection

5.3 Visual Block Practical Examples

Visual Block (<C-v>) is extremely useful for inserting or deleting text across multiple lines simultaneously.

Example: Adding // comments to the beginning of multiple lines

1. Enter Visual Block with <C-v>
2. Press j to select the desired number of lines
3. Press I to enter block Insert Mode
4. Type //
5. Press <Esc> and // will be inserted on all selected lines

Example: Deleting content at a specific column across multiple lines

1. Enter Visual Block with <C-v>
2. Select the desired range (adjust column range with hjkl)
3. Press d to delete

6. Text Objects

Text objects are a core concept of Vim editing. They form commands in a "verb + preposition + noun" structure using {operator}{a|i}{object}.

  • a (around): Includes the object and surrounding whitespace/delimiters
  • i (inner): Selects only the inside of the object

6.1 Text Object List

Objecti (inner)a (around)
wInside wordWord + surrounding spaces
WInside WORDWORD + surrounding spaces
sInside sentenceSentence + trailing space
pInside paragraphParagraph + surrounding blank lines
"Contents inside "..."Entire "..."
'Contents inside '...'Entire '...'
`Contents inside `...`Entire `...`
( / )Inside (...)Entire (...)
[ / ]Inside [...]Entire [...]
{ / }Inside {...}Entire {...}
< / >Inside <...>Entire <...>
tInside XML/HTML tagEntire tag including markers

6.2 Text Object + Operator Combination Examples

CommandActionExample Scenario
diwDelete word under cursorOn hello - deletes the word
dawDelete word + surrounding spacesCompletely remove a word from a sentence
ci"Change contents inside "...""old" - replace content keeping quotes
ca"Change entire "...""old" - replace including quotes
di(Delete contents inside (...)Delete all function arguments
da(Delete entire (...)Delete including parentheses
yipYank current paragraphCopy entire paragraph
dapDelete current paragraphDelete entire paragraph
vitVisual select inside HTML tagSelect content in <div>content</div>
citChange inside HTML tagReplace tag content
=i{Auto-indent inside curly bracesAlign entire function body
>i{Add indent inside curly braces

7. Command-line Mode

7.1 File Operations

CommandAction
:wSave
:w filenameSave as different name
:qQuit (when no changes)
:q!Force quit ignoring changes
:wqSave and quit
:wq!Force save and quit
:xSave and quit only if changes exist (same as ZZ)
ZZSame as :x
ZQSame as :q!
:e filenameOpen file
:e!Discard current file changes and reload
:r filenameInsert file contents at current position
:r !commandInsert command output at current position

7.2 Search and Replace

CommandAction
:%s/old/new/gReplace all old with new in entire file
:%s/old/new/gcReplace all with confirmation for each
:%s/old/new/giReplace all ignoring case
:5,20s/old/new/gReplace in lines 5-20
:'<,'>s/old/new/gReplace in Visual selection
:%s/\s\+$//eRemove trailing whitespace
:%s/^/ /Add 4 spaces to beginning of all lines

7.3 Running External Commands

CommandAction
:!commandRun external command (e.g., :!ls -la)
:!python %Run current file with Python
:%!commandPipe entire file through command and replace with output
:.!commandPipe current line through command and replace with output
:shellTemporarily exit to shell (return with exit)

7.4 Range Specification

Range ExpressionMeaning
:5Line 5
:5,10Lines 5 through 10
:%Entire file (same as 1,$)
:.Current line
:.,$From current line to end of file
:'<,'>Visual selection
:.,+55 lines from current line

8. Buffers, Windows, and Tabs

8.1 Buffer Management

A buffer is a file loaded into memory. You can open and edit multiple files simultaneously.

CommandAction
:ls / :buffersList open buffers
:b2Switch to buffer 2
:bnSwitch to next buffer
:bpSwitch to previous buffer
:bdClose current buffer
:baOpen all buffers in split windows

8.2 Window Splitting

CommandAction
:sp / :splitHorizontal split
:vsp / :vsplitVertical split
:sp filenameOpen file in new horizontal split
:vsp filenameOpen file in new vertical split
<C-w>sHorizontal split (Normal Mode)
<C-w>vVertical split (Normal Mode)
<C-w>wMove focus to next window
<C-w>h/j/k/lMove to window in direction
<C-w>H/J/K/LMove window to that direction
<C-w>=Equalize all window sizes
<C-w>+ / <C-w>-Adjust horizontal size
Ctrl-w > / Ctrl-w <Adjust vertical size
Ctrl-w _Maximize current window vertically
Ctrl-w |Maximize current window horizontally
<C-w>qClose current window
<C-w>oClose all other windows (only)

8.3 Tab Management

CommandAction
:tabnewOpen new tab
:tabnew filenameOpen file in new tab
gtMove to next tab
gTMove to previous tab
2gtMove to tab 2
:tabcloseClose current tab
:tabonlyClose all other tabs
:tabsList tabs

9. Macros and Registers

9.1 Macros

Macros are a feature that records a sequence of keystrokes for repeated execution.

KeyAction
q{a-z}Start recording macro to register a-z
qStop recording macro
@{a-z}Execute macro from register
@@Re-execute last executed macro
10@aExecute macro in register a 10 times

Practical Macro Example: Adding quotes to the first field of each CSV line

Original:  hello,world
Target:    "hello",world

1. q a          (start recording to register a)
2. 0            (move to start of line)
3. i"<Esc>      (insert " at start of line)
4. f,           (move to first ,)
5. i"<Esc>      (insert " before ,)
6. j            (move to next line)
7. q            (stop recording)
8. 99@a         (repeat on remaining lines)

9.2 Register Types

RegisterDescription
" (unnamed)Default register. Automatically used on delete/yank
0Last yank content
1-9Recent delete/change content (cycled)
a-zUser-defined registers
A-ZAppend to lowercase register
+System clipboard
*Primary selection (Linux X11)
_Black hole register (delete without polluting registers)
%Current filename
:Last executed command
/Last search pattern

Register usage examples:

"+yy        " Yank current line to system clipboard
"+p         " Paste from system clipboard
"_dd        " Delete line without polluting registers
"ayy        " Yank current line to register a
"Ayy        " Append current line to register a
:reg        " View contents of all registers
:reg a      " View contents of register a

10. Essential .vimrc Settings

10.1 Basic Configuration Block

" ===================================================
" .vimrc Essential Settings
" ===================================================

" Basic convenience settings
set nocompatible            " Vim mode (disable Vi compatibility)
set encoding=utf-8          " Encoding
set fileencoding=utf-8
set number                  " Show line numbers
set relativenumber          " Relative line numbers (based on current line)
set cursorline              " Highlight current line
set showmatch               " Highlight matching brackets
set nowrap                  " Disable line wrapping
set scrolloff=8             " Maintain margin when scrolling
set signcolumn=yes          " Always show sign column

" Search settings
set hlsearch                " Highlight search results
set incsearch               " Incremental search
set ignorecase              " Case insensitive
set smartcase               " Case sensitive when uppercase included

" Tab/indentation settings
set tabstop=4               " Tab = 4 spaces
set shiftwidth=4            " Indent = 4 spaces
set softtabstop=4
set expandtab               " Convert tabs to spaces
set autoindent              " Auto indent
set smartindent             " Smart indent

" Performance/UX settings
set lazyredraw              " Minimize screen updates during macro execution
set updatetime=250          " Swap file update interval (ms)
set timeoutlen=300          " Key input timeout (ms)
set hidden                  " Allow hidden buffers (switch without saving)
set history=1000            " Command history size 1000
set undolevels=1000         " Maximum undo count

" File type and syntax highlighting
filetype plugin indent on   " Enable filetype plugins/indentation
syntax on                   " Enable syntax highlighting
set background=dark         " Dark background

" Clipboard
set clipboard=unnamedplus   " Use system clipboard (Linux)
" set clipboard=unnamed     " macOS

" Disable backup files
set nobackup
set nowritebackup
set noswapfile

" Status bar
set laststatus=2            " Always show status bar
set ruler                   " Show cursor position
set showcmd                 " Show command being typed

" Mouse support (optional)
set mouse=a

10.2 Useful Key Mappings

" ===================================================
" Key Mappings
" ===================================================

let mapleader = " "         " Set Leader key to spacebar

" General convenience mappings
nnoremap <Leader>w :w<CR>         " <Space>w to save
nnoremap <Leader>q :q<CR>         " <Space>q to quit
nnoremap <Leader>wq :wq<CR>       " <Space>wq to save+quit
nnoremap <Leader>ev :e ~/.vimrc<CR>  " Quick edit vimrc

" Clear search highlighting
nnoremap <Leader>/ :nohlsearch<CR>

" Window navigation (Ctrl + hjkl)
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l

" Move lines (Alt + j/k)
nnoremap <A-j> :m .+1<CR>==
nnoremap <A-k> :m .-2<CR>==
vnoremap <A-j> :m '>+1<CR>gv=gv
vnoremap <A-k> :m '<-2<CR>gv=gv

" Keep Visual selection after indenting
vnoremap < <gv
vnoremap > >gv

" Exit terminal mode
tnoremap <Esc> <C-\><C-n>

" Make Y behave like D and C (yank from cursor to end of line)
nnoremap Y y$

" Keep centered while searching
nnoremap n nzzzv
nnoremap N Nzzzv

" Preserve register on paste
xnoremap <Leader>p "_dP

" Buffer navigation
nnoremap <Leader>bn :bnext<CR>
nnoremap <Leader>bp :bprevious<CR>
nnoremap <Leader>bd :bdelete<CR>

11. Plugin Ecosystem

11.1 Installing vim-plug

# Vim
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
    https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

# Neovim
curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs \
    https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

11.2 .vimrc Plugin Configuration Example

call plug#begin('~/.vim/plugged')

Plug 'preservim/nerdtree'           " File tree
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'             " Fuzzy finder
Plug 'neoclide/coc.nvim', {'branch': 'release'}  " LSP
Plug 'vim-airline/vim-airline'      " Status bar
Plug 'vim-airline/vim-airline-themes'
Plug 'tpope/vim-fugitive'           " Git integration
Plug 'tpope/vim-surround'           " Surround manipulation
Plug 'tpope/vim-commentary'         " Comment toggling
Plug 'airblade/vim-gitgutter'       " Git diff display
Plug 'morhetz/gruvbox'              " Color theme

call plug#end()

11.3 Key Plugin Overview

PluginFunctionKey Commands
NERDTreeFile tree explorer:NERDTreeToggle (<C-n>)
fzf.vimFuzzy file/content search:Files, :Rg, :Buffers
coc.nvimLSP, autocomplete, diagnosticsgd (go to definition), K (docs)
vim-surroundSurround with brackets/quotescs"', ds", ysiw"
vim-commentaryComment togglegcc (line), gc (Visual)
vim-fugitiveGit integration:G, :Gblame, :Gdiff
vim-gitgutterGutter change indicators]c / [c (hunk navigation)
vim-airlineEnhanced status barAuto-activated
gruvboxRetro color themecolorscheme gruvbox

11.4 vim-surround Usage

cs"'        → Change "Hello" to 'Hello' (change surrounding)
cs({Change (Hello) to { Hello }
ds"         → Remove quotes from "Hello" (delete surrounding)
ysiw"       → Add "" around word under cursor (you surround inner word)
yss)Wrap entire line with ()
S"          → Wrap Visual selection with ""

11.5 Why Switch to Neovim

Neovim is compatible with Vim while offering the following advantages.

FeatureVimNeovim
Config LanguageVimscriptVimscript + Lua
Built-in LSPNone (plugin required)Built-in support
Async APILimitedFull async
TreesitterNoneBuilt-in support
Config File~/.vimrc~/.config/nvim/init.lua
Recommended DistrosLazyVim, AstroNvim, NvChad
# Install Neovim
brew install neovim              # macOS
sudo apt install neovim          # Ubuntu
sudo dnf install neovim          # Fedora/RHEL

# Install LazyVim (recommended distro)
git clone https://github.com/LazyVim/starter ~/.config/nvim

12. Comprehensive Cheat Sheet

12.1 Top Priority Commands to Memorize

CategoryCommandDescription
Escape<Esc>Return to Normal Mode
Save/Quit:wqSave and quit
Force Quit:q!Quit ignoring changes
Navigationgg / GFile start / end
Navigation/patternSearch
Navigationn / NNext/previous match
EditingddDelete line
EditingyyYank line
EditingpPaste
EditinguUndo
Editing<C-r>Redo
EditingciwChange word
Modev / V / <C-v>Visual modes
Window<C-w>s / <C-w>vSplit
Replace:%s/old/new/gGlobal replace

12.2 Operator + Motion Combination Formula

{count}{operator}{motion or text object}

Examples:
  3dd     → Delete 3 lines
  2yy     → Yank 2 lines
  d3w     → Delete 3 words
  ci"     → Change contents inside quotes
  da(Delete including parentheses
  >ip     → Indent paragraph

12.3 Insert Mode Shortcuts

KeyAction
<C-w>Delete previous word
<C-u>Delete to start of line
<C-h>Delete one character (Backspace)
<C-t>Add indent
<C-d>Remove indent
<C-r>{reg}Insert register contents
<C-r>=Insert expression result (e.g., <C-r>=2+2<CR> yields 4)
<C-o>{cmd}Execute one Normal Mode command then return to Insert Mode

12.4 Essential Command Mode Patterns

CommandDescription
:%s/\n/,/gReplace newlines with commas
:%s/^\s*$\n//gRemove blank lines
:%s/\s\+$//eRemove trailing whitespace
:%!sortSort entire file
:%!sort -uSort entire file and remove duplicates
:g/pattern/dDelete lines containing pattern
:v/pattern/dDelete lines not containing pattern (inverse)
:g/pattern/y AYank all lines containing pattern to register A

13. Reference

All commands covered in this post can be explored in detail within Vim using :help {command}. For example: :help text-objects, :help registers, :help macros