VimのCTRL-X補完について
この記事はVim Advent Calendar 2015の5日目の記事です。
Vimで補完といえばShougo
さんのプラグインneocomplete
が有名ですが、プラグインを使わなくてもCTRL-X サブモード
で補完を行うことが可能です。
この機能はブログや書籍などでたびたび紹介されてはいますが、文字だけではイメージがつきにくいところもあるのでGIFアニメで紹介してみたいと思います。
行(全体)補完: CTRL-X CTRL-L
if から始まる行と l から始まる行を補完(go)
検索対象はcomplete
オプションで設定可能
局所キーワード補完: CTRL-X CTRL-N / CTRL-X CTRL-P
現在のファイルから T で始まるキーワードを補完(perl)
辞書補完: CTRL-X CTRL-K
dictionary
オプションで設定したファイルから twist で始まる単語を補完
dictionary
オプションに使用するファイルを設定する必要がある(デフォルトは未設定)
set dictionary=/usr/share/dict/words
シソーラス補完: CTRL-X CTRL-T
thesaurus
オプションで設定したファイルから twister の類語を補完
thesaurus
オプションに使用するファイルを設定する必要がある(デフォルトは未設定)
set thesaurus=/usr/share/mythes/th_en_US_v2.dat
パスパターン補完: CTRL-X CTRL-I
インクルードしているSocket.pmから getpr で始まるキーワードを補完(perl)
検索対象はinclude
オプションとpath
オプションで設定可能
タグ補完: CTRL-X CTRL-]
読み込むtagsファイルはtags
オプションで設定可能
ファイル名補完: CTRL-X CTRL-F
/etc/y から始まるファイル名を補完
定義補完: CTRL-X CTRL-D
mixinを補完(sass)
検索対象はdefine
オプションとinclude
オプションとpath
オプションで設定可能
コマンドライン補完: CTRL-X CTRL-V
vimのコマンドと関数を補完
ユーザー定義補完: CTRL-X CTRL-U
completefunc
オプションに設定したCompleteMonthsで月の名前を補完
fun! CompleteMonths(findstart, base) if a:findstart " 単語の始点を検索する let line = getline('.') let start = col('.') - 1 while start > 0 && line[start - 1] =~ '\a' let start -= 1 endwhile return start else " "a:base" にマッチする月を探す let res = [] for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec") if m =~ '^' . a:base call add(res, m) endif endfor return res endif endfun
オムニ補完: CTRL-X CTRL-O
omnifunc
オプションに設定されたjavascriptcomplete#CompleteJSでDate型のメソッドを補完(javascript)
スペリング補完: CTRL-X s / CTRL-X CTRL-S
頭文字が大文字になっていない単語と綴りが間違っている単語の修正候補を補完
spell
オプションをオンにする必要がある
上記環境はDocker上のcentos6に以下のパッケージをインストールしたものです。
プラグインは一切インストールしておらず、vimrcも作成していません。
yum install vim-enhanced ctags words mythes-en
CTRL-X サブモード について
順序が逆転してしまいましたが、CTRL-X サブモード
は挿入モード
または置換モード
中にCTRL-X
キーで入ることができます。
ポップアップメニューの補完候補はCTRL-N
(次の候補)またはCTRL-P
(前の候補)キーで選択し、CTRL-Y
キーやスペース、エンターなどで挿入することができます。
また、CTRL-E
キーで補完を中止して元のテキストに戻すことができます。
最近neocomplete
が入っていないVimを触ることがちょこちょことあり、ここ1週間くらいはメインのVimでもneocomplete
を使わずに過ごしてみました。
昔は自動補完プラグインが無いとコーディングなんてできない...とか思っていましたがそこまで困らないくらいには成長していたようです。
ただ、CTRL-X
キーがイマイチ押しにくいと感じているのでこれさえなんとかなれば自動補完プラグインは使わなくなるかもしれません。
今はこんなマッピングを試してみています。
inoremap <expr><Tab> pumvisible() ? "\<C-n>" : MyInsCompl() function! MyInsCompl() let c = nr2char(getchar()) if c == "l" return "\<C-x>\<C-l>" elseif c == "n" return "\<C-x>\<C-n>" elseif c == "p" return "\<C-x>\<C-p>" elseif c == "k" return "\<C-x>\<C-k>" elseif c == "t" return "\<C-x>\<C-t>" elseif c == "i" return "\<C-x>\<C-i>" elseif c == "]" return "\<C-x>\<C-]>" elseif c == "f" return "\<C-x>\<C-f>" elseif c == "d" return "\<C-x>\<C-d>" elseif c == "v" return "\<C-x>\<C-v>" elseif c == "u" return "\<C-x>\<C-u>" elseif c == "o" return "\<C-x>\<C-o>" elseif c == "s" return "\<C-x>s" endif return "\<Tab>" endfunction