VS Codeだけでコードを読んでいた頃、特にやりづらかったのが検索でした。結果を待ち、対象ファイルを開き、定義や呼び出し先を確認して、また検索へ戻る。この往復に引っかかりを感じていました。
Neovimへ移ってからは<Space>sGで検索しています。rgを使っているつもりはなかったのですが、いつものキーの裏でripgrepが動いていました。私の環境ではレスポンスに不満はありません。しかし設定を調べ直すと、Snacks Picker、Telescope Live Grep Args、Grug-farの3つが入っていました。それでも、実際に使っていたのは<Space>sGだけです。
一つの検索画面ですべてを済ませるのではなく、普段の検索、複数のripgrep引数を組み立てる検索、置換で入口を分けることにしました。まず使うのはSnacksの<Space>sg、引用・除外・検索先をまとめて指定したい時はTelescopeの<Space>sG、複数ファイルを置換する時はGrug-farの<Space>srです。小文字のsgはSpace、s、g。大文字のsGはSpace、s、Shift+gです。
設定を増やす前に、すでにあるキーを確認した
現在の設定には、次の検索キーがありました。<leader>はSpaceキーです。
| キー | 役割 | 実体 |
|---|---|---|
<leader>ff |
ファイル名から探す | Snacks Picker |
<leader>sg |
プロジェクト全体を文字列検索 | Snacks Picker + ripgrep |
<leader>sG |
引数付きで文字列検索 | Telescope Live Grep Args + ripgrep |
<leader>sw |
カーソル下の単語・選択範囲を検索 | Snacks Picker + ripgrep |
<leader>ss |
現在のファイル内のシンボル(対応するLSP接続中) | LSP + Snacks Picker |
<leader>sS |
ワークスペース全体のシンボル(対応するLSP接続中) | LSP + Snacks Picker |
<leader>sr |
検索結果を見ながら置換 | Grug-far + ripgrep |
SnacksのPicker公式ドキュメントには、ファイル、grep、バッファ、LSPシンボルなどの検索元が並んでいます。私のLazyVim設定では標準の検索入口がSnacksになっていました。
一方、<leader>sGには自分でTelescope Live Grep Argsを追加しています。標準の検索と自分の追加設定が似た名前で並び、役割を決めないまま片方だけ使っていました。
普段はSnacksの<leader>sgを使う
関数名、画面の文言、エラーメッセージなどを探す時は<leader>sgを最初の入口にします。プロジェクトのルートからripgrepで検索し、候補とプレビューを同じ画面で確認できます。
例えば、APIの認証処理を調べるならauthorizeやエラーメッセージをそのまま入れます。まだ正確な関数名が分からない時は、まず文字列から入口を見つけます。
今の設定では、Snacksの検索画面にAlt+tとAlt+gも追加しています。LazyVimではSnacksがすでに設定されているため、require("snacks").setup()をもう一度呼ぶのではなく、lua/plugins/に置くfolke/snacks.nvimのspecへoptsを追加します。実際の設定では、ripgrepへ渡す引数との区切り--が未入力なら自動で補います。
return {
{
"folke/snacks.nvim",
opts = {
picker = {
sources = {
grep = {
win = {
input = {
keys = {
["<M-t>"] = {
function(picker)
local text = picker.input:get()
local suffix = text:find(" -- ", 1, true) and " -t " or " -- -t "
picker.input:set(text .. suffix)
end,
mode = "i",
desc = "Insert -t args",
},
["<M-g>"] = {
function(picker)
local text = picker.input:get()
local suffix = text:find(" -- ", 1, true) and " -g " or " -- -g "
picker.input:set(text .. suffix)
end,
mode = "i",
desc = "Insert -g args",
},
},
},
},
},
},
},
},
},
}
Alt+tでripgrepのファイルタイプ、Alt+gでglobを入力できます。普段の検索はSnacksのまま、必要になった時だけ対象を絞れます。
引数を組み立てたい時だけ<leader>sGへ切り替える
Telescope Live Grep Argsは、検索欄へripgrepの引数も入力できます。公式READMEには、引用符で囲んだ語句、--no-ignore、--iglob、検索対象ディレクトリなどの例があります。
現在の設定では次のキーを使えます。
| 検索画面内のキー | 入力するもの |
|---|---|
<C-k> |
現在の検索語を引用符で囲む |
<M-t> |
-tを追加する |
<M-i> |
--iglobを追加する |
例えばC#だけを対象にするなら、次のような検索です。
"CreateOrder" -t cs
テストディレクトリだけを探すなら、次のように絞れます。
"CreateOrder" --iglob **/test/**
毎回ここから始めると、検索語よりオプションを考える時間が増えます。<leader>sGは、普通のgrepでは対象が広すぎた時の二手目です。
目の前の単語なら<leader>sw、コードの関係ならLSPを使う
カーソル下の関数名や型名を、設定ファイルやドキュメントも含めて文字列検索したい時は<leader>swを使います。選択範囲をそのまま検索することもできます。
一方、定義や参照の関係が欲しい時はgrepではなくLSPです。ただし、次のキーは開いているファイルへLSPが接続し、その操作を言語サーバーが提供している時に使えます。言語やサーバーによって使える範囲は同じではありません。
| キー | 確認するもの | 必要なLSP機能 |
|---|---|---|
gd |
定義 | 定義ジャンプ |
gr |
参照元 | 参照検索 |
gI |
interfaceなどの実装 | 実装検索 |
gy |
型定義 | 型定義検索 |
gai |
呼び出し元 | Call HierarchyのIncoming Calls |
gao |
呼び出し先 | Call HierarchyのOutgoing Calls |
現在のLazyVimでは、特にgaiとgaoは対応するCall Hierarchy機能がある時だけ、そのバッファにキーが作られます。キーが見当たらない時は設定漏れと決めつけず、接続中のLSPがその機能に対応しているかを確認します。<leader>ssと<leader>sSも、それぞれドキュメントシンボルとワークスペースシンボルに対応するLSPが必要です。
私がよくやるのは、検索で対象ファイルへ飛び、gdで定義を開き、grで使われ方を見る流れです。深く移動した後はCtrl+oで戻ります。
grepは文字が一致する場所を探します。LSPは言語としての定義や参照を探します。同じ関数名を探す場合でも、設定やテストデータまで見たいならgrep、コード上の関係だけを追いたいならLSPです。
置換まで進む時は<leader>srで検索をやり直す
検索して読むだけならSnacksかTelescopeで終わります。複数ファイルを変更したい時は、結果を見つけた後に<leader>srでGrug-farを開きます。
私の設定では、現在開いているファイルに拡張子がある場合、同じ拡張子を対象ファイルの初期値にしています。
local ext = vim.fn.expand("%:e")
require("grug-far").open({
prefills = {
filesFilter = ext ~= "" and "*." .. ext or nil,
},
})
Grug-farの公式READMEでは、ripgrepまたはast-grepによる検索・置換、差分表示、Quickfixへの出力などが案内されています。
例えばC#ファイルを開いている時に起動すれば、まず*.csが対象になります。検索結果と置換後の差分を確認してから反映できるため、プロジェクト全体へいきなり置換コマンドを実行するより、変更範囲を把握しやすくなります。
私がまず試す検索の順番
新しいキーを全部覚えるのはやめました。次の順番だけをチートシートへ残しています。
- ファイル名を覚えているなら
<leader>ff - 内容から探すなら
<leader>sg - 目の前の単語を広げるなら
<leader>sw - 条件を細かく付けるなら
<leader>sG - 置換まで行うなら
<leader>sr - コードの関係は
gd、gr、gI - 迷ったら
<leader>?でチートシートを開く
これまでは<leader>sGしか使っていませんでした。まずはsg、複数の条件をまとめて渡すならsG、変更するならsr。この三段階で使います。
ターミナルからプロジェクトへ入り、Neovimで検索するまでの全体像はAIにコードを書かせた後、rg・fzf・Yazi・Neovimで読む、LSPの実行経路はNeovimのLSPが動かない原因はプラグインではなくPATHだったへ書いています。
確認した公式情報
確認日: 2026年9月15日
- Snacks Picker:Pickerの情報源、grep、非同期処理
- Telescope Live Grep Args:ripgrep引数付き検索と入力例
- Grug-far.nvim:検索・置換、差分表示、Quickfix出力
- Telescope.nvim:組み込みPickerと基本設定

コメント