Vim駅伝8/2の記事です。
telescope.nvimはNeovim向けのファジーファインダーと類されるプラグインです。
便利な機能の一つに:Telescope live_grep
があり、プロジェクト内のファイルを正規表現で検索できます。
しかし、検索結果が多いときに、ファイル名で絞り込みたいことがあります。
たとえば、特定のディレクトリだけの結果が必要とか、テスト関係のファイルを除外したいとかいった状況があります。
telescope.nvimには検索結果をクイックフィックスリストに送り込むアクションがあるので、これと:Telescope quickfix
を組み合わせると、近しいことが簡単に実現できます。
require("telescope.builtin").live_grep({
attach_mappings = function(prompt_bufnr, map)
map("i", "<C-G><C-G>", function()
require("telescope.actions").send_to_qflist(prompt_bufnr)
require("telescope.builtin").quickfix()
end)
return true
end,
})
しかし、この方法では検索対象にファイル名だけでなく、grepにマッチした行も含まれてしまいます。
たとえば、以下のようなクイックフィックスリストが作成された場合、ファイル名にqfscope
が含まれる行だけを絞り込みたいとします。
実際には、README.md
の1行目にqfscope
が含まれているため、README.md
もマッチしてしまいます。
README.md|1 col 12| # qfscope.nvim
doc/qfscope.txt|1 col 37| *qfscope.txt* Refine telescope.nvim search results by using quickfix list
doc/qfscope.txt|2 col 11| *qfscope.nvim*
doc/qfscope.txt|6 col 47| Repository: https://github.com/atusy/qfscope.nvim
これを防ぐには、telescope.nvimのsorter
を弄る必要があります。sorter
は、プロンプト文字列に対して検索結果のマッチ度(スコア)を計算するscoring_function
というメソッドを持ちます。
このメソッドを良い感じにしてあげれば、ファイル名だけを検索対象にできます。
scoring_function
は通常では、function(self, prompt, line, entry): number
をいったシグネチャを持ます。
このline
引数が検索対象に相当します。
先程のクイックフィックスリストの例で言えばREADME.md|1 col 12| # qfscope.nvim
ですね。
ファイル名を検索対象にするには、lien
引数の変わりにentry
引数のfilename
フィールドに注目させてあげればOKです。
ということで↓のように上書きする関数を用意しましょう。
local function filename_sorter()
local sorter = require("telescope.config").values.generic_sorter()
local score = sorter.scoring_function
sorter.scoring_function = function(self, prompt, _, entry)
return score(self, prompt, entry.filename, entry)
end
return sorter
end
あとは、:Telescope quickfix
を起動する時に、自前のsorter
を渡してあげれば、live_grep
した結果をファイル名で絞り込めるようになります。
telescope.nvimのsetup
時に、検索アルゴリズムとしてtelescope-fzf-native.nvimを指定していれば、!_test.go
などとして、テスト関連のファイルを除外するといった使い方もできます。
require("telescope.builtin").live_grep({
attach_mappings = function(prompt_bufnr, map)
map("i", "<C-G><C-G>", function()
actions.send_to_qflist(prompt_bufnr)
require("telescope.builtin").quickfix({
sorter = filename_sorter(),
})
end)
return true
end,
})
ちなみに今日紹介した内容をより一般化したプラグインとして、atusy/qfscope.nvimを作成しました。
次回の記事あたりでデモも含めて紹介できたらなと思います。
ENJOY!!