Vim Basics: Essential Commands and Practical Techniques

Vim Basics: Essential Commands and Practical Techniques

What You'll Learn

  • Understand Vim modes and stop getting stuck
  • Master the minimum workflow for movement, editing, and search/replace used in real work
  • Set up a comfortable .vimrc for any new server
  • Stay productive when only vi is installed on a remote box

Quick Summary (the practical workflow)

  • After launching, always think in normal mode first (Esc)
  • The editing loop is: i → edit → Esc:w — four steps
  • If you get stuck, press Esc twice, then :q! to force-quit
  • For config files, use sudoedit, not sudo vim

Assumed environment

  • OS: Ubuntu or any Linux
  • Vim 8+ or Neovim (vi-compatibility quirks are noted)
  • Mainly remote server work over SSH

1. Modes: 80% of the Battle

The single biggest reason beginners give up on Vim is modes. Once you internalize them, the rest is just memorizing commands.

Mode How to enter What you can do
Normal Esc Move, delete, copy
Insert i / a / o Type text
Visual v / V Select ranges
Command-line : Save, quit, replace

Rule of thumb: When anything weird happens, hit Esc twice to return to normal mode.

1-1. Entering Insert Mode (Which Key to Use)

i   # Insert before cursor
a   # Insert after cursor (great at end of line)
o   # Open new line below
O   # Open new line above
I   # Insert at start of line
A   # Insert at end of line

At first, just use i and o. Once comfortable, A (append at end) becomes a daily driver.

2. Save and Quit: The #1 Stuck Point

This is where the "I can't escape Vim" memes come from. Memorize this section.

:w           # Write (save)
:q           # Quit
:wq          # Save and quit
:x           # Save and quit (only writes if changed)
ZZ           # Same as :wq in normal mode
:q!          # Quit without saving
:w !sudo tee %   # Save a file you forgot to open with sudo (see below)

Plain :q refuses to quit if there are unsaved changes. Use :q! to discard, :wq to keep them.

2-1. Recovering from a sudo Mistake

Classic accident: open /etc/something with vim, edit it, then hit Permission denied on save.

:w !sudo tee % > /dev/null
  • % expands to the current filename
  • tee writes to disk; > /dev/null discards stdout
  • After saving, :q! (file is already on disk, so ! is fine)

The proper fix: edit config files with sudoedit /etc/ssh/sshd_config (alias sudo -e). It opens a temp copy and writes back on exit.

3. Movement: Skip the Mouse

These work in normal mode only. They do nothing in insert mode.

3-1. Character-Level

h j k l   # left down up right

Mnemonic: j looks like a hook going down, k punches up.

3-2. Word, Line, Screen

w / b      # Next / previous word start
e          # End of word
0 / ^ / $  # Start of line / first non-blank / end of line
gg / G     # Top / bottom of file
:42        # Jump to line 42
Ctrl-d / Ctrl-u   # Half-screen down / up
Ctrl-f / Ctrl-b   # Full-screen down / up

3-3. Search-Based Movement

/word      # Search forward
?word      # Search backward
n / N      # Next / previous match
*          # Search forward for word under cursor

Practical tip: When tailing a log, hit G to jump to the end, then ?ERROR to search backward.

4. Editing: The Bare Minimum

x          # Delete one character
dd         # Delete a line (into clipboard)
3dd        # Delete 3 lines
dw         # Delete a word
d$ / D     # Delete to end of line
yy         # Yank (copy) a line
3yy        # Yank 3 lines
p / P      # Paste (after / before)
u          # Undo
Ctrl-r     # Redo
.          # Repeat last change

The most powerful command is . (dot). It repeats your last edit. Run dw once, move the cursor, hit . — same edit applied.

4-1. Numeric Prefixes

Almost any command takes a count prefix.

5j         # Move 5 lines down
10x        # Delete 10 characters
3yy        # Yank 3 lines

5. Search and Replace: Daily Driver

/pattern   # Forward (regex allowed)
?pattern   # Backward
n / N      # Next / previous

5-2. Replace (The Important One)

:s/foo/bar/        # First match on current line
:s/foo/bar/g       # All matches on current line
:%s/foo/bar/g      # All matches in the file
:%s/foo/bar/gc     # Same, with confirmation
:5,10s/foo/bar/g   # Only lines 5-10

:%s/foo/bar/g is powerful and dangerous. Start with the gc flag for confirmation mode, then walk through with y (yes), n (no), a (all), q (quit).

5-3. Regex Pitfalls

Vim's regex flavor differs subtly from POSIX extended regex.

:%s/\v(\w+)\s+\1/\1/g   # \v enables "very magic" — closer to standard regex

With \v, you no longer need to escape (), +, or ?. Save it as muscle memory; it prevents a lot of head-scratching.

6. Multiple Files and Windows

6-1. Buffers (Multiple Files)

:e other.txt    # Open another file
:ls             # List open buffers
:b 2            # Switch to buffer 2
:bn / :bp       # Next / previous buffer
:bd             # Close buffer

6-2. Split Windows

:sp file.txt    # Horizontal split
:vsp file.txt   # Vertical split
Ctrl-w w        # Cycle through windows
Ctrl-w q        # Close current window
Ctrl-w =        # Equalize window sizes

A common setup: logs on one side, config file on the other. Pair with tmux over SSH for an even stronger workflow.

7. Visual Mode: Operate on a Selection

v          # Start character-wise selection
V          # Start line-wise selection
Ctrl-v     # Start block (rectangular) selection

With a selection active:

d          # Delete
y          # Yank
>          # Indent
<          # Outdent
:s/a/b/    # Replace within selection only

Block selection trick: To prefix multiple lines with # (comment them out), use Ctrl-v → select lines → I#Esc. It applies the prefix to all selected lines at once.

8. .vimrc: A Minimal Setup

Write this in ~/.vimrc. It's small enough that you can retype it on a fresh server in 30 seconds.

" Basics
set number              " Show line numbers
set ruler               " Show cursor position
set showcmd             " Show partial commands
set wildmenu            " Better command completion

" Search
set hlsearch            " Highlight matches
set incsearch           " Incremental search
set ignorecase          " Case-insensitive
set smartcase           " But case-sensitive if pattern has uppercase

" Indent
set autoindent          " Auto indent
set expandtab           " Tab -> spaces
set tabstop=4           " Tab width
set shiftwidth=4        " Indent width

" Safety
set backup              " Keep backup files
set backupdir=~/.vim/backup,/tmp
set undofile            " Persistent undo
set undodir=~/.vim/undo

" UI
syntax on               " Syntax highlighting
set background=dark     " Assume dark terminal

Create the directories first: mkdir -p ~/.vim/backup ~/.vim/undo.

On a server with only vi (Vim's compatibility mode), some set options silently fail. Check :version to see what's available.

9. Escape Routes When Stuck

Common stuck states and the mechanical fix.

9-1. Can't Quit

Esc Esc :q!

Always return to normal mode first, then force-quit.

9-2. Can't Save (Read-Only)

:set noreadonly
:w

Or use the sudo trick: :w !sudo tee % > /dev/null.

9-3. Frozen Screen

Ctrl-q        # Resume a terminal stopped by Ctrl-s

Ctrl-s pauses the terminal itself — not a Vim problem.

9-4. Strange Characters Like ~ Appearing

A swap file (.swp) is left over.

ls -la .file.swp
:recover       # Run inside Vim

If genuinely abandoned, rm .file.swp will clear it.

Check first: someone else may be editing right now. Run ps aux | grep vim before deleting swap files.

10. vi vs Vim vs Neovim

Name What it really is Notes
vi Usually Vim running in vi-compatible mode Some settings disabled
Vim Vi IMproved The de facto standard
Neovim A fork of Vim Lua config, built-in LSP, modern internals
which vi       # /usr/bin/vi
ls -l $(which vi)   # Often a symlink to vim or vim.basic

Minimal Ubuntu installs may only have vim-tiny. Install the full version with sudo apt install vim.

11. Summary: The Workflow You'll Use Tomorrow

Copy-paste template: minimum daily workflow

# 1. Open
vim file.txt

# 2. Move in normal mode
gg              # Top of file
/keyword        # Search

# 3. Switch to insert mode
i               # Start editing
(edit)
Esc             # Back to normal

# 4. Save and quit
:wq

# If you mess up
:q!             # Discard and quit

Don't do this

  • Typing :wq while still in insert mode (you write :wq into the file)
  • Opening a file with sudo vim /etc/... and getting stuck on save — use sudoedit instead
  • Reflexively deleting .swp files — someone may be editing
  • Bloating your .vimrc — it stops being portable across servers

Next Reading