この記事では、Vim / neovim でプラグインを使わずに「全バッファを検索する」ためのコマンドについて、ご紹介します。
[解答] Bufdo + Vimgrep + Quickfix
Vimには、全バッファにコマンド実行するBufdoコマンドと検索コマンド Vimgrep、実行結果を表示するための Quickfix といった便利な機能が備わっています。これらを組み合わせることで、便利に検索することができます。
全バッファの検索結果を一覧表示する
(ノーマルモード) :bufdo vimgrep /{検索パターン}/g % | cwindow :bufdo vim /{検索パターン}/g % |cw (省略形)
:vimgrep コマンドを全バッファで実行した結果を、Quickfixウインドウを開いて表示させるコマンドになっています。
検索パターンについては、通常の検索と同様に Vim で扱える検索パターン(正規表現)を入力します。
検索の対象として、% はカレントバッファ(今開いているバッファ)を指します。これを全バッファに適用しているわけです。
このコマンドは、vimgrep の次の実行書式が元になっていますので、覚えておきましょう。
:vimgrep {検索パターン} {検索対象}
このコマンドの実行結果は、Quickfixウインドウ (実行結果のウインドウ)に格納されます。
ただし、このまま実行しても検索結果の一覧は表示されませんので、それを次のコマンドで Quickfixウインドウを開いています。
:cwindow
検索結果の一覧表示ウインドウを常に表示する
Quickfixウインドウを表示する動作を標準動作にするには、次のコマンドを実行します。
(ノーマルモード) :autocmd QuickFixCmdPost *grep* cwindow
次のように設定ファイル(.vimrc / init.nvimなど)に記載しておくのも良いかもしれません。
autocmd QuickFixCmdPost *grep* cwindow
あるいは、次のようにキーマッピングしておくのも手かもしれませんね。
command! -nargs=1 Myvimgrep :vimgrep /<args>/g % | cw
nnoremap <Leader>g :Myvimgrep
補足
vimgrep は内部grepとも呼ばれます。通常の検索と比べて便利な点は次の通りです。
- 検索にヒットした件数がわかる
- Quickfixで一覧表示できる
- カレントバッファ以外も検索できる
今回の方法は、最後の利点を現す方法の一つです。
これらについては、次の記事でも言及していますので、ぜひご確認ください。
このVimコマンドの補足情報
- 利用頻度
- 便利さ
- 覚え易さ
関連するVimヘルプ
Vim のヘルプでは下記のように解説されています。
5.1 Vimの内部grepの使い方
:vim:vimgrepE682E683
:vim[grep][!] /{pattern}/[g][j] {file} …
ファイル{file}から{pattern}を検索し、マッチ位置をエラー
リストに追加する。‘wildignore’ にマッチしたファイルは
無視される。‘suffixes’ にマッチしたファイルは最後に検
索される。
フラグ ‘g’ がない場合、各行は1度だけ追加される。
‘g’ がある場合、マッチ位置が毎回追加される。{pattern}はVimの検索パターンである。/ で囲まない場合、
それが{pattern}中に現れない限り、どんな非ID文字
(‘isident’ を参照) でも使える。
‘ignorecase’ が適用される。パターン中に/\cを含めると
大文字小文字を区別しなくなり、/\Cを含めると区別する
ようになる。これは ‘ignorecase’ より優先される。
‘smartcase’ は適用されない。
{pattern} が空のときは(つまり // が指定されたときは)、
最後に使われた検索パターンが使用される。last-pattern
:{count}vim[grep] …
このコマンドの前に数字が置かれると、その数が検索する
マッチの最大数となる。”:1vimgrep pattern file” とする
と最初のマッチだけを検索する。マッチが存在するかどうか
だけをチェックしたく、それが見つかったらすぐに終了して
ほしい場合に便利である。フラグ ‘j’ がない場合、最初のマッチへジャンプする。
‘j’ がある場合はquickfixリストが更新されるだけである。
[!]がついた場合、カレントバッファに対する変更は全て失
われる。進行状況を示すため、1秒程度ごとに検索されたファイル名
が表示される。
例:
:vimgrep /an error/ *.c
:vimgrep /\<FileName\>/ *.h include/*
:vimgrep /myfunc/ **/*.c “**” の使い方についてはstarstar-wildcardを参照。:vim[grep][!] {pattern} {file} …
quickfix – Vim日本語ドキュメント
上と同様だが、パターンを非ID文字で囲むのでなく、空白で
パターンを区切る。パターンはID文字で始まらねばならな
い。
例:
:vimgrep Error *.c
:cw[indow] [height] 認識されたエラーがあるときquickfixウィンドウを開く。
quickfix – Vim日本語ドキュメント
ウィンドウがすでに開いていて認識されたエラーがない場合
はウィンドウを閉じる。
。
:bufdo
windows – Vim日本語ドキュメント
:[range]bufdo[!] {cmd} {cmd} をバッファリスト内の各バッファに対して実行する。
[range]が指定された場合は、指定された範囲の番号の
バッファが操作対象となる。これは次のようにするのと同じ
動作をする:
:bfirst
:{cmd}
:bnext
:{cmd}
etc. カレントファイルが破棄されえなく(abandon)かつ [!]が
与えられない場合、このコマンドは失敗する。
1つのバッファに対してエラーが検出されると、それ以降
のバッファに対しては実行されない。
リストされていないバッファはスキップされる。
最後のバッファ (またはエラーが起こったバッファ) がカレ
ントウィンドウになる。
{cmd} は ‘|’ を含んで複数のコマンドを連結していてもよ
い。
{cmd} はバッファリストにバッファを削除、追加してはなら
ない。
Note:このコマンドを実行している間、Syntax 自動コマンド
イベントが ‘eventignore’ に追加され、無効化される。
これは各バッファの編集を大幅にスピードアップさせる。
:tabdo、:argdo、:windo、:cdo、:ldo、:cfdo、
:lfdo も参照。
こちらは、Vim上では下記のコマンドでヘルプを確認できます。
:help :vimgrep :help :vim :help :cw :help :cwindow :help quickfix :help :bufdo
ヘルプで検索するときは、通常は大文字小文字は識別されませんので、どちらでも構いません。
参考書籍
Vim力をレベルアップさせるには、こちらの書籍が参考になります。
Vim/neovim関連の書籍で、もっとも評判が良くてバイブルと呼んでる人もいる一冊です。Vim/neovimのバージョンに依存しない沢山のTips形式で、その表題通りに「思考のスピードで編集」できるようになるノウハウが詰まっています。その高い評価は Amazon のレビューからも分かる通りです。Vimmer なら必ず一度は読んでおいて間違いありません。
こちらもVim関連の書籍で評価が高い書籍の一冊です。vim-jpで見かける上級Vimmer(Vimサポーターズ)の皆様による、Vimを実践で使ったノウハウからプラグイン関連の情報が詰まっています。日本の Vim界隈を知る上でも是非一読しておきたい一冊です。
Vim/neovim の設定ファイルやプラグインなど、Vim script に関するノウハウがいくつも詰まった一冊です。日本で Vim Script をここまで深く解説している唯一の書籍と言えます。Vim力を伸ばしたいと考えるなら、絶対に避けては通れない書籍でしょう。