Vim Configuration
Summary: in this tutorial, you will learn customize vim to your preferences with vimrc settings, custom mappings, autocommands, a custom status line, and plugin management.
Vim Configuration
Now that you know how to edit, navigate, and manage files in Vim, it's time to make Vim truly yours. Vim is incredibly customizable — you can change almost every behavior, create your own keyboard shortcuts, and even install plugins that add new features.
What you'll learn in this tutorial:
- How to organize your vimrc file clearly
- How to create custom keyboard shortcuts (mappings)
- What autocommands are and how they automate repetitive tasks
- How to build a custom status line showing useful information
- How to install and manage plugins
- A complete, well-commented vimrc you can use as a starting point
The vimrc File
Your ~/.vimrc file (on Windows: ~/_vimrc or $HOME/_vimrc) is Vim's configuration file. It runs every time Vim starts. If you followed the installation tutorial, you already have one.
Where is my vimrc? To find out, open Vim and type :echo $MYVIMRC and press Enter. Vim will show you the full path to your configuration file.
Organizing Your vimrc
As your vimrc grows, it helps to organize it into sections using comments. In Vim's configuration language, comments start with " (double quote):
" ============================================================
" GENERAL SETTINGS
" ============================================================
set nocompatible " Use Vim features, not old vi compatibility
set encoding=utf-8 " Use modern text encoding
" ============================================================
" DISPLAY SETTINGS
" ============================================================
set number " Show line numbers
set relativenumber " Show relative line numbers (distance from current line)
set cursorline " Highlight the line the cursor is on
set showmatch " Briefly highlight matching bracket when you type one
set wrap " Wrap long lines to the next screen line
set linebreak " Wrap at word boundaries, not in the middle of a word
" ============================================================
" SEARCH SETTINGS
" ============================================================
set incsearch " Show matches as you type
set hlsearch " Highlight all matches
set ignorecase " Case-insensitive search by default
set smartcase " ...unless you type a capital letter
" ============================================================
" EDITING SETTINGS
" ============================================================
set tabstop=4 " A tab character looks like 4 spaces
set shiftwidth=4 " Indenting (> and <) uses 4 spaces
set expandtab " Pressing Tab inserts spaces instead of a tab character
set autoindent " New lines get the same indentation as the previous line
set smartindent " Vim guesses the right indentation for code
set backspace=indent,eol,start " Backspace works normally (can delete anything)
" ============================================================
" BEHAVIOR SETTINGS
" ============================================================
set hidden " Allow switching buffers without saving
set wildmenu " Show completion menu when pressing Tab in command mode
set wildmode=list:longest " Complete to the longest common match
set scrolloff=8 " Keep 8 lines visible above/below the cursor
set mouse=a " Enable mouse support (click, scroll, select)
set clipboard=unnamedplus " Use the system clipboard for copy/pasteDon't memorize these settings! Add them to your vimrc, use Vim for a while, and if something bothers you, search for a setting to fix it. You can also type :set option? (with a question mark) to see the current value of any setting. For example :set tabstop? shows how many spaces a tab uses.
Custom Mappings (Keyboard Shortcuts)
Mappings let you create your own keyboard shortcuts. The most common type is nnoremap, which creates a mapping in Normal mode:
" The format is:
" nnoremap shortcut commandLet's break down the mapping command names:
| Prefix | Mode | Stands For |
|---|---|---|
nnoremap | Normal mode | normal non-recursive map |
inoremap | Insert mode | insert non-recursive map |
vnoremap | Visual mode | visual non-recursive map |
cnoremap | Command-line mode | command non-recursive map |
What does "noremap" mean? The "noremap" part means "non-recursive map." This ensures your mapping doesn't trigger other mappings, which could cause infinite loops. Always use noremap versions (not nmap, imap, etc.) unless you specifically want recursive behavior.
The Leader Key
The leader key is a special prefix for custom shortcuts, so they don't conflict with Vim's built-in keys. By default, the leader key is \ (backslash), but most people remap it to the spacebar or comma:
let mapleader = " " " Set leader key to Space
" Now you can create shortcuts like <leader>w which means Space + wUseful Custom Mappings
Here are practical mappings with explanations:
" ---- FILE OPERATIONS ----
" Save file with Space+w (instead of typing :w and Enter)
nnoremap <leader>w :w<CR>
" Quit with Space+q
nnoremap <leader>q :q<CR>
" Save and quit with Space+x
nnoremap <leader>x :wq<CR>
" ---- SEARCH ----
" Clear search highlights with Space+h
nnoremap <leader>h :nohlsearch<CR>
" ---- WINDOW NAVIGATION ----
" Move between windows with Ctrl+h/j/k/l (instead of Ctrl-w h/j/k/l)
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
" ---- BUFFER NAVIGATION ----
" Next/previous buffer with Space+n / Space+p
nnoremap <leader>n :bnext<CR>
nnoremap <leader>p :bprevious<CR>
" Close current buffer with Space+d
nnoremap <leader>d :bd<CR>
" ---- CONVENIENCE ----
" Move selected lines up/down in Visual mode
vnoremap J :m '>+1<CR>gv=gv
vnoremap K :m '<-2<CR>gv=gv
" Keep cursor centered when scrolling
nnoremap <C-d> <C-d>zz
nnoremap <C-u> <C-u>zz
" Keep search results centered
nnoremap n nzz
nnoremap N Nzz
" Indent in Visual mode without losing selection
vnoremap > >gv
vnoremap < <gv
" Quick escape from Insert mode by typing 'jk' quickly
inoremap jk <Esc>The <CR> at the end of mappings stands for "Carriage Return" — it's the same as pressing Enter. Without it, Vim would type the command but wait for you to press Enter manually.
Reading a Mapping
Let's decode this mapping step by step:
nnoremap <leader>w :w<CR>| Part | Meaning |
|---|---|
nnoremap | Create a non-recursive mapping for Normal mode |
<leader>w | When I press the leader key (Space) followed by w... |
:w<CR> | ...execute :w (save) and press Enter (<CR>) |
Autocommands (Automatic Actions)
Autocommands tell Vim to automatically run commands when certain events happen — like opening a file, saving, or switching buffers.
The format is:
autocmd Event Pattern Command- Event — when to trigger (e.g., opening a file, saving a file)
- Pattern — which files to apply to (e.g.,
*.py,*.js,*) - Command — what to do
Common Autocommands
" Remove trailing whitespace when saving any file
autocmd BufWritePre * %s/\s\+$//e
" Set indentation to 2 spaces for JavaScript and HTML files
autocmd FileType javascript,html setlocal tabstop=2 shiftwidth=2
" Set indentation to 4 spaces for Python files
autocmd FileType python setlocal tabstop=4 shiftwidth=4
" Return to the last position when reopening a file
autocmd BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$") | exe "normal! g`\"" | endif
" Automatically reload files that changed outside Vim
set autoread
autocmd FocusGained,BufEnter * checktimeWhat do those events mean?
| Event | When It Fires |
|---|---|
BufWritePre | Just before a file is saved (great for cleanup) |
BufReadPost | Just after a file is opened |
FileType | When Vim detects the file type (python, javascript, etc.) |
FocusGained | When Vim gets focus back (you switch from another app) |
BufEnter | When you switch to a buffer |
Autocommand Groups (Preventing Duplicates)
If you reload your vimrc (:source ~/.vimrc), autocommands get added again, resulting in duplicates. Wrapping them in groups with autocmd! prevents this:
augroup MyAutocommands
autocmd! " Clear existing autocommands in this group
autocmd BufWritePre * %s/\s\+$//e
autocmd FileType python setlocal tabstop=4 shiftwidth=4
autocmd FileType javascript setlocal tabstop=2 shiftwidth=2
augroup ENDautocmd! at the start of the group tells Vim: "Delete any autocommands that were already in this group." This way, even if you reload your vimrc multiple times, you won't get duplicate autocommands.
Custom Status Line
The status line is the bar at the bottom of each window. By default, it shows minimal info, but you can make it much more useful:
set laststatus=2 " Always show the status line (even with one window)
" Build a custom status line
set statusline= " Clear the status line first
set statusline+=%f " File path (relative to current directory)
set statusline+=\ %m " Modified flag ([+] if unsaved changes)
set statusline+=\ %r " Read-only flag ([RO] if you can't edit)
set statusline+=%= " Switch to the right side
set statusline+=\ %y " File type (e.g., [python], [javascript])
set statusline+=\ %l:%c " Current line:column number
set statusline+=\ [%p%%] " Percentage through the fileThis creates a status line like:
src/app.js [+] [javascript] 42:15 [68%]
What each piece means:
| Code | What It Shows |
|---|---|
%f | The file name/path |
%m | [+] if the file has unsaved changes |
%r | [RO] if the file is read-only |
%= | Everything after this goes on the right side |
%y | The file type (e.g., [vim], [python]) |
%l | Current line number |
%c | Current column number |
%p%% | Percentage through the file (%% prints a literal %) |
Plugin Management
Plugins add new features to Vim. The easiest way to manage them is with a plugin manager. We'll use vim-plug — it's simple, fast, and widely used.
Installing vim-plug
Run this command in your terminal (for Unix/Mac):
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vimWhat does this command do?
curldownloads a file from the internet-fLomeans: fail silently on errors (f), follow redirects (L), and save to a specific output file (o)~/.vim/autoload/plug.vimis where the file is saved — Vim automatically runs files in theautoloaddirectory--create-dirscreates the directories if they don't exist
For Windows (PowerShell):
iwr -useb https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim |`
ni $HOME/vimfiles/autoload/plug.vim -ForceAdding Plugins to Your vimrc
Add a plugin section to your ~/.vimrc:
" ============================================================
" PLUGINS
" ============================================================
call plug#begin('~/.vim/plugged')
" File finder — fuzzy search for any file in your project
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
" Color scheme — a popular dark theme
Plug 'morhetz/gruvbox'
" Status line — a beautiful, informative status bar
Plug 'vim-airline/vim-airline'
" Git integration — see what lines changed in the gutter
Plug 'airblade/vim-gitgutter'
" Surround — easily add/change/delete surrounding quotes, brackets, tags
Plug 'tpope/vim-surround'
" Commentary — toggle comments: gcc for a line, gc for a selection
Plug 'tpope/vim-commentary'
call plug#end()
" Apply the color scheme (after plugins are loaded)
colorscheme gruvbox
set background=darkInstalling Plugins
After adding plugins to your vimrc:
- Save the file (
:w) - Reload the vimrc (
:source ~/.vimrc) - Run
:PlugInstall
A window opens showing download progress. When it says "Done!", press q to close the window.
Managing Plugins
| Command | What It Does |
|---|---|
:PlugInstall | Install new plugins you've added |
:PlugUpdate | Update all installed plugins |
:PlugClean | Remove plugins you've deleted from vimrc |
:PlugStatus | Check the status of all plugins |
Start with few plugins! It's tempting to install dozens of plugins, but each one adds complexity. Start with the basics (a color scheme and maybe 2-3 utility plugins), learn them well, then add more as you identify specific needs. Many "essential" plugin features are already built into Vim.
Useful Plugins Explained
Here's what some popular plugins do:
vim-surround
Lets you add, change, or delete surrounding characters (quotes, brackets, tags):
cs"' " Change surrounding " to ' → "hello" becomes 'hello'
ds" " Delete surrounding " → "hello" becomes hello
ysiw" " Add " around the current word → hello becomes "hello"vim-commentary
Quickly toggle comments:
gcc " Toggle comment on the current line
gc3j " Toggle comments on 3 lines
" In Visual mode: select lines, then gc to toggle commentsfzf.vim (Fuzzy File Finder)
Search for files and text across your project:
:Files " Find files by name (fuzzy matching)
:Rg text " Search for "text" in all files (requires ripgrep installed)
:Buffers " Switch between open buffersA Complete Starter vimrc
Here's a complete, well-organized vimrc you can use as a starting point. Copy it to your ~/.vimrc:
" ============================================================
" STARTER VIMRC
" A beginner-friendly configuration for Vim
" ============================================================
" Don't try to be old vi — use all Vim features
set nocompatible
set encoding=utf-8
" --- Leader Key ---
let mapleader = " " " Space as the leader key
" --- Display ---
set number " Show line numbers
set relativenumber " Relative line numbers (helpful for motions like 5j)
set cursorline " Highlight current line
set showmatch " Flash matching bracket
set wrap " Wrap long lines
set linebreak " Wrap at word boundaries
set signcolumn=yes " Always show the sign column (for git/error indicators)
set termguicolors " Enable true colors (if your terminal supports it)
" --- Search ---
set incsearch " Live search as you type
set hlsearch " Highlight all matches
set ignorecase " Ignore case when searching
set smartcase " ...unless you use a capital letter
" --- Indentation ---
set tabstop=4 " Tab = 4 spaces visually
set shiftwidth=4 " Indent/unindent = 4 spaces
set expandtab " Insert spaces when pressing Tab
set autoindent " Keep indentation from previous line
set smartindent " Auto-indent for code blocks
" --- Behavior ---
set hidden " Switch buffers without saving
set backspace=indent,eol,start " Normal backspace behavior
set wildmenu " Command completion menu
set wildmode=list:longest " Complete to longest match
set scrolloff=8 " Keep 8 lines visible above/below cursor
set sidescrolloff=8 " Keep 8 columns visible left/right
set mouse=a " Enable mouse
set clipboard=unnamedplus " Use system clipboard
set autoread " Auto-reload files changed outside Vim
set confirm " Ask to save instead of failing
set noerrorbells " No beeping
set novisualbell " No screen flashing
" --- File Management ---
set noswapfile " Don't create swap files
set nobackup " Don't create backup files
set undofile " Keep undo history after closing
set undodir=~/.vim/undodir " Where to store undo files
" --- Key Mappings ---
nnoremap <leader>w :w<CR> " Save
nnoremap <leader>q :q<CR> " Quit
nnoremap <leader>h :nohlsearch<CR> " Clear search highlighting
" Window navigation
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
" Buffer navigation
nnoremap <leader>n :bnext<CR>
nnoremap <leader>p :bprevious<CR>
nnoremap <leader>d :bd<CR>
" Keep cursor centered when scrolling/searching
nnoremap <C-d> <C-d>zz
nnoremap <C-u> <C-u>zz
nnoremap n nzz
nnoremap N Nzz
" Stay in Visual mode when indenting
vnoremap > >gv
vnoremap < <gv
" Move lines up/down in Visual mode
vnoremap J :m '>+1<CR>gv=gv
vnoremap K :m '<-2<CR>gv=gv
" Quick escape from Insert mode
inoremap jk <Esc>
" --- Autocommands ---
augroup MySettings
autocmd!
" Remove trailing whitespace on save
autocmd BufWritePre * %s/\s\+$//e
" Return to last edit position when opening a file
autocmd BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$") | exe "normal! g`\"" | endif
" File-type-specific indentation
autocmd FileType javascript,html,css,json setlocal tabstop=2 shiftwidth=2
autocmd FileType python setlocal tabstop=4 shiftwidth=4
augroup END
" --- Status Line ---
set laststatus=2
set statusline=%f\ %m%r%=%y\ %l:%c\ [%p%%]
" --- netrw (File Explorer) ---
let g:netrw_banner = 0
let g:netrw_liststyle = 3
let g:netrw_winsize = 25Create the undo directory before using the vimrc above! The undodir setting needs the directory to exist:
mkdir -p ~/.vim/undodirOn Windows:
New-Item -ItemType Directory -Force -Path "$HOME\.vim\undodir"Summary
Here's what you've learned:
- The vimrc file (
~/.vimrc) runs every time Vim starts — it's your configuration file - Organize your vimrc into sections with comments (
") - Mappings create custom keyboard shortcuts:
nnoremap <leader>w :w<CR>saves with Space+w - The leader key (usually Space) is a prefix for your custom shortcuts
- Autocommands run commands automatically on events (saving, opening files, etc.)
- Wrap autocommands in
augroupto prevent duplicates - Customize the status line with
set statusline=... - vim-plug is a simple plugin manager — install plugins with
:PlugInstall - Start with few plugins and add more as needed
- Use
:set option?to check any setting's current value
Practice: Customize Your Vim
Try these configuration tasks:
- Open your vimrc:
vim ~/.vimrc - Add the leader key mapping:
let mapleader = " " - Add a mapping to save with Space+w:
nnoremap <leader>w :w<CR> - Add a mapping to clear search highlights:
nnoremap <leader>h :nohlsearch<CR> - Add window navigation shortcuts (the
Ctrl-h/j/k/lmappings from above) - Add the autocommand group to remove trailing whitespace on save
- Save and reload your vimrc:
:wthen:source %(the%means "current file") - Test your new mappings! Press Space+w to save, Space+h to clear highlights
- (Optional) Install vim-plug and add a color scheme plugin
Show Solution
" Add these to your ~/.vimrc:
" Step 2: Leader key
let mapleader = " "
" Step 3: Save shortcut
nnoremap <leader>w :w<CR>
" Step 4: Clear highlights
nnoremap <leader>h :nohlsearch<CR>
" Step 5: Window navigation
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
" Step 6: Trailing whitespace autocommand
augroup MySettings
autocmd!
autocmd BufWritePre * %s/\s\+$//e
augroup END
" After saving (:w), reload the config:
" :source %
" Step 8: Test!
" - Press Space then w → file should save (you'll see "written" message)
" - Search for something (/word), then press Space+h → highlights disappear
" - Open a split (:vsp), then use Ctrl-h and Ctrl-l to move between windows
" Step 9: Install vim-plug (run in terminal, then add plugins to vimrc)
" curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
" https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
"
" Then add to vimrc:
" call plug#begin('~/.vim/plugged')
" Plug 'morhetz/gruvbox'
" call plug#end()
" colorscheme gruvbox
"
" Save, reload (:source %), then run :PlugInstallWritten by the ShellRAG Team
The ShellRAG editorial team writes practical, beginner-friendly Vim tutorials with tested code examples and real-world use cases. Every article is technically reviewed for accuracy and updated regularly.
Learn more about us →