ノーマルモードについて学ぼう 〜 Vimはいいぞ!ゴリラと学ぶVim講座(2)

こんにちは。
ゴリラ.vimを運営しているゴリラです。

前回の記事でVimのモードの概要と基本操作のことについて解説しました。本記事では基本操作から更に一歩踏み込んでノーマルモードでどんなことができるのかについて解説します。ノーマルモードだけでも機能が多いため、その他のモードについては別記事にて解説していきます。すこし覚えることが多いですが、本記事でVimの良さをすこし感じ取って頂けると思いますので、ぜひ最後まで読んでみてください。

ノーマルモード

このモードの一番の強みはテキスト編集に特化した機能がたくさんあることです。前回の連載でも少し触れたオペレーター、モーション、テキストオブジェクト、リピート以外にもカウントという機能もあります。本記事は改めてこれらについて解説していきます。

カウント

Vimはypなどのコマンドを指定した回数分を繰り返し実行するカウントがあります。例えば5pの場合、ヤンクした内容を5回プットする操作になります。これはpppppと同様の動きになります。カウントを指定しない場合は1回になります。

Yでヤンク、3pで3回プット

モーション

モーションはカーソル移動コマンドのことです。基本操作で解説したh j k l もモーションコマンドです。Vimのメリットの一つはこのモーションコマンドの豊富さにあります。一部を除き、モーションコマンドにカウントを前置することで、そのモーションコマンドを繰り返し実行することができます。例えば10jは10行下に、5lは5文字右に移動します。

少し多いですが、次のモーションコマンドを覚えておくと便利です。

モーション 説明
0 (ゼロ) 行頭に移動(空白文字も含む)
^ 行頭の非空白文字に移動
$ 行末に移動(カウントがある場合は[count]-1行)
g_ 行末の非空白文字に移動(カウントがある場合は[count]-1行)
f{char} 右に向かって[count]番目の{char}に移動
F{char} 左に向かって[count]番目の{char}に移動
t{char} 右に向かって[count]番目の{char}の1つ左の文字に移動
T{char} 左に向かって[count]番目の{char}の1つ右の文字に移動
; [count]回、最後のf、F、t、Tを繰り返す
, [count]回、最後のf、F、t、Tを反対方向に繰り返す
G [count]行目の最初の非空白文字に移動、カウントを指定しないときはファイルの最終行に移動
gg [count]行目の最初の非空白文字に移動、カウントを指定しないときはファイルの先頭に移動
w 次の[count]個目のword(*1)の先頭に移動
W 次の[count]個目のWORD(*2)の先頭に移動
b 前の[count]個目のwordの先頭に移動
B 前の[count]個目のWORDの先頭に移動
e [count]個目のwordの末尾に移動
E [count]個目のWORDの末尾に移動
} 次の[count]個目の段落(*3)に移動
{ 前の[count]個目の段落に移動
% 対応する記号に移動(デフォルトは([{}])
[count]go ファイルの先頭から[count]バイト目に移動

*1: アルファベット、数字、アンダースコア、もしくは他の非空白文字で構成された単語
*2: 非空白文字で構成された単語
*3: 段落は空行の後から始まる

イメージし辛いものがあるかと思いますのでキャプチャを見てみましょう。

  • 行頭と行末に移動 ($, 0, g_, ^)
  • {char}に移動
    fs(右のsに移動)→;;(2回繰り返し)→,,(反対方向に2回繰り返し)→ft(右のtに移動)→;(繰り返し)→,(反対方向に繰り返し)
  • ファイル先頭と末尾と指定行に移動
    Ggg10G(10行目に移動)
  • 単語の移動 (w, b, W, B, e, E)
  • 段落の移動 (}, {)

紹介したモーションコマンド以外にもまだいくつかあります。慣れてきた方は次のヘルプをぜひ読んでみてください。

ヘルプ コマンド
左右の移動 :h left-right-motions
上下の移動 :h up-down-motions
単語単位での移動 :h word-motions
オブジェクト単位での移動 :h object-motions

オペレーター

オペレーターはydといった操作のコマンドになります。オペレーターコマンドはカウントとモーションコマンドと組み合わせることができます。例えば2ywは2つのwordをヤンク、2cWは2つのWORDを削除して挿入モードに切り替えになります。

次のオペレーターを覚えておくと便利です。

オペレーター 説明
y ヤンク
d 削除
c 変更(削除して、挿入モードに切り替え)
gU 大文字にする
gu 小文字にする
g~ 大文字/小文字を入れ替え
> 1インデント増やす
< 1インデント減らす
zf 折りたたみを作成

キャプチャを見てみましょう。

  • ヤンク、削除、変更
    y4j(5行ヤンク)→P(貼り付け)→d4j(5行削除)→c4j(5行削除して挿入モードへ)
  • 大文字、小文字切り替え
    gUw(単語を大文字に)→guW(単語を小文字に)→g~W(小文字単語を大文字に)→g~W(大文字単語を小文字に)
  • インデント
    >4j(5行を右へインデント)→<4j(5行を左へインデント)→>G(ファイル末尾まで右へインデント)
  • 折りたたみ
    3zfj(4行を折りたたみ)→zfG(ファイル末尾まで折りたたみ)

    折りたたみを開くには za、すべての折りたたみを開くにはznコマンドを使用します。

テキストオブジェクト

テキストオブジェクトはテキストを一つの意味のあるまとまりとして扱うことができます。例えばiwはホワイトスペース(スペース、タブ、改行のこと)を含まない一つのword、i(()で囲った中身を示しています。テキストオブジェクトはオペレーターもしくはビジュアルモードの後にのみ使用できますが、とても強力な機能です。少し種類が多いのですが、覚えておくと便利なテキストオブジェクトをピックアップして解説します。

テキストオブジェクト 説明
iw ホワイトスペースを含まないwordを選択
aw ホワイトスペースを含むwordを選択
ip 段落の内部(最後の改行を含まない)を選択
ap 段落を選択
i] [ ]ブロックの内部を選択
a] [ ]ブロックを選択
i) () ブロックの内部を選択
a) () ブロックを選択
i> <> ブロックの内部を選択
a> <> ブロックを選択
i" "" の内部を選択
a" "" を選択
i' '' の内部を選択
a' '' を選択
it html、xmlのタグの内部を選択
at html、xmlのタグを選択

量が多いですが、iは内部、aはブロックなどを含むというルールがあるのですぐに覚えられると思います。キャプチャを見てみましょう。

行っている操作は、i'(hello gorillaを選択)、a'('hello gorilla'を選択)、it(<p>...</p>の内部、つまりhello gorillaを選択)、at(<p>...</p>を選択)、ip(段落を選択(最後の改行を除く))、ap(段落を選択(最後の改行を含む))、です。なお、各々の選択前にvを押してビジュアルモードに移行し、選択後はESCを押してノーマルモードに戻っています。

リピート

.コマンドで最後の変更を繰り返すことができます。ここで指している変更とは、テキストを変更する操作のことになります。例えば、wordを削除するdiwコマンドを.だけで繰り返すことができます。ノーマルモード以外にも、挿入モードに入ってからノーマルモードに戻るまでの変更も繰り返すことができます。リピートを積極的に使用すると編集が早くなるので、使える場面では使っていきましょう。

diw(単語を削除)→.を連打して繰り返し削除
i(挿入モードに)→hello gorillaを挿入→ESC(ノーマルモードに)→.を連打して繰り返し挿入

その他

カウント、モーション、オペレーター、テキストオブジェクト、リピートについて解説しましたが、他にもいくつか覚えておくと便利なコマンドがあります。

コマンド 説明
u [count]個の変更を元に戻す(undo)
Ctrl-r undoされた変更を[count]個やり直す(redo)
Ctrl-u 画面半分上にスクロール
Ctrl-d 画面半分下にスクロール
Ctrl-o ジャンプリストの中の[count]個古いカーソル位置に移動
Ctrl-i ジャンプリストの中の[count]個新しいカーソル位置に移動
~ カーソル下の文字の大文字/小文字を切り替え
* カーソル下の単語を前方検索
n 最後の検索を[count]回繰り返す、*と組み合わせて使用すると便利
N 最後の検索を逆方向に[count]回繰り返す
D カーソル下から[count]-1行末まで削除
C カーソル下から[count]-1行末まで削除して、挿入モードに切り替え
S [count]行を削除して、挿入モードに切り替え
s カーソル下の[count]文字を削除して、挿入モードに切り替え
r{char} カーソル下の文字を{char]に置換
Ctrl+a カーソル下またはそれ以降の数値を[count]加算
Ctrl-x カーソル下またはそれ以降の数値を[count]減算
>> 現在行を1インデント増やす
<< 現在行を1インデント減らす
J Jで[count]行を空白を挟んで連結
gJ Jと基本は同じだが、空白を挿入しない

補足ですが、ジャンプリストというのはジャンプコマンドを使用して移動したときに記録されるカーソル位置の履歴です。G } %などがジャンプコマンドになります。

最後に

ノーマルモードだけで便利なコマンドがたくさんありますが、これらを使いこなせれば編集の効率が著しく向上すると筆者は考えています。たくさん使って、試して、自分の手癖と思考の癖に合うコマンドの組み合わせをぜひ見つけてみてください。

次回の記事では、その他のモードについて解説していきます。まだまだ便利な機能がたくさんあります。楽しみにして頂ければと思います。