hotoolong's blog

プログラムのことやエンジニアリングに関することを記事にしています。

vimのプラグインマネージャをdein.vimに変更しようとして読み込めないプラグインがある?

イントロ

現在vim-plugを使っています。 プラグインが増えてきて遅延させてロードを対応したこともあったんですけど、 設定が必要なプラグインの場合ロード前に設定がエラーなるようなケースもあり、 deinに乗り換えることにしました。

github.com

以前もdeinを使っていたのですが、vim-plugに移行して、戻ろうとしています。 以前はtomlファイルで管理していなかったのですが、非同期で読み込みませるため、tomlで管理することにしました。

dein.vim の設定

dein.vim は 非同期にプラグインの設定を読み込むことができるのでドキュメントを読みながら設定をしていきました。 以前使っていたときにはtomlファイルで管理していなかったのですが、今回はtomlファイルで管理してみようかと思います。

hookの複数設定

hookを複数設定することはできそうです。 hook_add と hook_source を設定して遅延して読み込みたいものは後で読み込ませることは出来ました。 同じhook(例えば hook_addとhook_add)を設定すると後勝ちになります。 誤って設定して場合には気をつける必要があります。

depends の振る舞い

ドキュメントを確認すると以下のようになっています。

depends      (List or String)
        Specify a list of plugins a plugin depends on.
        List items are '{plugin-name}'.
        Those specified in the list are NOT installed automatically.
        Note: The loading order is not guaranteed in non lazy plugins.

注:レイジーでないプラグインでは、ロード順序は保証されません。 とあります。

tomlファイルをlazy 0と1の2ファイルを用意しました。

私は使わなかったのですが、
ドキュメントを読んでいるとlazyはNumberで設定できるので2以上でも設定できそうです。

以下が用意した設定です。

  call dein#load_toml('dein.toml',      {'lazy': 0})
  call dein#load_toml('dein_lazy.toml', {'lazy': 1})

呼び出すプラグインは dein.tomlにA,Bというプラグインを 呼び出す設定をして hook_add で コメントを出力しました。 上から順番に呼ばれることが予想されるのでB,Aの順にプラグインを記載しています。 同じくdein_lazy.tomlにC,Dというプラグインを呼び出す設定をしてコメントを出力しています。 こちらも同様にD,Cの順に記載しいます。

BのdependsにAを DのdependsにCを設定しました。

この状態でどのような順序で呼ばれるのかを確認してみました。

B hook_add
A hook_add
D hook_add
C hook_add

という順で呼び出されました。 記述順に呼び出されています。 hook_addはdependsに影響しないようです。

AからDのプラグインにhook_sourceを追加してみました。

B hook_add
A hook_add
D hook_add
C hook_add
A hook_source
B hook_source

lazyでないファイルのA,Bはhook_sourceが呼び出されていますが、 lazyなファイルのC,Dは呼び出されませんでした。

ドキュメントを確認すると

dein#end() の後、または VimEnter で autoloadされるようです。

非遅延型プラグインの hook_source は使用できません。
必要に応じてdein#call_hook() で呼び出す必要があります。

ということでした。

dein#call_hook('source')

を明示的にconfigに記載することで呼び出すことができます。 ドキュメントを見ると、 on_eventがあり

on_event (String) or (List)
        dein will call |dein#source()| on the events.

設定することでsourceが呼べるそうです。

先程 呼びだされなかったCとDに

on_event = 'CursorMoved'

を設定してカーソルを移動してみます。

B hook_add
A hook_add
D hook_add
C hook_add
A hook_source
B hook_source
A hook_source
B hook_source
C hook_source
D hook_source

何故かA,Bのhook_sourceが2回呼ばれています。
初回のA,Bのhook_sourceは何も設定しないでdein#end()の後に呼び出されるもので、
その後ろのA,B,C,Dのhook_sourceはカーソル移動させたときによばれるようです。
設定されてるhook_sourceは何度も呼ばれるかもしれないです。
とりあえずこれで設定が呼び出されることはわかりました。

on_ft の振る舞い

次にon_ftです。 ドキュメントを見てみましょう。

on_ft        (List) or (String)
        If it is matched to 'filetype', dein will call
        |dein#source()|.

ファイルタイプを設定することで呼び出されるようです。
先程のA,B,C,Dにon_ftを設定してみます。

今回はrubyを設定してみます。

一旦jsファイルを開いてみます。

B hook_add
A hook_add
D hook_add
C hook_add
A hook_source
B hook_source
A hook_source
B hook_source
C hook_source
D hook_source

すべてのhookが呼び出されました。

rubyファイルを呼び出してみます。

A hook_add
B hook_add
C hook_add
D hook_add

予想では逆の挙動になるかと思ったのですが、
rubyファイルでhook_sourceが呼ばれなくなりました。
lazyではないA,Bのhook_sourceも呼ばれなくなりました。
lazy側のC,Dのon_eventとバッティングしてるのか気になったので一旦外して
再度rubyファイルを確認してみました。

B hook_add
A hook_add
D hook_add
C hook_add
A hook_source
B hook_source

A,Bのhook_sourceは呼ばれるようになりました。 jsファイルも確認してみたのですが同様の結果になりました。
on_ft と on_event で挙動がおかしくなるのかもしれないです。

on_ftを設定している場合はhook_addに設定を記載するほうがいいかもしれないです。

on_idle の振る舞い

先程のon_eventを設定していましたが、 on_idleを設定するのが便利そうです。

on_idle      (Number)
        If set to non-zero, dein will call |dein#source()| on
        |FocusLost| or |CursorHold| autocmd.
        Note: This is deprecated option.  You should use
        |dein-options-on_event| instead.

on_idle を設定すると FocusLost CursorHold のイベントで dein#source() が 呼び出されるようです。 イベントを設定するよりもこのオプションでカバーできそうです。

上手くいかないこと

いろいろ試しながらわかったこともはあるのですが、 スニペットが上手く動かなくなってしましました。 調べてみたのですが、よくわからない状態です。

lazyでのhook_source

lazyに high-moctane/asyncomplete-nextword.vimリポジトリを設定して

[[plugins]]
repo = 'high-moctane/asyncomplete-nextword.vim'
depends = ['asyncomplete.vim']
on_idle = 1
hook_source = '''
call asyncomplete#register_source(asyncomplete#sources#nextword#get_source_options({
  \   'name': 'nextword',
  \   'whitelist': ['*'],
  \   'args': ['-n', '20'],
  \   'completor': function('asyncomplete#sources#nextword#completor')
  \   }))
'''

このような設定をしていたのですが、

[dein] Error occurred while executing hook: asyncomplete-nextword.vim
[dein] Vim(call):E117: 未知の関数です: asyncomplete#sources#nextword#get_source_options

ファイル読み込み時にエラーになってしまいました。 検証していたようにhook_addであれば先に読み込まれるのでhook_source を hook_addに変更してみたのですが、 同様のエラーになりました。 plugins自身のfunctionなのですが、参照出来ない状態になりました。 asyncomplete-nextword.vim は上手く読み込まれないのかもしれないです。

scriptnamesを確認するとasyncomplete-nextword.vimは含まれてなさそうです。

filter /async/ scriptnames

で関連する

'prabirshrestha/asyncomplete.vim'
'prabirshrestha/async.vim'

が読み込まれているか確認してみると

 50: ~/.cache/dein/.cache/init.vim/.dein/plugin/async.vim
 51: ~/.cache/dein/.cache/init.vim/.dein/plugin/asyncomplete-lsp.vim
 52: ~/.cache/dein/.cache/init.vim/.dein/plugin/asyncomplete.vim
167: ~/.cache/dein/.cache/init.vim/.dein/autoload/asyncomplete.vim
168: ~/.cache/dein/.cache/init.vim/.dein/autoload/asyncomplete/utils/_on_change/textchangedp.vim
169: ~/.cache/dein/.cache/init.vim/.dein/autoload/asyncomplete/sources/ale.vim
192: ~/.cache/dein/.cache/init.vim/.dein/autoload/gitgutter/async.vim

と出力されているので関連するプラグインは読み込まれていそうです。
自身のプラグインは読み込まれていないので、何かが起因で読み込まれないのかもしれないです。

同様に

[dein] Error occurred while executing hook: asyncomplete-ultisnips.vim
[dein] Vim:E492: エディタのコマンドではありません: asyncomplete#sources#ultisnips#get_source_options

とエラーになっています。 こちらは関連するプラグインが以下の通りで 'SirVer/ultisnips'
'honza/vim-snippets'

filter /snip/ scriptnames

プラグインが見つからなかったので読み込まれてないようです。

他の影響があるかもしれないので以下のプラグインを読み込むだけの設定ファイルを作ってみました。

[[plugins]]
repo = 'Shougo/dein.vim'

[[plugins]]
repo = 'SirVer/ultisnips'

これをlazy 0 で読み込んで確認してみました。

call dein#load_toml('dein_test.toml', {'lazy': 0})

この設定でファイルを開いて

filter /snip/ scriptnames

再度scriptnamesで確認してみるとプラグインは見つかりませんでした。 読み込まれるプラグインと読み込まれないプラグインがあるかもしれないです。

ちなみにキャッシュファイル配下にはSirVer/ultisnipsのディレクトリは存在しているので読み込みに時に何かあるやもしれません。

*追記* UltiSnips.vimリポジトリ名とvimファイル名が異なっていた為、scriptnamesで確認できました。

~/.cache/dein/.cache/init.vim/.dein/plugin/UltiSnips.vim

まとめ

一旦ここまで移行してきたのですが、
vimデバッグする方法がわからなさすぎるので、どうすればいいかわからない状態です。
解決方法が分からない場合はまたvim-plugに戻して動かそうかとも思います。 私にはdein.vimは早すぎたのか、vimで嵌って時間が取られるケースがとても増えてきているので、VSCodeに移行時期かもしれません。
vimって難しいですね。

*追記*

Shougoさんに確認いただけてプラグインの読みこみはされている状態でした。
現状自分が設定している環境でhook_sourceでプラグインが上手く読み込まれてないことは確認出来ている状態なので、
時間があるときに最小構成で確認していこうかと思います。

参考にしたサイト

https://www.youtube.com/watch?v=B6rhg9uAWi8 https://qiita.com/kawaz/items/ee725f6214f91337b42b https://qiita.com/delphinus/items/cd221a450fd23506e81a