以前 VSCode で英語の入力補完をするプラグイン を作ったので,
今度は Vim で動く英語入力補完プラグイン asyncomplete-nextword.vim を作りました。
このプラグインは正しいスペルを表示するだけでなく,バッファの内容に適した単語を 頻出順 で提案するので便利です。
asyncomplete.vim を使うことで簡単に入力補完プラグインを作成できると分かりました。
asyncomplete.vim を用いた入力補完プラグイン作成の情報が少なかったので,忘れないうちに書き留めておきたいと思います。
入力補完プラグインで実装する・使う関数
/<project_root>/autoload/asyncomplete/sources/<plugin_name>.vim
にて以下の関数を定義します。
asyncomplete#sources#<plugin_name>#get_source_options(opt)
asyncomplete#sources#<plugin_name>#completor(opt, ctx)
また,以下の関数を呼び出します。
asyncomplete#complete(name, ctx, startcol, items, ...)
asyncomplete#log(...)
これから 4 つの関数について解説していきます。
asyncomplete.vim のソースコードを全部は読んでいないので間違っていたらごめんなさい。
get_source_options(opt)
補完プラグイン固有の設定を受け取る関数です。
この関数は asyncomplete.vim を利用したプラグインの README.md に書いてあるとおり, ~/.vimrc
で呼ばれます。
a:opt
はディクショナリ型で,補完プラグインの名前や,有効になる filetype などが格納されています。
asyncomplete-nextword.vim では nextword
コマンドに渡す引数のリストを受け取るために利用しています。
completor(opt, ctx)
buffer の情報 a:ctx
をもとに,補完候補を返す関数です。
おそらく a:opt
は get_source_options()
で返されたものが渡されていると思います。
a:ctx
の中身は asyncomplete#context()
で定義されています。
-
"bufnr"
バッファの番号 -
"curpos"
getcurpos()
の結果 -
"changedtick"
バッファの総変更回数 -
"lnum"
行数(1始まり!) -
"col"
何文字目か "filetipe"
"filepath"
-
"typed"
その行の先頭からカーソルまでの文字列
これらの情報をもとに,asyncomplete#complete()
に補完の候補を渡します。
asyncomplete#complete(name, ctx, startcol, items, ...)
この関数に補完結果を渡します。
name
には get_source_options(opt)
の a:opt['name']
を, ctx
には completor(opt, ctx)
で得た a:ctx
を渡しましょう。
よくわかっていないですが,これらの情報で補完結果が有効かどうか判断しているようです。
startcol
は補完が始まった文字の位置です。この値が不正だと asyncomplete の補完入力がずれます。
items
に補完結果を返します。items
はリスト型で,ディクショナリ型のアイテムを持ちます。
各アイテムはキーに "word"
と "kind"
を持ちます。"word"
が補完結果の文字列で,"kind"
が補完結果の右に表示される説明文です。
asyncomplete#log(...)
この関数はロガーです。
g:asyncomplete_log_file
にログを吐きます。便利です。
おわりに
Vim script でまとまったものを書くのは初めてでしたが,asyncomplete.vim のソースコードが読みやすく,どうにかなりました。
LanguageSeverProtocol 以外の方法で入力補完を行う必要があるケースもあると思うので,この記事がお役に立てれば幸いです(`・ω・´)