snacks.nvimのpickerでkensaku.vimによる全文検索を行う
はじめに
snacks.nvimがとても使いやすかったので、多くのプラグインをこちらに移行しています。
Fuzzy Finderも例外ではないのですが、私はあらゆるメモをひとつのディレクトリで管理しており、日本語による全文検索を多用していました。そのため、kensaku.vimに対応していないのは大きな問題です。
以前はtelescope.nvimとそのkensaku.vim対応Extensionにお世話になっていました。
pickerにオリジナルの全文検索sourceを追加する
snack.nvimのpickerには40以上の検索sourcesが組み込まれており、ファイル名やファイルの内容だけでなく、GitやLSP、Vimのキーマップ等の情報まで検索できるようになっています。
いかにもオリジナルのsourceを追加できそうなのですが、情報があまりなかったので無理やり追加してみます。
live_grepのsourceをコピペ
built-inのlive_grepと同じ動きをしてくれれば良いので、まずは
を ~/.config/nvim/lua/plugins/snacks/sources/grep_kensaku.lua
にコピペします。
検索文字列をkensaku.vimの正規表現に変換
get_cmd
関数でripgrepの引数を生成しているので、検索文字列を扱っている部分を探してkensaku.vimの正規表現に変換します。
local function get_cmd(opts, filter)
-- ...
local pattern, pargs = Snacks.picker.util.parse(filter.search)
vim.list_extend(args, pargs)
-- 検索文字列をkensaku.vimの正規表現に変換
local kensaku_pattern = vim.fn["kensaku#query"](pattern, {
rxop = vim.g["kensaku#rxop#javascript"],
})
args[#args + 1] = "--"
table.insert(args, kensaku_pattern)
-- ...
end
モジュールの型をsourceに合わせる
built-inの grep
はこんな感じになっています。
M.grep = {
finder = "grep",
regex = true,
format = "file",
show_empty = true,
live = true, -- live grep by default
supports_live = true,
}
finder
を必要なタイミングで関数に置き換えているようなので、そこだけ最初から関数にしたモジュールにしておきます。
local function get_cmd(opts, filter)
-- ...
local pattern, pargs = Snacks.picker.util.parse(filter.search)
vim.list_extend(args, pargs)
-- 入力文字列をkensaku.vimの正規表現に変換
local kensaku_pattern = vim.fn["kensaku#query"](pattern, {
rxop = vim.g["kensaku#rxop#javascript"],
})
args[#args + 1] = "--"
table.insert(args, kensaku_pattern)
-- ...
end
-- ...
-- M.grepをM.finderに変更
M.finder(opts, ctx)
-- ...
end
M.regex = true
M.format = "file"
M.show_empty = true
M.live = true
M.supports_live = true
return M
lazy.nvimでsourceを追加
built-inのsourceのfinderは実行される直前に読み込まれるようなので、同じようにキーマップが呼ばれたタイミングでgrep_kensakuモジュールをsourcesに追加し、Snacks.pickerのcontextで実行します。
return {
"folke/snacks.nvim",
priority = 1000,
lazy = false,
dependencies = { "lambdalisue/kensaku.vim" },
---@type snacks.Config
opts = {
picker = { enable = true },
},
keys = {
{ "<leader>/", function() Snacks.picker.grep() end, desc = "Grep" },
{
"<leader>fk",
function()
require("snacks.picker.config.sources").grep_kensaku = require("plugins/snacks/sources/grep_kensaku")
Snacks.picker.grep_kensaku()
end,
desc = "Grep with kensaku.vim",
},
-- ... Other keymaps
},
}
無事に検索できました!
Discussion