おかゆ++

IT業界の片隅で生き残るブログ

vimrcをファイル分割する&VimとNeoVimで共通化する

vimrc分割の理由

Vimを使っていれば、プラグインを追加したり、設定を変えたり等々でvimrcは長くなっていく一方です。 ということで、読みやすさと拡張性を確保するためにも当然分割したいわけです。

分割ついでに、VimとNeoVimの両方で同じvimrcを使うようにしたい。vimrcの中身が同じって意味ではなくて、同じvimrcファイルをVimとNeoVimの両方で参照するってことです。

分割の仕組みというか、sourceについて

Vimのコマンドに source というのがあります。まんま指定したVim scriptファイルを読み込むコマンドです。これを使えば複数ファイルに分割できそうですね。実際には source をラップした関数を作るのがいいんじゃないでしょうか。

今回のディレクトリ構成

以下の方針でディレクトリを分けます。

  • 全ての設定ファイルは ~/.dotfiles/vim に配置して、所定の位置にはシンボリックリンクを張る。
  • プラグイン管理には dein を使う
  • Vim で dein を使った時のファイル類や、その他のファイルは ~/.vim に配置する。
  • NeoVim で dein を使った時のファイル類、その他のファイルは ~/.nvim に配置する。
  • 設定ファイル類は *.rc.vim という名前にする。

ということで、こんな感じ。

~/
├─.vim
│  ├─dein    deinがダウンロードしたリポジトリとかが入る
│  └─rc      ~/dotfiles/vim/rc へのシンボリックリンク
├─.nvim
│  ├─dein    deinがダウンロードしたリポジトリとかが入る
│  └─rc      ~/dotfiles/vim/rc へのシンボリックリンク
└─dotfiles
    └─vim
        └─rc  色々な設定ファイル類が入る。vimrcからsourceで読み込む。

VimとNeoVimの判定

vimrcの先頭でVimとNeoVimの判定を実施して、ディレクトリパスなどをグローバル変数に入れておきます。以後はこの変数を使うようにします。

NeoVimの場合は has('nvim') がTrueになるので、これを使います。

if has('nvim')
    let g:vim_home = expand('~/.nvim')
    let g:rc_dir = expand('~/.nvim/rc')
else
    let g:vim_home = expand('~/.vim')
    let g:rc_dir = expand('~/.vim/rc')
endif

読み込み用の関数

基本的には rcディレクトリからのみ読み込むようにするので、それ用に関数を作ります。 また、VimとNeoVimではディレクトリが違うので、そのあたりもさっきのグローバル変数で吸収します。

" rcファイル読み込み関数
function! s:source_rc(rc_file_name)
    let rc_file = expand(g:rc_dir . '/' . a:rc_file_name)
    if filereadable(rc_file)
        execute 'source' rc_file
    endif
endfunction

call s:source_rc('init.rc.vim') のような感じで書けば、dotfiles/vim/rc/init.rc.vim が読み込まれます。

最終的なvimrc

最終的には以下のようになりました。

if has('nvim')
    let g:vim_home = expand('~/.nvim')
    let g:rc_dir = expand('~/.nvim/rc')
else
    let g:vim_home = expand('~/.vim')
    let g:rc_dir = expand('~/.vim/rc')
endif

" rcファイル読み込み関数
function! s:source_rc(rc_file_name)
    let rc_file = expand(g:rc_dir . '/' . a:rc_file_name)
    if filereadable(rc_file)
        execute 'source' rc_file
    endif
endfunction

"------------------------------------------------------------------------------

" 基本設定
call s:source_rc('init.rc.vim')

" エディタの設定
call s:source_rc('editor.rc.vim')

" Dein.vim
call s:source_rc('dein.rc.vim')

" カラースキーマ
call s:source_rc('color.rc.vim')

" ターミナル設定(今の所NeoVimの :terminal の設定)
call s:source_rc('terminal.rc.vim')

" neocomplete
call s:source_rc('neocomplete.rc.vim')

" unite
call s:source_rc('unite.rc.vim')

" caw.vim
call s:source_rc('caw.rc.vim')

" NERDTree
call s:source_rc('nerdtree.rc.vim')

" lightline.vim
call s:source_rc('lightline.rc.vim')

ちょっと設定ファイルを分けすぎた感もあるけど、まぁ許容範囲かなーということで。

インストール用のスクリプトも作っておく

install.sh とか install.bat とかを作っておけば、git clone して sh install.sh すれば環境が整うはず。

Unix用のinstall.shはこんな感じ。

#!/bin/sh
cd $(dirname ${0}) 

vim_home=~/.vim
mkdir -p ${vim_home}
ln -sf `pwd`/vim/vimrc ~/.vimrc
ln -sf `pwd`/vim/rc ${vim_home}/rc

nvim_home=~/.nvim
mkdir -p ${nvim_home}
mkdir -p ~/.config/nvim
ln -sf `pwd`/vim/vimrc ~/.config/nvim/init.vim
ln -sf `pwd`/vim/rc ${nvim_home}/rc

Windows場合、シンボリックリンクの作成に管理者権限で実行する必要があることだけ注意が必要です。 また、vimrcの置き場所とかも色々*1だと思いますので、以下はあくまでも例です。

@echo off
@setlocal
cd %~dp0
set current=%~dp0

set vim_home=%HOME%\.vim
mkdir %vim_home%
mklink "%HOME%\.vimrc" "%current%vim\vimrc"
mklink "%HOME%\.gvimrc" "%current%vim\gvimrc"
mklink /D "%vim_home%\rc" "%current%vim\rc"

set nvim_initdir=%userprofile%\AppData\Local\nvim
mkdir "%nvim_initdir%"
mklink %nvim_initdir%"\init.vim" "%current%vim\vimrc"

@endlocal
@echo on

*1:自分は環境変数HOMEを用意して、vimrcなんかもそこに置いてます。