2016/12/04

ファイル検索プラグイン file_selector.vim を作った

ファイル一覧を絞り込んで選択するやつを作ったので、 そのあたりの作業について備忘メモしておく。

目的

netrw でファイルを開くのが面倒。 プロジェクト内のファイル一覧から、文字列打ち込んで絞り込みつつファイル選択したい。 この欲望を満たすプラグインを作る。

何を考えたか?

ファイル絞り込みの構成要素としては、

  1. ファイル一覧取得
  2. 入力文字列取得
  3. 入力文字列を使った絞り込み処理
  4. バッファへの反映

みたいなのがあると思っていて、 2 と 4 のイメージがついてなくって途方に暮れていたところ、 @pink_bangbi さんにつぶやきを拾っていただいた。

そんなわけで、方針としては

  • 文字列取得は InsertCharPre から一文字ずつ取得
  • バッファは全部書き直し

の方針で考えた。

構成要素の実現方法を考える

それぞれ考えていく。

ファイル一覧取得

単純に glob("./**/*") とする。

入力文字列取得

autocmdInsertCharPre を捕まえる。

入力文字列を使った絞り込み処理 + バッファへの反映

v/文字列/d で、文字列が含まれていない行を削除できるので、

  1. バッファクリア
  2. glob("./**/*") で取得した一覧をバッファに流し込む
  3. v/文字列/d で関係ない行を削除

を、文字列入力・削除が行われるたびに実行する。

文字列のハンドリング

InsertCharPre で取得するのはいいけど、それどう管理するの?」を考える。

  • ファイル一覧
    • ファイル一覧はスクリプト変数
    • ファイル絞り込み用バッファを開くときに、``glob("./**/*") する
  • 絞り込み文字列
    • 絞り込み文字列はスクリプト変数
    • ファイル絞り込み用バッファを開くときに、空文字で初期化する
    • InsertCharPre で取得した文字列を絞り込み文字列に追加する
    • <BS> 押下で絞り込み文字列の末尾の文字を消す

file_selector をクラスとして考えると、下図のような感じ。

  • OpenFileSelector() を呼ぶたびに s:patterns:all_file_list を初期化する。
  • 文字入力されるたび( InsertCharPre が呼ばれるたび) AddChar()s:pattern 更新
    • InsertCharPre 内でバッファの更新ができないようなので、バッファの更新は TextChangedI で行う
  • <BS> が押されたら、 DelChar() -> UpdateBuffer() する。

上記のような方針で実装して、下記のような挙動が実現できた。

所感

「OpenFileSelector() を呼び出したバッファでファイルを開きたい」とか、 すでに気に入らないところがあるが、とりあえず絞り込み UI の習作として使用・改良していきたい。

リポジトリはこちら。

以上。

0 件のコメント: