🔎

ミニマリストのためのファジーセレクタ fzyselect.vim

2022/12/16に公開

この記事はVim Advent Calender 2022の17日目の記事です。

screenshot.png

ミニマリストのためのファジーセレクタプラグイン: fzyselect.vimを開発しましたので、その紹介をさせていただきます。

なぜfzyselect.vimなのか

ファジーファインダー・セレクタプラグインはVimプラグインの中でも近年トレンドになっています。telescope.nvimddu.vimをはじめ、世の中には様々なファジーセレクタプラグインが開発され、機能追加され、公開されています。これらのファジーセレクタはよくできており、デザインや検索パフォーマンスも含めてユーザーを満足させてくれます。触っているだけでワクワクさせてくれるものでもあります。

しかし、それらはデフォルトのソースが多すぎたり、抽象度が高すぎて用いないオプションが溢れているものが多くなっています。
これはある種アタリマエな帰結です。ファジーセレクタは汎用的な存在で、それを導入する目的は「様々な操作について、統一的に操作できるUIを提供する」ことでしょう。なので、余計なデフォルトソースや汎用性のあるコードで溢れるのは当然なのです。
しかしながらミニマリストにとって使わないデフォルトソースや用いられないコードは気になってしまうのが性分です。

ミニマリストは、汎用性と合理性を兼ね備えた必要最小限のインタフェースで実装されたファジーセレクタを求めているのです。fzyselect.vimを開発したのはこれを実現するためです。

特徴

1. vim.ui.selectに対応する関数しか提供しない。

本質として汎用性が必要であるファジーセレクタをミニマリスト向けにするためには、その汎用性に合理性があるものでなくてはなりません。つまり、プラグイン作者の自作仕様には疑いの余地があるのです。したがって今回fzyselect.vimを開発するにあたり、仕様について次のことを遵守することにしました。

vim.ui.selectのインタフェースに合わせる

vim.ui.selectはNeovimで標準とされているインタフェースですので、これに遵守することはオレオレインタフェースを自作するよりも合理的です。これは多くのミニマリストを満足させることでしょう。

2. デフォルトソースを同梱しない。

ユーザーにとって要らないソースは同梱するべきではありません。このため、デフォルトソースやキーマップは何ひとつとして同梱しておりません。

このため、各ユーザーが設定ファイルでソースから自作することが求められます。
例えば、git ls-filesでプロジェクト上のファイルをサーチする「ソース」は以下のように設定することができます。

fu! s:fzyselect_lsfiles() abort
	let out = system(['git', 'ls-files'])
	if v:shell_error
		echo out
	el
		cal fzyselect#start(split(out, '\n'), #{prompt:'git ls-files'}, {p-><SID>edit(p)})
	en
endfunction
fu! s:edit(path) abort
	if a:path != v:null
		exe 'e ' .. a:path
	en
endfunction
nnoremap <c-p> <cmd>cal <SID>fzyselect_lsfiles()<cr>

その他需要が高いと思われる設定はREADME.mdに公開しています。

3. matchfuzzyposの使用。

ファジーマッチ及びハイライトはVim組みこみの関数:matchfuzzyposによって行います。組みこみ関数のため高速で、かつ車輪の再発明となっていないことがポイントです。

確かにファジーマッチのアルゴリズムはそのプラグインの性能を特徴づける側面があります。しかしながら、今回は「あるものは使う」精神で自前実装しないことにしました。

インストール方法など

ほとんどのユーザーは、自作ソース設定の他にインストールキーマップ設定を行う必要があります。

Plug.vim

Plug 'gw31415/fzyselect.vim'
" 中略
fu! s:fzy_keymap()
	nmap <buffer> i <Plug>(fzyselect-fzy)
	nmap <buffer> <cr> <Plug>(fzyselect-retu)
	nmap <buffer> <esc> <cmd>clo<cr>
endfu
au FileType fzyselect cal <SID>fzy_keymap()

packer.nvim

use {
    'gw31415/fzyselect.vim',
    config = function()
        vim.api.nvim_create_autocmd('FileType', {
            pattern = 'fzyselect',
            callback = function ()
                vim.keymap.set('n', 'i','<Plug>(fzyselect-fzy)', { buffer = true })
                vim.keymap.set('n', '<cr>','<Plug>(fzyselect-retu)', { buffer = true })
                vim.keymap.set('n', '<esc>','<cmd>clo<cr>', { buffer = true })
            end
        })
    end
}

結び

巷のファジーファインダーは機能が多すぎるという方は、是非fzyselect.vimをご利用してみてください。
ご要望やバグ報告があればこのリポジトリにお願いいたします。

GitHubで編集を提案

Discussion