vim中級者からステップアップするために必要なことを考える
はじめに
vimを使い始めて数ヶ月が経ち、基本的な操作には慣れてきた。hjklで移動し、iやaで挿入モードに入り、:wqで保存して終了する。けれど、まだvimの力を十分に引き出せていない気がする―そんな感覚を抱いている人は多いのではないでしょうか(少しくらいはいてほしい)。
私自身、vimを使い始めた当初は「なんとなく使える」状態が長く続いていました。しかしvimの本質的な思想に触れることで編集効率を上げることができました。この記事では、私がvimmerとしてステップアップする過程で学んだことを振り返りがてら紹介しています。
思えば私が本格的にvimを使うようになったのは大学時代、研究室でのサーバー管理で使うようになったことがきっかけでした。細かいことはもはや覚えていないですが、VScodeもろくに使いこなせていなかった状態でvimを使うようになったことは覚えています。実際自分はコードの編集で日常的に使用するような基礎的な動作ですらVSCodeでどうやるのかわかりません。Cursorに馴染めなかった理由の一つがこれですね。
Practical Vimを読む
vimmerにとっての聖典と名高い『Practical Vim』ですが、その名に恥じない内容で多くのことを学べます。vimを本格的に使っていきたい人には特におすすめで、一通り目を通すだけでも一気にレベルを上げられると思います。この書籍を通して最も重要な学びは「編集単位を小さくする」という考え方でしょう。この考え方はvimを使いこなす上で必要不可欠です。
編集単位を小さくすることの意味
編集単位を小さくするとは、一つ一つの操作を原子的(これ以上分割できない最小単位)にすることです。例えば、ある単語を削除して別の単語に置き換える操作を考えてみましょう。
初心者の頃の私は、iで挿入モードに入り、BackspaceやDeleteキーで文字を消して、新しい文字を入力していました。しかしこれでは、「削除」と「入力」が混在した複雑な操作になってしまいます。
編集単位を小さくする考え方では、ciw(change inner word)で単語を削除して挿入モードに入り、新しい単語を入力します。このように「削除」と「入力」の操作を分解することで、後述するマクロや.(ドットコマンド)での繰り返しが容易になります。
ドットとマクロの力
編集単位を小さくすることで受けられる恩恵のうち、最もわかりやすいのがマクロです。
マクロは一連の操作を記録して繰り返し実行できる機能で、q<レジスタ名>で記録を開始し、再度qで終了します。例えば、複数行の文頭に- を追加してリスト形式にしたい場合は、以下のようにしてマクロを記録できます。
qa " aレジスタにマクロ記録開始
I- <Esc> " 行頭に'- 'を挿入
j " 次の行へ移動
q " 記録終了その後、@aで実行、@@で直前のマクロを再実行、10@aで10回繰り返すことができます。編集単位が小さければ小さいほど、マクロは汎用的で再利用しやすくなります。これがPractical Vimで強調される重要なポイントです。
テキストオブジェクトとモーションを理解する
この記事ではあまり具体的なテクニックに触れるのは避けるつもりでしたが、これだけは知っていてほしいと感じたので少しだけテキストオブジェクトとモーションについて述べたいと思います。これらの組み合わせを理解することで編集の幅が一気に広がります。これらを使いこなせることが初心者から中級者にステップアップする壁の一つかなと考えています。
テキストオブジェクトとは
テキストオブジェクトは、文章の構造的な単位を表す概念です。単語(word)、文(sentence)、段落(paragraph)、括弧で囲まれた範囲など、意味のあるまとまりを一つの単位として扱えます。
テキストオブジェクトはi(inner)とa(around)という修飾子と組み合わせて使います。
iw:inner word(単語の内側、空白を含まない)aw:a word(単語全体、後続の空白を含む)i":ダブルクォート内のテキストa":ダブルクォートを含むテキストi):括弧内のテキストa):括弧を含むテキストオペレータとの組み合わせ
テキストオブジェクトは、オペレータ(d、c、yなど)と組み合わせることができます。
diw " delete inner word:カーソル下の単語を削除
ci" " change inner ":ダブルクォート内を変更
yi( " yank inner (:括弧内をyank
da{ " delete a {:波括弧とその中身を削除例えば、const message = "Hello, World!";というコード内の文字列を変更したい場合、文字列上にカーソルを置いてci"と入力すれば、一発で文字列の中身だけを削除して挿入モードに入れます。
これは余談ですが、Treesitterなどを用いることによって構文解析の結果が必要になる関数やクラスといったまとまりをテキストオブジェクトとして扱えるようになるプラグインが公開されています。vimとneovimのどちらを使っているかによって適したプラグインがあるので、興味のある人はぜひ探してみてください。
モーションの活用
モーションは移動コマンドですが、オペレータと組み合わせることで範囲指定としても機能します。
d$ " delete to end of line:行末まで削除
c0 " change to beginning of line:行頭まで変更
yt, " yank till ,:カンマの直前までyank
df) " delete find ):)を含めてそこまで削除t(till)とf(find)の違いは、対象文字を含むか含まないかです。tは直前まで、fは対象を含みます。また、後方検索を行う場合は T , F が使えます。
例えば、以下のような行があるとします(|はカーソル位置)
const result = calculate(x, y, z);
|それぞれのコマンドの挙動は以下の通りです。
f( " 次の ( まで移動((の上にカーソル)
" → const result = calculate(|x, y, z);
t( " 次の ( の直前まで移動
" → const result = calculate|(x, y, z);
F= " 前の = まで後方移動(=の上にカーソル)
" → const result =| calculate(x, y, z);
T= " 前の = の直後まで後方移動
" → const result = |calculate(x, y, z);さらに便利なのが、 ; と , による繰り返しです。
// 例:カンマで区切られた引数を一つずつ削除したい
calculate(x, y, z, w);
|
df, " 最初のカンマまで削除 → calculate(y, z, w);
d; " 次のカンマまで削除 → calculate(z, w);
d; " さらに次のカンマまで削除 → calculate(w);t と f を使った移動が習慣化できれば、個人的には中級者と言えると思います。vimの特徴は思考のスピードで編集できることであり、狙った位置にカーソルを瞬時に移動させるテクニックは必要不可欠です。このカーソル移動を補助するプラグインは多く存在するため、そういったプラグインを入れることで習慣化のサポートにもなるでしょう。
テキストオブジェクトとオペレータ・モーションを組み合わせることで、「この範囲を削除したい」「ここからここまでをコピーしたい」という操作が、視覚的な範囲選択なしに直接表現できるようになります。
素の状態で使う
vimを使い始めると、多くの人が「おすすめの設定」や「必須プラグイン」を検索し、それらを片っ端から.vimrcに追加していきます。私も同じでした。動画や記事で「これは便利!」と紹介されている設定を見つけては、見様見真似で追加していました。しかし、ある程度慣れてきたら、一度すべてを捨てて素の状態で使ってみることを強くおすすめします。個人的にもvim理解を深める上で、最も重要な経験の一つでした。
なぜ素の状態で使うのか
プラグインや設定に最初から頼り切っていると、「vimそのものができること」と「プラグインが提供する機能」の境界が曖昧になります。vimのテキスト編集に特化した機能に着目できず、独特なキーマップがあるIDEとしてしか使えていない自覚がありました。素の状態で使うことで、テキスト編集のために研ぎ澄まされた状態のvimを使えます。加えて以下のことが明確になります。
デフォルト機能でできること
vimには、プラグインなしでも驚くほど多くの機能が備わっています。grepや補完だけでなく、ファイラー機能もデフォルトで備わっています。専用のファイラープラグインやファジーファインダーがなくても、十分にテキスト編集ができます。
実践のすすめ
個人的には、最初は他の人の設定を真似してvimそのものに慣れていき、ある程度慣れてきたら素の状態で使うという流れが理想的かなと思います。たとえば、以下のようなアプローチがおすすめです。
.vimrcをバックアップして、空の状態から始めるこの過程で、「便利だと思っていたけど、実はなくても困らない」設定や、「デフォルト機能で代替できる」プラグインが多数見つかるはずです。素のvimを使うことで単なる軽量IDEとしてではなく、テキスト編集のツールとしてのvimの思想を実践できるトレーニングになると考えています。すべてのプラグインを捨てろという話ではありません。昨今の開発において、プラグインの利便性は必要不可欠です。重要なのは、vimの思想に触れた上で「何ができて何ができないのか」を理解し、必要なものを選択していくことです。
おわりに
この記事では詳細なテクニックに着目することは極力避けるようにしましたが、他にも以下のようなトピックがあると思います。これらはPractical vimでも取り上げれている内容なので、ご自身で深めていってほしいと思います。
vimは初学者にとってのハードルが高く、その習得は一朝一夕にはいきません。私自身、ここで紹介した内容を理解し、身につけるまでにはかなりの時間がかかりました。ですが一つずつ理解を深めていくことで、自分の中でvimは単なるテキストエディタから思考をそのまま反映するためのツールへと変わっていきました。
重要なのは、機能を暗記することではなく、vimの思想をを理解することだと思います。テキストを構造として捉えること、編集単位を小さくすること、そしてそれらを組み合わせること―これらの考え方を身につければ、個々の機能は自然と使えるようになると思います。まずは『Practical Vim』を手に取り、気になったところから一つずつ実践してみてください。そして、時には素の状態で使い、vimのコアと向き合ってみてください。きっと新しい発見があるはずです。思考そのままをエディタに反映できる感覚は一度手にするとなかなか手放せなくなるものだと思います。
この記事が少しでもvimを使ってみたいと考えている人の助けになれれば、こんなに嬉しいことはありません。