Vimモード入門

# Vimモード入門

こんにちわ。
[ゴリラ.vim](https://gorillavim.connpass.com/)を運営しているゴリラです。

vimを初めて半年過ぎましたが、未だにvimの底がみえていないのでvimは沼ではなくブラックホールであることに気づきました。
道のりは遠いですが、楽しみながら旅していこうと思います。

さて、vimを初めて触る方は最初にモードがあることに戸惑う方が多くいるかと思います。
本記事は次のことについて触れていきます。

- モードによる恩恵はなにか
- モード一覧
- モードごとにできること

この記事を読み終わる頃にはきっとvimはなぜモードがあるのかを理解できると思います。
理解できなかったら、ぼくが面と向かって3時間語りますのでご連絡ください。

## モードによる恩恵はなにか
テキストエディタはモードレスが一般的かと思います。
ではvimはなぜモードがあるのでしょうか？

それは「操作性・機能性」の幅が広がるからとぼくは考えています。

Windowsのメモ帳では`A~Z0~9`や`/@`といった記号や文字はそのまま入力でき、`Ctrl+C`で文字列コピー、`Ctrl+S`でファイル保存を行います。

対してvimでは入力モードでは文字列の入力、ノーマルモードでは`h,j,k,l`でカーソル移動、`y`で文字列ヤンク[^1]、`dw`で単語の削除を行います。
モードがあることより同じキーが全く異なる動きをします。

そう、これがモードがもたらす恩恵です。

[^1]: コピーすることを指す

## モード一覧
vimでは以下のモードがあり、それぞれのモードでできることは大まか次の表になります。

| モード               | 機能                                         |
|----------------------|----------------------------------------------|
| ノーマルモード       | カーソル移動、ヤンク、プット[^2]、削除、など |
| 入力モード           | 文字入力、プットなど                         |
| ビジュアルモード     | 範囲選択、選択範囲のヤンク、削除など         |
| コマンドラインモード | 変更の保存、vim終了、文字列置換など          |

[^2]: 貼り付けのことを指す

他にオペレーター待機モード、端末ジョブモード、選択モードがありますが、
こちらに関しては別の機会にご紹介します。

## モードの切り替え方
vimでは基本的にモードを切り替えながら編集します。
次がモードの移行方法です。

| 現在のモード   | 移行先モード   | キー                         |
|----------------|----------------|------------------------------|
| ノーマル       | 入力           | `i`、`I`、`a`、`A`、`s`、`S` |
| ノーマル       | コマンドライン | `:`                          |
| ノーマル       | ビジュアル     | `v`、`V`、`ctr-v`            |
| 入力           | ノーマル       | `esc`、`ctrl-c`              |
| コマンドライン | ノーマル       | `esc`、`ctrl-c`              |
| ビジュアル     | ノーマル       | `esc`、`ctrl-c`              |

モード移行キーがいくつかありますが、違いについては[ノーマルモード](#ノーマルモード)で説明します。

## モードごとにできること
それぞれのモードでできることを一部ピックアップしてご紹介します。

### ノーマルモード
| コマンド | 操作                                                   |
|----------|--------------------------------------------------------|
| `h`      | カーソルを左に移動                                     |
| `j`      | カーソルを下に移動                                     |
| `k`      | カーソルを上に移動                                     |
| `l`      | カーソルを右に移動                                     |
| `yy`     | 行ヤンク                                               |
| `Y`      | 行ヤンク                                               |
| `dd`     | 行削除                                                 |
| `D`      | 現在のカーソルから行末まで削除                         |
| `p`      | カーソルの後にプット                                   |
| `P`      | カーソルの前にプット                                   |
| `c`      | 削除して入力モードに移行                               |
| `C`      | 現在のカーソルから後ろをすべて削除して入力モードに移行 |
| `w`      | 次の単語の先頭に移動                                   |
| `W`      | 空白と改行で区切られた次の単語の先頭に移動             |
| `e`      | 単語の末尾に移動                                       |
| `E`      | 空白と改行で区切られた単語の最後尾に移動               |
| `b`      | 前の単語移動                                           |
| `B`      | 空白と改行で区切られた前の単語に移動                   |
| `ZZ`     | 保存してvimを終了する                                  |

モード移行のコマンドは次になります。

| コマンド | 操作                                                   |
|----------|--------------------------------------------------------|
| `s`      | カーソル上の文字削除して入力モードに移行               |
| `S`      | 行を削除して入力モードに移行                           |
| `i`      | 入力モードに移行                                       |
| `I`      | カーソルを行先頭に移動して入力モードに移行             |
| `a`      | カーソルの後ろに移動して入力モードに移行               |
| `A`      | カーソルを行末尾に移動して入力モードに移行             |
| `v`      | 文字単位ビジュアルモードに移行                         |
| `V`      | 行単位ビジュアルモードに移行                           |
| `Ctrl-v` | 矩形ビジュアルモードに移行                             |

ノーマルモードでは表通りの操作が可能ですが、その中で`y`、`d`、`c`はオペレーターコマンド、`h`、`j`、`k`、`l`、`w`、`W`、`b`、`B`はモーションコマンドと呼ばれています。

モーションコマンドは範囲を指すため、オペレーターコマンドの後にモーションコマンドを続けて入力することでオペレーターの操作がその範囲に適用されます。

つまり、`dw`で単語を削除、`cw`で単語を削除して入力モードに移行る事ができます。

範囲を示すコマンドはモーション以外にテキストオブジェクトがあります。
一般的によく使うと思われるテキストオブジェクトは次の表になります。

| テキストオブジェクト | 範囲                 |
|----------------------|----------------------|
| `iw`                 | 単語                 |
| `aw`                 | 前後の空白を含む単語 |
| `is`                 | 文                   |
| `as`                 | 後の空白を含む文     |
| `ip`                 | 段落                 |
| `ap`                 | 改行を含む段落       |
| `ib`                 | ()の内部             |
| `ab`                 | ()と内部を含む       |

表以外のテキストオブジェクトは[こちら](https://vim-jp.org/vimdoc-ja/motion.html#text-objects)を参照してください。

この通り、vimではテキストオブジェクト・モーション・オペレーターを駆使することでテキストの高速編集を実現しています。
ここから楽しくなるので、初学者の方はまずこれらに慣れることをおすすめします。

### 入力モード
一部をご紹介します。
他に何ができるか気になる方は[Vimのインサートモードでできること](https://gorilla.netlify.com/articles/20190123-vim-insert.html)をぜひ読んでみてください。
gif付きでわかりやすく説明しています。

| キー                      | 操作                                 |
|---------------------------|--------------------------------------|
| `esc`                     | ノーマルモードに移行                 |
| `Ctrl-c`                  | ノーマルモードに移行[^3]             |
| `Ctrl-y`                  | 上の行のカーソルの位置の文字を挿入   |
| `Ctrl-e`                  | 下の行のカーソルの位置の文字を挿入   |
| `Ctrl-t`                  | 1タブ入力                            |
| `Ctrl-d`                  | 1タブ削除                            |
| `Ctrl-g` `j`              | 下の行に移動                         |
| `Ctrl-g` `k`              | 上の行に移動                         |
| `Ctrl-h`                  | 1文字削除                            |
| `Ctrl-r` `{0-9a-z"%#*:=}` | 指定したレジスタ[^4]をプット         |
| `Ctrl-x` `Ctrl-n`         | 開いているファイルないにある単語補完 |

[^3]: `esc`と同等ではないと[h_eastさん](https://twitter.com/h_east?s=17)より指摘をいただきました。詳細は[こちらのコメント](http://neko-mac.blogspot.com/2016/07/vimvim.html?showComment=1481768895634#c2524567742061789023)を参照してください。
[^4]: ヤンクしたデータが保存されている領域のこと

### ビジュアルモード

| キー | 操作                                                   |
|------|--------------------------------------------------------|
| `y`  | 選択した範囲をヤンク                                   |
| `d`  | 選択した範囲を削除                                     |
| `c`  | 選択した範囲を削除して入力モードに移行                 |
| `=`  | 選択した範囲を整形する                                 |
| `>`  | 選択した範囲を1タブ右に移動                            |
| `<`  | 選択した範囲を1タグ右に移動                            |
| `I`  | 矩形選択の時、選択範囲のすべての行先頭にテキストを入力 |
| `J`  | 選択した範囲をすべて連結する                           |
| `o`  | 選択した範囲の先頭または末尾にカーソルを移動           |

もっと詳しく知りたい方は[マニュアル](https://vim-jp.org/vimdoc-ja/visual.html)を参照してみてください。

### コマンドラインモード
こちらの[Vimのコマンドラインモードでできること](https://gorilla.netlify.com/articles/20190422-vim-cmdline.html)にまとめてありますので、ぜひ読んでみてください。

## 最後に
みなさん、なぜvimにはモードがあるのか理解できましたか？

本記事で紹介した内容はほんの一部をでしかなくて、他にもできることがたくさんあります。
ぜひ日本語マニュアルや他の方の記事を読んでみてください。

また、ぼくが運営しているゴリラ.vimではvimmerがたくさん集まっています。
一人ではなかなか知ることのできない知見がゴリラ.vimにあります。

では、よいvimライフを〜