はじめに
以下の記事では、僕の Vim の構成について記述しています。本来はこの記事で vim-lsp の導入方法と私的 Go 編集環境について書こうと思っていましたが、あまりにも長くなってしまったので別途書く事にしました。僕は Windows と Linux しか使わないので、皆さんの環境で使うとうまく動かない可能性があります。また僕は最新の Vim 8 しか使いません。古めの Vim を使いません。neovim も使いません。それらをお使いの方はうまく動かない可能性があります。ご了承下さい。なお設定ファイルの配置スタイルは完全に僕個人の趣味ですので必ずしも僕の構成が正しい訳ではありません。
ぼくのかんがえたさいきょうの Vim こうせい
Vim の設定は vimrc に記述するのですが、その設定方法には「汚くさせない」ための工夫が必要だと思っています。以下は僕が行っている「vimrc を綺麗に保つ方法」です。
vimrc に記述する内容は大きく分けて以下の物があります。
- Vim 本体の機能のデフォルト値を変更する設定
- プラグインの読み込み
- ユーザ固有のマッピングやコマンドの定義
- プラグイン固有の設定
vimfiles
├─vimrc
├─gvimrc
├─autoload/
├─plugged/
└─_config/
autoload には後で述べる vim-plug の plug.vim しか入っていません。上記のリストの内、1と2は vimrc および gvimrc に記述しています。残りは全て _config というフォルダ内に、各機能毎に分けて記述しています。以下は僕の vimrc の概要です。
" 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')]})
これを $HOME/.vim
、Windows であれば %USERPROFILE%\vimfiles
の中に vimrc というファイル名で置いています。便宜上、vimfiles
を Windows のシンボリックリンクを使って .vim
にリンクさせています。
気を付けるべきはこの状態を常に保つ事です。これは vimrc だけでなく .emacs.el
等にも言える事ですが、「ちょっと今だけ」と vimrc に手を加えた設定は、おそらく数か月後もそのままになってしまう可能性があるからです。綺麗な vimrc を保ち続けたいのであれば、この形は崩さない事です。
またなぜ僕がこの形にしているかというと、機能単位またはプラグイン単位で設定ファイルを消せるからです。必要なくなったプラグインの設定が vimrc に残ったままだと、どんどん汚くなってしまいます。必要に応じて消していくのも、vimrc を綺麗に保つ秘訣です。これは僕が2015年から SoftwareDesign の連載「Vim の細道」を書く上で毎月 vimrc を継ぎ足ししているうちに、どうしても vimrc が汚くなってしまった問題を解決する為に行き着いた方法です。
Vim 本体の機能のデフォルト値を変更する設定
ここで僕が言える事は「これらの設定をばらまかない事」。これらの設定は今後どんな新しいプラグインが出てきたとしても変わらない設定であるはずです。
プラグインの読み込み
僕は vim-plug というプラグインマネージャを使っています。他のプラグインマネージャを使っている方もいると思います。ちなみに僕も vim-plug に満足している訳ではなく、現在は minpac に移行しようか検討中です。
ユーザ固有のマッピングやコマンド定義
これ以降は、ユーザ固有のマッピングやコマンド定義、プラグイン固有の設定、の2つとなりますが、これらは個別の設定ファイルに書いています。例えば僕は_config
ディレクトリの下に以下の様に配置しています。
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
おおよそ番号体系があって、000番台が Vim 本体に関する物、100番台が全体に関わるプラグインの設定、200番台以降がプラグインの設定ですがその中でもグローバルに適用される物、300番台がファイルタイプに関連する物、400番台がアプリケーションに関する物、となっています。この番号体系は完全に守れている訳ではないです。
ユーザ固有のコマンド定義では、コマンドの実行可否を利用するのが良いと思います。例えば外部コマンド foo が存在しない場合にユーザ定義コマンドを定義したくない場合には以下の様にファイルの先頭に書きます。
if !executable('foo')
finish
endif
プラグイン固有の設定
上記のリストで、番号が飛んでいるのに気付いたかもしれません。以前は使っていたけれど不要になったので消した為です。これにより、プラグインを足したり消したりする際にゴミが残ってしまう問題を解決しました。
これらの設定で注意する事は、プラグインの有無をチェックする事です。プラグインをチェックする為には、globpath
関数を使ってスクリプトの存在を確認する方法を使います。
例えば vim-lsp
の設定ファイル 200-lsp.vim
の先頭には以下の様に書いています。
if empty(globpath(&rtp, 'autoload/lsp.vim'))
finish
endif
こうする事で、vimrc の Plug
行をコメントアウトしても正常に Vim が起動できる様になります。例えば何かの拍子に環境が変わり、プラグインが正常に動作しなくなった場合には、そのプラグインを読み込みを停止してしまえば合わせて設定も無効になってくれる、という仕組みです。