Vim Tutorial for Beginners: Learn Vim Step by Step

✅ Tested with Vim 9.1 and Neovim 0.9 on Linux — Last updated: June 2026
Vim is the most powerful text editor available on Linux, and it's installed on virtually every Unix-like system you'll ever touch. Whether you're editing a config file on a headless server via SSH or writing code, knowing Vim is a survival skill for Linux users. This guide teaches you Vim from zero — opening files, basic editing, saving — up to intermediate workflows that will make you genuinely productive.
Table of Contents
- Install Vim / Neovim
- The Three Modes
- Opening and Closing Files
- Navigation Commands
- Editing Commands
- Search and Replace
- Visual Mode
- Undo and Redo
- Multiple Files and Buffers
- The .vimrc Configuration File
- Essential Plugins
- Neovim — The Modern Fork
- Cheat Sheet
Install Vim
# Ubuntu / Debian:
sudo apt install vim -y
# Fedora:
sudo dnf install vim -y
# Arch Linux:
sudo pacman -S vim
# Check version:
vim --version | head -2
# VIM - Vi IMproved 9.1The Three Modes — The Most Important Concept
Vim is a modal editor. This is the single most important thing to understand. Unlike every other editor where you just start typing, Vim has distinct modes, each with different behavior for keystrokes.
- Normal Mode (default): Keys are commands, not characters.
ddeletes,ycopies (yanks),ppastes,wmoves forward a word. PressEscto return to Normal mode from anywhere. - Insert Mode: Keys type text, like a normal editor. Enter it with
i,a,o, etc. - Visual Mode: Select text with movement keys. Enter with
v(character),V(line), orCtrl+V(block). - Command Mode: Enter
:in Normal mode to run Ex commands — save, quit, search/replace, run shell commands.
# How to know which mode you're in:
# - Bottom left shows "-- INSERT --" when in Insert mode
# - Bottom left shows "-- VISUAL --" when in Visual mode
# - Normal mode shows nothing
# - Pressing Esc always gets you back to Normal modeOpening and Closing Files
# Open a file:
vim myfile.txt
vim /etc/nginx/nginx.conf
# Open multiple files:
vim file1.txt file2.txt
# Open at a specific line:
vim +42 myfile.txt # open at line 42
vim +/search_term myfile.txt # open at first occurrence of search_term
# From inside vim:
:e /path/to/file # open/edit another file
:e! # reload current file (discard unsaved changes)Saving and Quitting (Most Important Commands)
:w # save (write)
:w file.txt # save to specific filename
:q # quit (fails if unsaved changes)
:q! # quit WITHOUT saving (force)
:wq # save and quit
:x # save and quit (only writes if changes were made)
ZZ # same as :x (Normal mode shortcut)
ZQ # same as :q! (Normal mode shortcut)The single most common mistake for new Vim users: they type :wq but accidentally typed characters first. If you're stuck: press Esc several times until the mode indicator disappears, then type :q! to exit without saving.
Navigation Commands
In Normal mode, the keyboard is entirely dedicated to commands. You'll use these constantly:
Basic Movement
h / l # left / right
j / k # down / up (think: j has a tail that points down)
0 # beginning of line
^ # first non-blank character of line
$ # end of line
gg # go to first line of file
G # go to last line of file
50G # go to line 50
50gg # sameWord Navigation
w # next word (beginning)
W # next WORD (whitespace delimited)
e # end of current word
E # end of current WORD
b # back to previous word
B # back to previous WORD
# Example: on "hello_world.txt":
# w stops at: h, _, w, ., t, x, t (punctuation = word boundaries)
# W stops at: h (only whitespace = boundaries)Screen Navigation
Ctrl+F # page down (Forward)
Ctrl+B # page up (Backward)
Ctrl+D # half page down
Ctrl+U # half page up
H # move cursor to top of screen (High)
M # move cursor to middle of screen (Middle)
L # move cursor to bottom of screen (Low)
zz # scroll so current line is in centerSearching for Navigation
f{char} # jump to next occurrence of char on current line
F{char} # jump to previous occurrence
t{char} # jump to just before next occurrence
; # repeat last f/F/t search
, # repeat in opposite direction
% # jump to matching bracket/parenthesis/braceEditing Commands
Entering Insert Mode
i # insert before cursor
a # append after cursor
I # insert at beginning of line
A # append at end of line
o # open new line below and insert
O # open new line above and insert
s # substitute (delete char, enter insert)
S # substitute line (delete line, enter insert)
cc # change entire line
C # change from cursor to end of lineDelete, Copy, Paste
Vim uses "operators + motions" — most commands follow the pattern: [count] [operator] [motion].
# Delete (cut):
x # delete character under cursor
X # delete character before cursor
dd # delete current line
dw # delete from cursor to end of word
d$ # delete from cursor to end of line
d0 # delete from cursor to beginning of line
d5j # delete current and 5 lines below
dgg # delete from cursor to start of file
dG # delete from cursor to end of file
# Copy (yank):
yy # yank (copy) current line
yw # yank word
y$ # yank to end of line
5yy # yank 5 lines
yG # yank to end of file
# Paste:
p # paste after cursor/below current line
P # paste before cursor/above current line
# Change (delete + enter insert mode):
cw # change word
cc # change entire line
c$ # change to end of lineText Objects — The Secret Weapon
Text objects let you operate on "things" like words, sentences, blocks. Combine operators with i (inner) or a (around/all):
diw # delete inner word (cursor anywhere in word)
daw # delete a word (including trailing space)
ci" # change inside double quotes (replaces content)
ca" # change around double quotes (including the quotes)
di( # delete inside parentheses
da( # delete including parentheses
ci{ # change inside curly braces (great for functions)
dip # delete inner paragraph
vip # visually select inner paragraph
# In practice — cursor somewhere in print("hello"):
ci" # deletes "hello", puts you in insert mode to type replacementSearch and Replace
# Search:
/pattern # search forward
?pattern # search backward
n # next match
N # previous match
* # search for word under cursor (forward)
# # search for word under cursor (backward)
# In your .vimrc:
set hlsearch # highlight search results
set incsearch # search as you type
set ignorecase # case insensitive search
set smartcase # ...unless you type a capital letter
# Clear search highlight:
:noh
# Search and replace (s = substitute):
:s/old/new/ # replace first on current line
:s/old/new/g # replace all on current line
:%s/old/new/g # replace all in entire file
:%s/old/new/gc # replace all, ask for confirmation
:5,10s/old/new/g # replace in lines 5 to 10
:%s/boldb/new/g # replace whole word "old" (word boundary)
# Replace with special characters:
:%s/old/newr/g # replace with newline (r in replacement)
:%s/ +/ /g # compress multiple spaces to oneVisual Mode
v # character visual mode (select character by character)
V # line visual mode (select entire lines)
Ctrl+V # block visual mode (select columns)
# After selecting text:
d # delete selection
y # yank (copy) selection
c # change (delete + insert)
> # indent selection
< # unindent selection
~ # toggle case of selected text
u # lowercase selection
U # uppercase selection
: # enter command mode for selected range
# Block visual mode is very powerful:
# Select a column, then:
I # insert at beginning of each selected line
A # append at end of each selected lineUndo and Redo
u # undo
Ctrl+R # redo
5u # undo 5 times
:undolist # show undo history tree
:earlier 5m # go to file state 5 minutes ago
:later 5m # go forward 5 minutesMultiple Files and Buffers
# Buffers (open files in memory):
:ls # list all buffers
:b2 # switch to buffer 2
:bn # next buffer
:bp # previous buffer
:bd # delete (close) current buffer
# Windows (split views):
:split file.txt # horizontal split
:vsplit file.txt # vertical split
Ctrl+W then h/j/k/l # navigate between windows
Ctrl+W then w # cycle through windows
Ctrl+W then +/- # resize horizontal split
Ctrl+W then >/ # resize vertical split
Ctrl+W then = # equal size
Ctrl+W then q # close current window
:only # close all except current
# Tabs:
:tabnew file.txt # open in new tab
:tabn # next tab
:tabp # previous tab
gt # next tab
gT # previous tab
:tabclose # close current tabThe .vimrc Configuration File
Create ~/.vimrc to configure Vim to your preferences. Here's a practical starting configuration:
" ~/.vimrc — practical Vim configuration
" Basic settings
set nocompatible " modern Vim mode
syntax enable " syntax highlighting
set number " line numbers
set relativenumber " relative line numbers (for fast navigation)
set ruler " show cursor position
set showcmd " show command being typed
" Indentation
set tabstop=4 " tab = 4 spaces
set shiftwidth=4 " indent = 4 spaces
set expandtab " use spaces, not tabs
set autoindent " keep indentation on new lines
set smartindent " smart auto-indent
" Search
set hlsearch " highlight search
set incsearch " search as you type
set ignorecase " case insensitive
set smartcase " case sensitive if capital letters used
" Behavior
set backspace=indent,eol,start " backspace works everywhere
set scrolloff=8 " keep 8 lines above/below cursor
set wrap " wrap long lines
set linebreak " wrap at word boundaries
set wildmenu " autocomplete in command mode
set wildmode=list:longest " smart autocomplete
set undofile " persistent undo (survives closing vim)
set mouse=a " enable mouse (if you want it)
" File
set encoding=utf-8
set fileencoding=utf-8
" Key mappings
let mapleader = "," " change leader key to comma
" Quick save
nmap w :w!
" Clear search highlight
nmap :noh
" Navigate splits with Ctrl+hjkl
nnoremap h
nnoremap j
nnoremap k
nnoremap l
" Yank to end of line (consistent with D)
nnoremap Y y$ Essential Plugins
Install vim-plug (plugin manager):
curl -fLo ~/.vim/autoload/plug.vim --create-dirs
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vimAdd to ~/.vimrc:
call plug#begin()
Plug 'tpope/vim-sensible' " sensible defaults
Plug 'tpope/vim-surround' " surround text with brackets, quotes
Plug 'tpope/vim-commentary' " gc to comment/uncomment lines
Plug 'jiangmiao/auto-pairs' " auto-close brackets and quotes
Plug 'airblade/vim-gitgutter' " show git changes in gutter
Plug 'preservim/nerdtree' " file tree
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } " fuzzy file finder
Plug 'junegunn/fzf.vim'
Plug 'morhetz/gruvbox' " popular color scheme
call plug#end()
" Install plugins: :PlugInstall
" Update plugins: :PlugUpdateNeovim — The Modern Fork
Neovim is a fork of Vim that adds: Lua scripting for config, built-in LSP (language server protocol) support, Tree-sitter for better syntax, and an active plugin ecosystem. For serious development work, Neovim + lazy.nvim (plugin manager) has become the modern choice.
# Install Neovim:
sudo apt install neovim -y # Ubuntu (may be outdated version)
# For latest version:
sudo add-apt-repository ppa:neovim-ppa/stable -y
sudo apt update && sudo apt install neovim
sudo dnf install neovim -y # Fedora
sudo pacman -S neovim # Arch
nvim --version
# Neovim uses ~/.config/nvim/init.vim (or init.lua for Lua config)
# Your ~/.vimrc works in Neovim with: ln -s ~/.vimrc ~/.config/nvim/init.vimVim Cheat Sheet — The Essentials
| Category | Command | What It Does |
|---|---|---|
| Mode | Esc | Return to Normal mode |
| Mode | i / a / o | Enter Insert before / after / on new line |
| Save/Quit | :w | Save |
| Save/Quit | :q! | Quit without saving |
| Save/Quit | :wq or ZZ | Save and quit |
| Navigation | gg / G | First / Last line |
| Navigation | 0 / $ | Start / End of line |
| Navigation | Ctrl+F / Ctrl+B | Page down / up |
| Delete | dd / dw | Delete line / word |
| Copy | yy / yw | Copy line / word |
| Paste | p / P | Paste after / before |
| Undo | u / Ctrl+R | Undo / Redo |
| Search | /pattern | Search forward |
| Replace | :%s/old/new/g | Replace all in file |
| Visual | v / V | Select chars / lines |
Frequently Asked Questions
I'm stuck in Vim and can't exit!
This is so common there are jokes about it. Press Esc (maybe several times) to make sure you're in Normal mode, then type :q! and press Enter. The ! forces quit without saving. If that doesn't work, you may be in a recursive state — type :qa! (quit all) or in absolute emergency, press Ctrl+C then :q!.
Should I use Vim or Neovim?
For editing config files on servers: use whatever's installed (usually Vim). For your daily development environment where you want IDE features (autocomplete, linting, debugging): Neovim with lazy.nvim and LSP setup is excellent. Both share the same modal editing model and most keybindings.
Is Vim worth learning when VS Code exists?
Yes, for two reasons: (1) Vim or Vi is available on every Linux/Unix server you'll ever SSH into — you don't always have a choice, and being comfortable with it is a real advantage. (2) Vim keybindings are so effective that VS Code, JetBrains IDEs, and even Obsidian offer Vim emulation modes. Learning Vim makes you faster everywhere. The investment pays off.
Learning Vim takes about a week to feel comfortable and a month to feel fast. Stick with it — the modal editing model is worth the initial friction. And when you're working on remote servers via SSH, being proficient in Vim means you're never helpless.
