Vimの読み取り専用レジスタ("% "# ": ".)の実践的な使い道
ファイル名を手打ちでコピーしていました。Vimには、今のファイル名や直前のコマンドを自動的に保持しているレジスタがあり、これを使えば毎回入力し直す必要がなくなります。
目次(11項目)
| キー | これだけ覚える |
|---|---|
| "% | カレントファイルの名前 |
| "# | 直前に編集していたファイル(alternate file)の名前 |
| ": | 直近に実行したExコマンドラインの内容 |
| ". | 直近に挿入したテキスト |
4つの読み取り専用レジスタ
いずれも自分で書き込むことはできず、p/P/:put/Ctrl-Rで読み出す専用のレジスタです。モードごとの使い分けはこちらにまとめています。
"% でファイル名を挿入する
"%p " ノーマルモードで貼り付け
Ctrl-r % " インサートモードで挿入
Markdownでファイル自身へのリンクを書きたいときや、コミットメッセージにファイル名を含めたいときなど、地味に使う場面が多くあります。
"# でファイルを行き来する
"#はコマンドラインでも便利で、:e #のように使えば直前のファイルへ切り替えられます。2つのファイルを行き来する作業をしているとき、正式なファイル名を毎回入力せずに済みます。
": で直前のコマンドを再現する
":p
直前に実行したExコマンドをテキストとして貼り付けられます。似たようなコマンドを少し変えて再実行したいとき、コマンドライン履歴から探すより、テキストとして貼り付けて編集したほうが早いこともあります。
フルパスやディレクトリ名が欲しいとき
"%はカレントディレクトリからの相対パスを保持しています。フルパスやディレクトリ名だけが欲しい場合は、expand('%:p')やexpand('%:h')のような関数呼び出しをexpressionレジスタと組み合わせて使うと加工できます。単純にファイル名だけで足りるかどうかで使い分けると便利です。
". で直前の挿入を貼り付ける
TODO: fixed bug
DONE│ ← カーソル
TODO: fixed bug
DONE: fixed bug
直近にインサートモードで打ち込んだ内容を、別の場所にも貼り付けられます。Ctrl-@やCtrl-a(挿入モードで直前の挿入内容を再入力するコマンド)も、内部的にはこのレジスタを利用しています。
複数の設定ファイルを見比べる作業で、:e #による行き来を覚えてからファイル名を入力する回数が激減しました。"%でファイル名をコミットメッセージに挿入する使い方も、知ってからは地味に手放せなくなっています。":で直前のコマンドを呼び出す使い方は最初こそピンときませんでしたが、似た置換コマンドを連続で打つ場面で徐々に頼るようになりました。一度覚えると、コマンド履歴を検索するより手が先に動くようになり、置換作業のリズムが崩れなくなりました。
ファイル名を加工して取り出す
"% が持っているのは、Vimがそのファイルを開いたときの表記そのままです。相対パスで開けば相対パス、絶対パスで開けば絶対パスが入ります。加工したいときは expand() に修飾子を渡します。
:echo expand('%') " src/main.js
:echo expand('%:p') " /home/user/proj/src/main.js
:echo expand('%:h') " src(ディレクトリ部分)
:echo expand('%:t') " main.js(ファイル名だけ)
:echo expand('%:t:r') " main(拡張子を除く)
挿入モードで使うときは Ctrl-r = に続けて式を打ちます。テストファイルの名前を本体から組み立てる、といった用途に使えます。修飾子は重ねられるので、%:t:r のように必要な順につなげてください。
Ctrl-^ でファイルを行き来する
"# が指す「直前のファイル」には、専用の切り替えキーがあります。Ctrl-^(環境によっては Ctrl-6)を押すと、いまのファイルと直前のファイルを往復します。
実装とテスト、設定とドキュメントのように2つを行き来する作業では、これが最も手数の少ない方法になります。:e# と打つより速く、バッファ番号を覚える必要もありません。
コマンドラインで打ち直さない
読み取り専用レジスタはコマンドラインでも使えます。加えて、画面から文字列を拾う専用のキーもあります。
:e <Ctrl-r>% " 開いているファイル名を挿入
:%s/<Ctrl-r><Ctrl-w>/ " カーソル下の単語を挿入
:<Ctrl-r>: " 直前のコマンドを呼び出す
長い識別子を置換するときに Ctrl-r Ctrl-w を使えば、打ち間違いが原理的に起きません。似たコマンドを少しだけ変えて実行し直すときは q: でコマンドライン履歴のウィンドウを開くほうが編集しやすくなります。
まとめ
読み取り専用レジスタは自動的に更新される情報を保持しているため、意識して使うだけで手入力の手間を減らせます。レジスタ全体の一覧はこちらを参照してください。各レジスタの正式な定義は公式ヘルプ(:h registers)にあります。