ファイル一覧を絞り込んで選択するやつを作ったので、 そのあたりの作業について備忘メモしておく。
目的
netrw でファイルを開くのが面倒。 プロジェクト内のファイル一覧から、文字列打ち込んで絞り込みつつファイル選択したい。 この欲望を満たすプラグインを作る。
何を考えたか?
ファイル絞り込みの構成要素としては、
- ファイル一覧取得
- 入力文字列取得
- 入力文字列を使った絞り込み処理
- バッファへの反映
みたいなのがあると思っていて、 2 と 4 のイメージがついてなくって途方に暮れていたところ、 @pink_bangbi さんにつぶやきを拾っていただいた。
vim で絞り込み機能を実装する方法気になる。入門としてどのプラグインの実装を見るのがよさげだろうか...
— 大雪 命 (@mikoto2000) 2016年12月1日
そんなわけで、方針としては
- 文字列取得は
InsertCharPre
から一文字ずつ取得 - バッファは全部書き直し
の方針で考えた。
構成要素の実現方法を考える
それぞれ考えていく。
ファイル一覧取得
単純に glob("./**/*")
とする。
入力文字列取得
autocmd
で InsertCharPre
を捕まえる。
入力文字列を使った絞り込み処理 + バッファへの反映
v/文字列/d
で、文字列が含まれていない行を削除できるので、
- バッファクリア
glob("./**/*")
で取得した一覧をバッファに流し込むv/文字列/d
で関係ない行を削除
を、文字列入力・削除が行われるたびに実行する。
文字列のハンドリング
「InsertCharPre
で取得するのはいいけど、それどう管理するの?」を考える。
- ファイル一覧
- ファイル一覧はスクリプト変数
- ファイル絞り込み用バッファを開くときに、``glob("./**/*") する
- 絞り込み文字列
- 絞り込み文字列はスクリプト変数
- ファイル絞り込み用バッファを開くときに、空文字で初期化する
InsertCharPre
で取得した文字列を絞り込み文字列に追加する<BS>
押下で絞り込み文字列の末尾の文字を消す
file_selector をクラスとして考えると、下図のような感じ。
OpenFileSelector()
を呼ぶたびにs:pattern
とs:all_file_list
を初期化する。- 文字入力されるたび(
InsertCharPre
が呼ばれるたび)AddChar()
でs:pattern
更新InsertCharPre
内でバッファの更新ができないようなので、バッファの更新はTextChangedI
で行う
<BS>
が押されたら、DelChar()
->UpdateBuffer()
する。
上記のような方針で実装して、下記のような挙動が実現できた。
所感
「OpenFileSelector() を呼び出したバッファでファイルを開きたい」とか、 すでに気に入らないところがあるが、とりあえず絞り込み UI の習作として使用・改良していきたい。
リポジトリはこちら。
以上。
0 件のコメント:
コメントを投稿