The .vimrc File#
Vim reads its configuration from ~/.vimrc on startup. Every setting you apply with :set during a session can be made permanent by adding it to this file.
vim ~/.vimrcLines starting with " are comments. Settings take effect immediately when you source the file:
:source ~/.vimrcEssential Settings#
Display#
" Show line numbers
set number
" Show relative line numbers (useful for counts like 5j, 12dd)
set relativenumber
" Highlight the current line
set cursorline
" Show matching brackets when cursor is on one
set showmatch
" Always show the status line
set laststatus=2
" Show command as you type it
set showcmd
" Show current mode in the status line
set showmodeSearch#
" Highlight search results
set hlsearch
" Search as you type (incremental)
set incsearch
" Case-insensitive search...
set ignorecase
" ...unless the query contains uppercase letters
set smartcaseIndentation#
" Use spaces instead of tabs
set expandtab
" Number of spaces per tab
set tabstop=4
" Number of spaces for auto-indent
set shiftwidth=4
" Insert/delete this many spaces with Tab/Backspace
set softtabstop=4
" Auto-indent new lines based on previous line
set autoindent
" Smart indent for C-like languages
set smartindentBehavior#
" Allow hidden buffers (switch without saving)
set hidden
" Don't create backup files
set nobackup
set nowritebackup
" Don't create swap files
set noswapfile
" Use system clipboard
set clipboard=unnamedplus
" Enable mouse support (useful for scrolling and resizing splits)
set mouse=a
" Faster updates (for plugins and git gutter)
set updatetime=300
" More natural split directions
set splitbelow
set splitright
" Don't wrap long lines
set nowrap
" Scroll before reaching the edge
set scrolloff=8
" Command-line completion menu
set wildmenu
set wildmode=longest:list,fullKey Mappings#
Mappings let you assign custom behavior to keys.
Mapping commands#
| Command | Mode |
|---|---|
nnoremap | Normal mode |
inoremap | Insert mode |
vnoremap | Visual mode |
cnoremap | Command-line mode |
Always use the noremap variants — they prevent recursive mappings.
The leader key#
The leader key is a prefix for custom shortcuts. It’s \ by default, but most people remap it to space:
let mapleader = " "Now you can create mappings like:
" Leader+w saves the file
nnoremap <leader>w :w<CR>
" Leader+q closes the window
nnoremap <leader>q :q<CR>Practical mappings#
" Clear search highlight with Esc
nnoremap <Esc> :nohlsearch<CR>
" Move between splits with 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 up and down in visual mode
vnoremap J :m '>+1<CR>gv=gv
vnoremap K :m '<-2<CR>gv=gv
" Keep visual selection when indenting
vnoremap < <gv
vnoremap > >gv
" Y yanks to end of line (consistent with D and C)
nnoremap Y y$
" Keep cursor centered when scrolling
nnoremap <C-d> <C-d>zz
nnoremap <C-u> <C-u>zz
" Keep cursor centered when searching
nnoremap n nzzzv
nnoremap N NzzzvAutocommands#
Autocommands run actions in response to events:
" 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
" Set file-specific indentation
autocmd FileType python setlocal tabstop=4 shiftwidth=4
autocmd FileType javascript setlocal tabstop=2 shiftwidth=2
autocmd FileType yaml setlocal tabstop=2 shiftwidth=2A Starter .vimrc#
Here’s a complete, well-commented starter configuration:
" ============================================================
" General
" ============================================================
set nocompatible " Disable vi compatibility
set encoding=utf-8 " UTF-8 encoding
set hidden " Allow hidden buffers
set nobackup " No backup files
set nowritebackup
set noswapfile " No swap files
set updatetime=300 " Faster updates
set mouse=a " Enable mouse
" ============================================================
" Display
" ============================================================
set number " Line numbers
set relativenumber " Relative line numbers
set cursorline " Highlight current line
set showmatch " Show matching brackets
set laststatus=2 " Always show status line
set showcmd " Show partial commands
set scrolloff=8 " Keep 8 lines visible above/below cursor
set signcolumn=yes " Always show sign column
set colorcolumn=80 " Mark column 80
syntax enable " Syntax highlighting
" ============================================================
" Search
" ============================================================
set hlsearch " Highlight matches
set incsearch " Incremental search
set ignorecase " Case-insensitive...
set smartcase " ...unless uppercase is used
" ============================================================
" Indentation
" ============================================================
set expandtab " Spaces, not tabs
set tabstop=4 " Tab width
set shiftwidth=4 " Indent width
set softtabstop=4 " Backspace through spaces
set autoindent " Copy indent from current line
set smartindent " Smart auto-indent
filetype plugin indent on " File-type specific indentation
" ============================================================
" Splits
" ============================================================
set splitbelow " Horizontal splits below
set splitright " Vertical splits to the right
" ============================================================
" Completion
" ============================================================
set wildmenu " Command-line completion
set wildmode=longest:list,full
" ============================================================
" Leader
" ============================================================
let mapleader = " "
" ============================================================
" Key Mappings
" ============================================================
" Save and quit
nnoremap <leader>w :w<CR>
nnoremap <leader>q :q<CR>
" Clear search highlight
nnoremap <Esc> :nohlsearch<CR>
" Split 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>bn :bn<CR>
nnoremap <leader>bp :bp<CR>
nnoremap <leader>bd :bd<CR>
" Keep visual selection when indenting
vnoremap < <gv
vnoremap > >gv
" Move lines in visual mode
vnoremap J :m '>+1<CR>gv=gv
vnoremap K :m '<-2<CR>gv=gv
" Y yanks to end of line
nnoremap Y y$
" Centered scrolling
nnoremap <C-d> <C-d>zz
nnoremap <C-u> <C-u>zz
nnoremap n nzzzv
nnoremap N Nzzzv
" ============================================================
" Autocommands
" ============================================================
" Remove trailing whitespace on save
autocmd BufWritePre * %s/\s\+$//e
" Return to last edit position
autocmd BufReadPost *
\ if line("'\"") > 0 && line("'\"") <= line("$") |
\ exe "normal! g`\"" |
\ endifNeovim Note#
If you use Neovim, configuration lives at ~/.config/nvim/init.vim (Vimscript) or ~/.config/nvim/init.lua (Lua). Most Vim settings work identically in Neovim. The Lua configuration path is the modern approach for Neovim-specific features and plugins.
Best Practices#
- Start with a minimal .vimrc and add settings as you understand what they do — don’t copy a 500-line config you can’t debug
- Use
noremap(non-recursive) for all custom mappings to prevent unexpected behavior - Set
mapleaderto space — it’s the easiest key to reach and doesn’t conflict with built-in commands - Use
set hiddenso you can switch buffers without being forced to save first - Enable relative line numbers — they make count-based motions (
5j,12dd) effortless - Keep your .vimrc organized with sections and comments — you’ll forget why you added something in six months

