A Minimal Vimrc
Parts of a “minimal” vimrc
What makes a minimal vimrc?
My opinion of a “minimal” vimrc might be different from yours, but for me, it means
- Not using external plugins
- < ~100 lines
- Reducing vi related pain-points
So here’s what I do:
Source default settings
While this may not be necessary most of the time, it is still worth it to check that it has been sourced IME. It is a small fine to pay for ensuring you have the defaults you deserve.
if filereadable(expand('$VIMRUNTIME/defaults.vim'))
unlet! g:skip_defaults_vim
source $VIMRUNTIME/defaults.vim
endif
And we’re done…
jkjk there’s more
Settings
Most of these will already be set in defaults.vim
, but that’s not really a concern
of mine – I still want to talk about them :)
“UI” Settings
set number "show line numbers
set wildmenu "enable a menu that shows tab completion options in the status bar
set showmatch "highlights matching brackets on cursor hover
set ruler "show cursor position in status bar
set showcmd "shows the normal mode command before it gets executed
Gotta have those line numbers, and I use wildmenu
all the time. The rest are just
nice-to-haves.
File Format and Encoding
set encoding=utf-8
set fileformats=unix,dos,mac
Lots of stuff is UTF-8 encoded these days (web pages, emojis, code, etc.) this is the reasoning behind utf-8.
Setting fileformats
instead of fileformat
allows more than one EOL type to
be detected. For example: Windows uses both <CR><NL>
to mark the end of a line
while Unix uses only one.
This is one reason you may see ^M
symbols at the end of each line.
See h:fileformats
for more info.
Searching
set hlsearch "highlights searches
set incsearch "incremental search (searches character by character)
set ignorecase "ignores the case of a search
set smartcase "only ignores case if there are no capital letters in search (only works after ignorecase has been set)
While this is the search behavior that I like personally, I know that
many people prefer case sensitive search by default. I find incsearch
jumps
around a bunch, which can be a bit disorienting, but I like the instant feedback.
Indents
set tabstop=4 "the amount of spaces that vim will equate to a tab character
set softtabstop=4 "like tabstop, but for editing operations (insert mode)
set shiftwidth=4 "used for autoindent and << and >> operators in normal mode
set autoindent "copies indent from current line to the next line
set expandtab "tabs will expand to whitespace characters
These indent settings can be confusing, but they apply in increasingly specific ways.
Here is my understanding of it:
tabstop
is your base level for what vim will think constitutes as a literal
\t
“tab character”.
It is 8 by default, but I set it to 4 because 4 is between 2 and 8 :D.
softtabstop
only matters when editing (insert mode).
shiftwidth
only applies when doing specific editing operators (» and «).
So if I set softtabstop=2
and tabstop=4
, I would have to hit the <Tab> key twice
to get an actual \t
(tab character). And if I set softtabstop=8
while
tabstop=4
, I would get 2 tab characters when I press tab.
Then expandtab
makes the <Tab>
key insert spaces instead of tab characters.
You’ll find this is necessary for languages like Python (thankfully these settings
are handled correctly in the default Python ftplugin under $VIMRUNTIME/ftplugin/python.vim
)
autoindent
and smarttab
use the values from softtabstop
and shiftwidth
to make indenting decisions too so watch out for that.
Tip: if you have any doubts about whether some space in a file consists of Tab
or a Space characters, use :set list
to see ^I
for tab characters
Use :set list!
to toggle.
Key Timeouts
set esckeys "allows function keys to be recognized in Insert mode
set ttimeoutlen=20 "timeout for a key code mapping
set timeoutlen=1000 "time(ms) to wait for key mappings
These adjust the ‘wait times’ for different commands. These settings are
necessary to get rid of delay when running vim
inside of tmux
.
Syntax, Filetype and Matchit
syntax enable "turn syntax highlighting on
filetype plugin indent on "load plugin and indent files associated a detected filetype
runtime macros/matchit.vim "allows jumping between brackets with % in normal mode
These are probably the settings the give the most “bang for buck” when it comes to vanilla vim.
Syntax highlighting, filetype/language specific settings and plugins are great, but they are a bit outside of the scope a truly minimal vimrc.
Once you start diving into the specifics of a language or ecosystem, you will likely have an easier time using external tools provided to do the “heavy lifting” and integrate with vim via plugin(s).
If you want to learn more about filetypes and plugins, see :h filetypes
.
Autocommands
augroup general
autocmd!
"keep equal proportions when windows resized
autocmd VimResized * wincmd =
"save cursor position in a file
autocmd BufReadPost * if line("'\"") > 1 && line("'\"")
\ <= line("$") | exe "normal! g'\"" | endif
augroup END
augroup languages
autocmd!
autocmd BufNewFile,BufRead *.bash set syntax=sh
autocmd FileType python xnoremap <leader>r <esc>:'<,'>:w !python3<CR>
autocmd FileType go set noexpandtab
autocmd FileType html :syntax sync fromstart
autocmd FileType html,javascript,css,json,yaml,sh
\ setlocal ts=2 sts=2 sw=2 expandtab
augroup END
I have a few autocommands at the end here just in case I want to add specific commands or mappings.
Autocommands are kind-of like ’events’ that get fired when stuff happens inside of Vim. They are an easy way set settings for filetypes or events.
For example, the following settings will only be applied to bash and go files respectively.
autocmd BufNewFile,BufRead *.bash set syntax=sh
autocmd FileType go set noexpandtab
And that’s all. 65 lines isn’t too bad. I could probably axe a few settings and some autocmds, but this is fine with me for now.
The full file
"
" minimal vimrc with no (extra) plugins
"
"load system defaults
if filereadable(expand('$VIMRUNTIME/defaults.vim'))
unlet! g:skip_defaults_vim
source $VIMRUNTIME/defaults.vim
endif
"regular settings
"----------------
" ui
set number
set ruler
set wildmenu
set showcmd
set showmatch
" encoding/format
set encoding=utf-8
set fileformats=unix,dos,mac
" searching
set hlsearch
set incsearch
set ignorecase
set smartcase
" indent
set shiftwidth=4
set tabstop=4
set softtabstop=4
set autoindent
" key timeout values
set esckeys
set ttimeoutlen=20
set timeoutlen=1000
" allow syntax and filetype plugins
syntax enable
filetype plugin indent on
runtime macros/matchit.vim
" autocmds
"---------
augroup general
autocmd!
"keep equal proportions when windows resized
autocmd VimResized * wincmd =
"save cursor position in a file
autocmd BufReadPost * if line("'\"") > 1 && line("'\"")
\ <= line("$") | exe "normal! g'\"" | endif
augroup END
augroup languages
autocmd!
autocmd BufNewFile,BufRead *.bash set syntax=sh
autocmd FileType python xnoremap <leader>r <esc>:'<,'>:w !python3<CR>
autocmd FileType go set noexpandtab
autocmd FileType html :syntax sync fromstart
autocmd FileType html,javascript,css,json,yaml,sh
\ setlocal ts=2 sts=2 sw=2 expandtab
augroup END