🍿

snacks.nvimのpickerでkensaku.vimによる全文検索を行う

2025/03/04に公開

はじめに

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と同じ動きをしてくれれば良いので、まずは

https://github.com/folke/snacks.nvim/blob/bc0630e43be5699bb94dadc302c0d21615421d93/lua/snacks/picker/source/grep.lua

~/.config/nvim/lua/plugins/snacks/sources/grep_kensaku.lua にコピペします。

検索文字列をkensaku.vimの正規表現に変換

get_cmd 関数でripgrepの引数を生成しているので、検索文字列を扱っている部分を探してkensaku.vimの正規表現に変換します。

~/.config/nvim/lua/plugins/snacks/sources/grep_kensaku.lua
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 はこんな感じになっています。

https://github.com/folke/snacks.nvim/blob/bc0630e43be5699bb94dadc302c0d21615421d93/lua/snacks/picker/config/sources.lua#L334

snacks.nvim/lua/snacks/picker/config/sources.lua
M.grep = {
  finder = "grep",
  regex = true,
  format = "file",
  show_empty = true,
  live = true, -- live grep by default
  supports_live = true,
}

finder を必要なタイミングで関数に置き換えているようなので、そこだけ最初から関数にしたモジュールにしておきます。

https://github.com/folke/snacks.nvim/blob/bc0630e43be5699bb94dadc302c0d21615421d93/lua/snacks/picker/config/init.lua#L277

grep_kensaku.lua
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で実行します。

~/.config/nvim/lua/plugins/snacks/init.lua
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