ruby_hl_lvar.vim とは
todesking/ruby_hl_lvar.vim · GitHub
ruby のローカル変数をハイライトするプラグインです。 たいぽの発見に割と便利だと思います。
詳しくは、
Rubyのローカル変数をシンタクスハイライトするVimプラグインを書いた - TODESKING
を読むと良いと思います。
Shougo ware とは
Shougo ware とは、その名の通り暗黒美夢王ことShougo氏が作成したVimプラグイン郡です。 代表的なものは、以下のようなものがあります。
- Shougo/neobundle.vim · GitHub
- Shougo/neocomplete.vim · GitHub
- Shougo/unite.vim · GitHub
- Shougo/neosnippet.vim · GitHub
- Shougo/vimfiler.vim · GitHub
- Shougo/vimshell.vim · GitHub
- etc...
今回は、この中のNeoBundleとNeoSnippetについて取り上げます。
NeoBundle
NeoBundleとは、vimのプラグイン管理プラグインです。
また、その中にはプラグインの遅延読み込みを実現するNeoBundleLazy
というコマンドがあります。
NeoBundleLazy に関しては、こちらが詳しいでしょう。
neobundle.vim の遅延処理で Vim の起動を高速化する - C++でゲームプログラミング
さて、ruby_hl_lvar.vim はRubyの時にだけ使用したいプラグインですね。 NeoBundle にはそのようなプラグインのために、「特定のFileTypeの時にプラグインを読み込む」機能があります。
NeoBundleLazy 'todesking/ruby_hl_lvar.vim', { \ 'autoload': { \ 'filetypes': ['ruby'] \ } \ }
このように書いてやると、Rubyの時にだけプラグインが読み込まれます。
しかし、ruby_hl_lvar の場合これだけだと若干問題が発生します。 最初に開いたバッファにおいて、ruby_hl_lvar が有効になりません。
なぜかと言うと、NeoBundleLazy
でFileTypeを指定した場合はautocmd
のFileType
イベントが呼ばれないからのようです。
FileTypeイベントは ここで呼ばれています。
augroup ruby_hl_lvar autocmd! autocmd! Filetype * call Ruby_hl_lvar_filetype() augroup END
ここで呼んでいる関数Ruby_hl_lvar_filetype()
で初期化がされています。
そのため、FileTypeイベントが発生しないと ruby_hl_lvar が有効になりません。
それには、NeoBundle の on_post_source
hook を利用します。
let s:bundle = neobundle#get('ruby_hl_lvar.vim') function! s:bundle.hooks.on_post_source(bundle) silent! execute 'doautocmd FileType' &filetype endfunction unlet s:bundle
vimrcに上の様に記述します。そうすると、 ruby_hl_lvar が読み込まれた後に、FileType イベントが発生し正常に動作する様になります。
NeoSnippet
NeoSnippet とは、コードスニペットを展開するプラグインです。めっちゃべんり
しかし、NeoSnippetとruby_hl_lvarを併用すると、NeoSnippetが正常に動作しません。
vim には、 expr
マップの中でnormal
コマンドを使用できないという仕様があります。
そして、NeoSnippetがSnippetを展開する時がexpr
マップであり、それに反応して ruby_hl_lvar が作動し、その中でnormal
コマンドが使用されているためNeoSnippetが正常に動作しなくなっています。
これを改善するには、normal
コマンドを呼ばないようにしなければなりません。
スニペット展開の時に呼ばれるイベントがTextChanged
なので、そのイベントをそのまま無効にすればよいです。その代わり、x
などでバッファを操作した時に変更が反映されなくなりますが…
先ほどのhookにコードを継ぎ足しましょう。
let s:bundle = neobundle#get('ruby_hl_lvar.vim') function! s:bundle.hooks.on_post_source(bundle) function! Ruby_hl_lvar_filetype() let groupname = 'vim_hl_lvar_'.bufnr('%') execute 'augroup '.groupname autocmd! if &filetype ==# 'ruby' if g:ruby_hl_lvar_auto_enable call ruby_hl_lvar#refresh(1) "autocmd TextChanged <buffer> call ruby_hl_lvar#refresh(0) autocmd InsertEnter <buffer> call ruby_hl_lvar#disable(0) autocmd InsertLeave <buffer> call ruby_hl_lvar#refresh(0) else call ruby_hl_lvar#disable(1) endif endif augroup END endfunction silent! execute 'doautocmd FileType' &filetype endfunction unlet s:bundle
このようにして、Ruby_hl_lvar_filetype()
を上書きします。
そして、TextChangedイベントへの hook をなくします。
そうすることで、NeoSnippetが正常に動作するようになります。