vimrc の分割管理を上手くやる 2020年版
筆者の環境について
Vim にはプラグインマネージャも沢山あります。その中で僕は vim-plug を使っています。Software Design という雑誌で「Vim の細道」という連載をやっている事もあり、皆さんに一番リーチしやすいプラグインマネージャを選んでいるという事もありますが、基本は「トラブルが発生しづらい」という理由で使っているのもあります。
vimrc の分割管理
ところで最近は Vim プラグインが沢山あり、個々に設定が必要な場合もあります。全て vimrc の中に書いてしまうのも良いのですが、そうするとどこからどこまでが、どのプラグインの設定か分からないといった問題が起きてしまいます。僕は vimrc をプラグイン毎に分割して管理しています。
Big Sky :: ぼくがかんがえたさいきょうの Vim のこうせい 2019年 年末版
" Vim 本体の機能のデフォルト値を経項する設定
setglobal cmdheight=2
setglobal laststatus=2
... 略 ...
setglobal fileformat=unix
setglobal formatoptions+=mb
if !has('win32') && !has('win64')
setglobal shell=/bin/bash
endif
if exists('&termguicolors')
setglobal termguicolors
endif
if exists('&completeslash')
setglobal completeslash=slash
endif
let g:no_gvimrc_example=1
let g:no_vimrc_example=1
let g:loaded_gzip = 1
let g:loaded_tar = 1
let g:loaded_tarPlugin = 1
let g:loaded_zip = 1
let g:loaded_zipPlugin = 1
let g:loaded_rrhelper = 1
let g:loaded_vimball = 1
let g:loaded_vimballPlugin = 1
let g:loaded_getscript = 1
let g:loaded_getscriptPlugin = 1
let g:loaded_netrw = 1
let g:loaded_netrwPlugin = 1
let g:loaded_netrwSettings = 1
let g:loaded_netrwFileHandlers = 1
let g:did_install_default_menus = 1
let g:skip_loading_mswin = 1
let g:did_install_syntax_menu = 1
"let g:loaded_2html_plugin = 1
let g:mapleader = '\'
let g:maplocalleader = ','
" git commit 時にはプラグインは読み込まない
if $HOME != $USERPROFILE && $GIT_EXEC_PATH != ''
finish
end
" Windows の場合は必要なパスを追加しておく
if has('win32')
let $PATH='c:\dev\vim;c:\msys64\mingw64\bin;c:\msys64\usr\bin;'
\ .'c:\Program Files\Java\jdk1.8.0_221\bin;'.$PATH
endif
" プラグインの読み込み
let g:plug_shallow = 0
call plug#begin('~/.vim/plugged')
Plug 'thinca/vim-ambicmd'
Plug 'thinca/vim-openbuf'
Plug 'thinca/vim-quickrun'
... 略 ...
call plug#end()
" 各種設定の読み込み
call map(sort(split(globpath(&runtimepath, '_config/*.vim'))), {->[execute('exec "so" v:val')]})
また個々の設定ファイルはプラグイン名を付けて管理しています。
000-mappings.vim
001-filetype.vim
002-commands.vim
003-path.vim
102-autofmt.vim
104-conda.vim
105-ctrlp.vim
106-emmet.vim
107-lightline.vim
200-lsp.vim
201-languageclient-nvim.vim
202-vsnip.vim
204-quickrun.vim
300-vim.vim
301-java.vim
400-memolist.vim
401-openbrowser.vim
402-previm.vim
403-termdebug.vim
404-tohtml.vim
405-twitvim.vim
おおよそこれで問題なく動いていて、各 _config
配下のファイルではプラグインの有効無効を確認する為に
if empty(globpath(&rtp, 'autoload/lsp.vim'))
finish
endif
こういうコードを先頭に書いています。こうする事で vimrc の Plug
をコメントアウトすれば自動で設定も読み込まない様にしていたのです。しかしこの globpath
という関数はランタイムパス上のファイルを探索する機能である為、幾分遅いという問題が当初から気になっていました。なんとかしないとなぁと感じていました。
vim-plug の機能を使う
なるべく vim-plug
に依存しない様にとこの形にしていたのですが、さすがに起動速度が気になってきたので管理方法を変更する事にしました。
" 各種設定の読み込み
call map(sort(split(globpath(&runtimepath, '_config/*.vim'))), {->[execute('exec "so" v:val')]})
まずこの部分を以下の様に変えました。
let s:plugs = get(s:, 'plugs', get(g:, 'plugs', {}))
function! FindPlugin(name) abort
return has_key(s:plugs, a:name) ? isdirectory(s:plugs[a:name].dir) : 0
endfunction
command! -nargs=1 UsePlugin if !FindPlugin(<args>) | finish | endif
runtime! _config/*.vim
vim-plug
はグローバル変数 g:plugs
に読み込んだプラグイン情報を管理しています。これを使えば globpath
でファイルの存在を確認する必要が無くなります。個々の設定ファイルでは先頭に UsePlugin
コマンド使って以下の様に書きます。
UsePlugin 'ctrlp.vim'
こうすると、もし Plug 'ctrlvim/ctrlp.vim'
をコメントアウトした場合にはそれ以降は読み込まれません。前述の通り globpath
はファイルを探索するので遅かったですが、この方法だとメモリ内の検索だけになり、起動速度も速くなります。僕の環境(Linux)では Vim の起動が500ミリ秒程度掛かっていたのですが、これにより200ミリ秒程度までに抑えられる様になりました。
僕の様に分割ファイルを使っていて globpath
でプラグインの有効無効を確認している方には、この方法を試してみて欲しいです。
Discussion