XDG Base Directory specification, $XDG_CONFIG_HOME
etc. Great thing - configs
separated from user data and cache, no clutter in home directory. Unfortunately,
many programs still don't respect it, including Vim. But what would be our favourite
text editor if we wouldn't be able to reconfigure it!
TL;DR #
Into environment/shell config (e.g. in ~/.profile
):
if [ -x "$(command -v vim)" ]; then
[ "$(vim --clean -es +'exec "!echo" has("patch-9.1.0327")' +q)" -eq 0 ] && \
export VIMINIT="set nocp | source ${XDG_CONFIG_HOME:-$HOME/.config}/vim/vimrc"
fi
At the top of vimrc:
" XDG Base Directory support
if empty($MYVIMRC) | let $MYVIMRC = expand('<sfile>:p') | endif
if empty($XDG_CACHE_HOME) | let $XDG_CACHE_HOME = $HOME."/.cache" | endif
if empty($XDG_CONFIG_HOME) | let $XDG_CONFIG_HOME = $HOME."/.config" | endif
if empty($XDG_DATA_HOME) | let $XDG_DATA_HOME = $HOME."/.local/share" | endif
if empty($XDG_STATE_HOME) | let $XDG_STATE_HOME = $HOME."/.local/state" | endif
if !has('nvim')
set runtimepath^=$XDG_CONFIG_HOME/vim
set runtimepath+=$XDG_DATA_HOME/vim
set runtimepath+=$XDG_CONFIG_HOME/vim/after
set packpath^=$XDG_DATA_HOME/vim,$XDG_CONFIG_HOME/vim
set packpath+=$XDG_CONFIG_HOME/vim/after,$XDG_DATA_HOME/vim/after
set backupdir=$XDG_STATE_HOME/vim/backup | call mkdir(&backupdir, 'p', 0700)
set directory=$XDG_STATE_HOME/vim/swap | call mkdir(&directory, 'p', 0700)
set viewdir=$XDG_STATE_HOME/vim/view | call mkdir(&viewdir, 'p', 0700)
set undodir=$XDG_STATE_HOME/vim/undo | call mkdir(&undodir, 'p', 0700)
set viminfofile=$XDG_STATE_HOME/vim/viminfo
endif
let g:netrw_home = $XDG_DATA_HOME."/vim"
call mkdir($XDG_DATA_HOME."/vim/spell", 'p', 0700)
call mkdir($XDG_STATE_HOME."/vim", 'p', 0700)
Step-by-step #
Relocating vimrc #
Since version 7.3.1178, Vim will search for ~/.vim/vimrc
if ~/.vimrc
is not found. So let's move the file there.
Let's move our ~/.vim
to $XDG_CONFIG_HOME/vim
. Now we need to command Vim
to read config from this new location prior to ~/.vim
.
If you have Vim 9.1.0327 or newer, you are in luck! From that version Vim
looks for $XDG_CONFIG_HOME/vim/vimrc
on its own, no further hacks required.
We can move on to configuring inside our vimrc.
Configuration in vimrc #
First of all, although not mandatory, let's set $MYVIMRC
variable:
if empty($MYVIMRC) | let $MYVIMRC = expand('<sfile>:p') | endif
Let's define fallback locations in case XDG_*
variables are not set.
if empty($XDG_CACHE_HOME) | let $XDG_CACHE_HOME = $HOME."/.cache" | endif
if empty($XDG_CONFIG_HOME) | let $XDG_CONFIG_HOME = $HOME."/.config" | endif
if empty($XDG_DATA_HOME) | let $XDG_DATA_HOME = $HOME."/.local/share" | endif
if empty($XDG_STATE_HOME) | let $XDG_STATE_HOME = $HOME."/.local/state" | endif
Let's add entries to runtimepath
:
set runtimepath^=$XDG_CONFIG_HOME/vim
set runtimepath+=$XDG_DATA_HOME/vim
set runtimepath+=$XDG_CONFIG_HOME/vim/after
$XDG_CONFIG_HOME/vim
and $XDG_CONFIG_HOME/vim/after
are just equivalents of
~/.vim
and ~/.vim/after
, but $XDG_DATA_HOME/vim
is brand new - there we
will keep downloadables (like plugins and spell files), Netrw bookmarks etc.
Let's set directory for Vim8 build-in packages:
set packpath^=$XDG_DATA_HOME/vim
set packpath+=$XDG_DATA_HOME/vim/after
Netrw is just as easy:
let g:netrw_home = $XDG_DATA_HOME."/vim"
What about spellings? Well, this one is more tricky, because it isn't controlled
by any option. Instead it searches for spell
directory in whole runtime path.
If none is found then it falls back to ~/.vim/spell
. So let's create one at
desired location ourselves!
call mkdir($XDG_DATA_HOME."/vim/spell", 'p', 0700)
So far so good. We are left with state (backup, undo, swap, viminfo, view).
Vim doesn't create directories for them (even for defaults), so we will need
to do it ourselves - luckily VimL offers mkdir()
function:
set backupdir=$XDG_STATE_HOME/vim/backup | call mkdir(&backupdir, 'p', 0700)
set directory=$XDG_STATE_HOME/vim/swap | call mkdir(&directory, 'p', 0700)
set undodir=$XDG_STATE_HOME/vim/undo | call mkdir(&undodir, 'p', 0700)
set viewdir=$XDG_STATE_HOME/vim/view | call mkdir(&viewdir, 'p', 0700)
if !has('nvim') " Neovim has its own location which already complies with XDG specification
set viminfofile=$XDG_STATE_HOME/vim/viminfo
endif
Congratulations!
Now your Vim is configured with accordance to XDG Base Directory specification.