この記事では、Vim / neovim でプラグインを使わずに「ファイルを探す」ためのコマンドについて、ご紹介します。
[解答] :find
今回紹介する :find コマンドは、path オプションに設定されたパス配下のファイルを探してくれます。
準備
次のように値を追加すると、カレントディレクトリ配下のファイルを対象に検索してくれるようになります。
:set path+=$PWD/**
** が指定ディレクトリ配下を示す表記になります。
設定ファイル(.vimrc/init.nvimなど)に次のように記載しても良いでしょう。
set path+=$PWD/**
次のコマンドで検索対象のパスを確認できます。
:set path?
標準だと、カレントディレクトリ(.) と /usr/include (C言語のヘッダファイルディレクトリ)です。
ファイルを検索して編集する
次のシンプルなコマンドで、pathオプションの値のパスからファイルを探して編集に入ります。
(ノーマルモード)
:find {ファイル名}
単純に探すだけでなく、ファイルの編集に移行します。次の動画をご覧ください。
* を入力すると、候補を補完してくれるのもポイントです。**を入力するとディレクトリ名を保管してくれます。これらをうまく使いましょう。
補足
インターネットで検索すると、Vim でファイル検索をするためには fzf を活用するケースが多く見られます。しかし、プラグイン無しでもそれなりに検索はできるので、必要かどうかは一考する価値があるのではないでしょうか。
また、ヘルプを見る限り、もっと複雑な検索ができたりします。しかし、複雑な検索をするならOSの検索コマンドを使ったほうがシンプルで速かったりもするので、あまり必要を感じないんじゃないかとは思います。
このVimコマンドの補足情報
- 利用頻度
- 便利さ
- 覚え易さ
関連するVimヘルプ
Vim のヘルプでは下記のように解説されています。
:fin :find
:fin[d][!] [++opt] [+cmd] {file}
オプション ‘path’ 内のディレクトリから {file} を探し、
それを :edit する。
{Vimが +file_in_path 機能付きでコンパイルされたとき
のみ有効}:{count}fin[d][!] [++opt] [+cmd] {file}
editing – Vim日本語ドキュメント
コマンド “:find” と同様だが、オプション ‘path’ 内のディ
レクトリで {count} にマッチしたファイルを編集する。つ
まり “:2find file” とすると ‘path’ 内で2番目に見つかっ
た “file” を編集する。‘path’ 内で見つかったマッチが
{count} より少ないと、エラーメッセージが表示される。
11. ファイル検索 file-searching
{Vimが +path_extra 機能付きでコンパイルされたときのみ有効}
現在の所、オプション ‘path’, ‘cdpath’, ‘tags’ とfinddir(), findfile() で、
本節で説明する「ファイル検索」にしたがってワイルドカードの展開が行われる。
それ以外のコマンドでは wildcards という少し異なるルールにしたがう。ファイル検索には以下の3種類がある:
1) 下向き検索: starstar
下向き検索にはワイルドカード ‘*’ と ‘**’ 及びユーザーのOSがサポートするその
他のものが使える。’*’ と ‘**’ はVim内部で処理されるので、全てのOSで機能する。
Note “**” はパス名の先頭で使われた場合のみ特別なワイルドカードとなる。‘*’ の使用法はきわめて単純: 0 個以上の文字にマッチする。
正規表現パターンでいうと “.*” と同じである。正規表現と異なり “.” は必要ない
ことに注意。‘**’ はもっとすばらしい。
– これはディレクトリのみにマッチする。
– これはデフォルトで 30 段階までの深さのディレクトリにマッチするので、ディ
レクトリツリー全体の検索に使える。
– マッチする深さの最大値は ‘**’ の後に数字を付け加えて指定できる。
だから ‘/usr/**2’ は下のようにマッチする。
/usr
/usr/include
/usr/include/sys
/usr/include/g++
/usr/lib
/usr/lib/X11
…. ‘/usr/include/g++/std’ には、深さが3なのでマッチしない。
指定可能な範囲は 0 (‘**0’ は無視される) から 100 である。
負数を指定すると 30 を、100 より大きい数を指定すると 100 を指定したも
のとされる。システムにもパスの長さの限界が存在する場合がある。通常は
256 または 1024 バイトである。
– ‘**’ はパスの末尾にのみ使える。後ろにパス区切り文字か、数字とパス区切
り文字の組み合わせを付けてもよい。‘*’ と ‘**’ を組み合わせる順番は自由である。
/usr/**/sys/*
/usr/*tory/sys/**
/usr/**2/sys/*
2) 上向き検索:
この方法ではディレクトリを指定すると、そのディレクトリから上に遡ってファイ
ルを探す。上向き探索の上限となるディレクトリが指定できる。それはパス (オプ
ション ‘path’) かファイル名 (オプション ‘tags’) の末尾に ‘;’ で区切って指定
する。複数のディレクトリを指定したいときはそれらを ‘;’ で区切る。上限ディレ
クトリを指定したくないときは (ルートディレクトリまで上向き検索したいとき)
‘;’ だけを付ける。
/usr/include/sys;/usr で検索されるディレクトリは:
/usr/include/sys
/usr/include
/usr
相対パスを使うと上向き検索はVimのカレントディレクトリから始まる。相対パスの
指定が ‘./’ で始まり、‘cpoptions’ にフラグ ‘d’ が含まれていないときはカレン
トファイルのディレクトリから始まる。Vimのカレントパスが /u/user_x/work/release のときに
:set path=include;/u/user_x とすると、コマンド gf でファイルを探す範囲は:
/u/user_x/work/release/include
/u/user_x/work/include
/u/user_x/include
3) 複合検索:
Vimのカレントパスが /u/user_x/work/release のときに
set path=**;/u/user_x とすると、コマンド gf でファイルを探す範囲は:
/u/user_x/work/release/**
/u/user_x/work/**
/u/user_x/**
注 意 ! これはかなりの時間を食うかもしれない。’/u/user_x/**’ は
‘/u/user_x/work/**’ や ‘/u/user_x/work/release/**’ を含むからだ。つまり
‘/u/user_x/work/release/**’ は3回、’/u/user_x/work/**’ は2回繰り返して検索
される。上の例では次のように設定したほうがいいかもしれない:
:set path=**,/u/user_x/** これに含まれる範囲は
/u/user_x/work/release/**
/u/user_x/**
となり、同じディレクトリだが順番が違う。Note: 現在 “:find”、”:sfind”、”:tabfind” コマンドは、‘path’ アイテムに URL
や深さ制限付きのダブルスター (/usr/**2) や 上方検索 (;) などが含まれている
と機能しない。vim:tw=78:ts=8:noet:ft=help:norl:
editing – Vim日本語ドキュメント
こちらは、Vim上では下記のコマンドでヘルプを確認できます。
:help :find :help :fin
ヘルプで検索するときは、通常は大文字小文字は識別されませんので、どちらでも構いません。
参考書籍
こちらの書籍が参考になります。
Vim/neovim関連の書籍で、もっとも評判が良くてバイブルと呼んでる人もいる一冊です。Vim/neovimのバージョンに依存しない沢山のTips形式で、その表題通りに「思考のスピードで編集」できるようになるノウハウが詰まっています。その高い評価は Amazon のレビューからも分かる通りです。Vimmer なら必ず一度は読んでおいて間違いありません。
こちらもVim関連の書籍で評価が高い書籍の一冊です。vim-jpで見かける上級Vimmer(Vimサポーターズ)の皆様による、Vimを実践で使ったノウハウからプラグイン関連の情報が詰まっています。日本の Vim界隈を知る上でも是非一読しておきたい一冊です。
Vim/neovim の設定ファイルやプラグインなど、Vim script に関するノウハウがいくつも詰まった一冊です。日本で Vim Script をここまで深く解説している唯一の書籍と言えます。Vim力を伸ばしたいと考えるなら、絶対に避けては通れない書籍でしょう。