Vim Adventuresを遊びながらVimの基礎(ノーマルモード中心)を学ぶ

今回は**Vimの操作方法**について、初心者向けに説明したいと思います。

・・・といっても、私も2週間前くらいからようやくVimを触り始めた身で、まだまだ学習中です。今回の記事では、同じような初心者の方に少しでも参考になるように、私がVimを学習する上で良教材であると感じた学習ツール**Vim Adventures**をベースに解説していきたいと思います。

Vim Adventuresの序盤から中盤に登場するVimコマンドを解説しながら、Vim操作の基礎も本記事で内容をさらっていきたいと思います。


# Vimとは

**vim**はCUIで動作可能なテキストエディタの一つです。
最大の特徴は、多数のコマンドを駆使することでマウスを使用せずにテキストを記述することができる点です。
文字の一括移動、検索、一括削除等々を全て英数字記号の組み合わせで実行するため、使いこなせればタイプ速度が向上します。
特に**英数字・記号を多用するコードの記述時**に真価を発揮します。

一方で、そのコマンドは果てしない種数が用意されており、学習がとっつきにくいツールではないかと思います。Vim日本語ドキュメントを読むと、これを見るとボリュームの厚さが伝わるのではないでしょうか。

# Vim Adventuresとは

筆者は、最初にこのツールを勉強しよう！と考えた時に、その難解さから、どうやって学習を進めよう・・・と悩みました。

いくつか教材(Vimtutor等)や初心者向け記事を漁っていたのですが、そんな中Vim Adventuresという学習ツールを現在私が通っているスクールで紹介されていたので試したところ、効果的に学習を進められそうと感じたので、本項で紹介したいと思います。

Vim Adventuresは、一言で説明すると、パズルRPG風のゲームでVimを学習できるツールです。



ドラクエ風マップ上でキャラクターを操作しながらパズルを解いていくのですが、上下左右の移動はなんと**Vim方式の `h` `j` `k` `l` キー**で操作！　
途中のパズルもVimのコマンドによって解いていきます。

![スクリーンショット 2023-09-13 1.24.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3534301/1caa12fe-6845-2284-54cd-70394d8b1073.png)
例えば、上記のパズル内容は、「*キーボードの入力数を10回以内で文章3箇所の文字を修正せよ*」というパズルです。
キーボードの入力10回以内となると、方向キーの使用のみでは達成はできないため、Vimコマンドをうまく活用する必要がありそうです。

このゲームではこのようなパズルを解くことによって先に進むことができます。
単純にvimを学習するよりも楽しみながら学べそうですね！

このゲームの最大の特徴は、**最初から全てのVimコマンドをゲーム上で使用することはできない**ということです。最初は`h` `j` `k` `l` キーから始まり、マップ上に落ちているアイテムを拾うことで徐々に使用できるVimコマンドが解放されていきます。

前述の通り、Vimはコマンド種類数が膨大であるため、いっぺんに覚えようとすると混乱してしまいます。
Vim Adventuresでは、ゲームを進めていくうちに(スキルを覚えていくように)徐々に使用するコマンドが解放されていくため、着実に覚えやすいです。

Vim Adventuresは**全13ステージ**が用意されています。
Stage3の途中からPaypalによる25ドルの課金が必要となります。

言語について現地点では日本語には対応しておりません。
とはいえ、ゲーム内に登場する英語はそこまで難しくはないため、多少慣れていれば大きな支障はないかと思います。


# Vim操作の基礎

さて、早速Vim Adventuresを触ってみる・・・前に、Vimを操作する上で最低限知っておきたい知識をまとめておきます。
こちらの内容はVim Adventuresを遊ぶだけでは理解しにくい内容であるため、本項でさらっと触れます。

### vimの起動方法

以下Macの環境でVimを起動する方法を説明します。

Vimは**ターミナル上**で起動可能です。まず、作業したいディレクトリにcd等で移動しておきましょう。

その上でvimと入力することでvimが起動します。

vimが起動するとこのような画面が出ます。

![スクリーンショット 2023-09-16 15.43.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3534301/869e451e-2b0e-347b-c919-35c0cfb7fa9b.png)

### vimのモードについて

vimは**モード**と呼ばれる概念があり、これを切り替えながら操作します。

以下4種類のモードを紹介します。

| モード | 用途 | モード変更方法 |
|:--|:--|:--|
|  ノーマルモード | カーソル移動、テキスト削除等  | 他のモード中に`esc`  |
| 挿入モード  | テキストの挿入  | `i`,`a` など |
| ビジュアルモード  | テキストの範囲選択  | `v` など  |
| コマンドラインモード  | ファイル操作・vim終了等  | `:(コロン)`キー  |


ノーマルモードの状態がVimの基本となり、何らかのコマンドを入力することで他の3種のモードに変更されます。他のモード中に`esc`を押すと再びノーマルモードに戻ります。

##### ノーマルモード
vimを起動すると、まずはこのモード設定から始まります。
この状態では多数のコマンドを使用することができます。
テキストの単語単位・行単位のカーソル移動・削除や、ワード検索を用いたカーソル移動など、通常はマウス操作等で文章を選択するところを文字(コマンド)入力のみで実行することができます。
そのため、いくつかのコマンドを習得すれば文字入力・編集の効率向上に繋がります。

**ノーマルモードのコマンドはVim AdventuresのStage1-10で多数習得ができるため、後述の項目にて詳しく紹介します！**


##### 挿入モード(Insert Mode)

挿入モードは、実際にテキストを編集することができます。

![スクリーンショット 2023-09-13 23.25.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3534301/41ad1b5c-48f0-d888-24ca-60f9d57dec62.png)
挿入モード中はこちらの画像のように、画面右下に-- INSERT --と表示されます。

ノーマルモード時に、
`i`を押すと現在のカーソル位置の一つ前から
`a`を現在のカーソル位置の一つ後から文章の挿入を開始します。
このモードでは一般的なテキストエディタのように、十字キー移動や`Backspace`による文字の削除が可能です。
Vimで文章編集を行う際は必ず使用するモードなので、早い段階で覚えておきましょう。

##### ビジュアルモード

コマンド`v`を入力するとビジュアルモードになります。この状態でカーソル移動すると、カーソルを起点に範囲選択を行うことができます。
そして選択した範囲を対象に、削除やコピー等のノーマルコマンドを実行することができます。

今回紹介するVim Adventuresの記事内容ではビジュアルモードの解説はありませんが、このモードも使用することが多いため、本記事でノーマルモードのコマンドを一通り解説したあと、最後に補足解説したいと思います。


##### コマンドラインモード

コマンドラインモードは`:`を入力することで開始します。

![スクリーンショット 2023-09-17 16.09.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3534301/8e92f419-f1e7-4d9c-2304-cb9ad1ca268d.png)
:を入力すると、上記画面のように、画面最下部の行に文字が入力できる状態になります。

以下、vim操作のために最低限覚えておきたいコマンドを紹介します。

| コマンド | 効果 |
|:--|:--|
| `:q` |  vimを終了 |
|  `:q!` |  vimを強制終了(**※**) |
|  `:w` |  vimファイルを上書き保存 |
|  `:w` + `(ファイル名)` |  (ファイル名)の名前をつけて保存 |
|  `:wq` | vimファイルを上書き保存してから終了  |
|  `:e` + `(ファイル名)`|  (ファイル名)を開く |

(**※**)保存せずに:qを実行すると以下のようなエラーが発生します。
![スクリーンショット 2023-09-17 15.45.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3534301/0f7444d2-fee7-8c5a-f37d-63e7decf1d7b.png)
`:q!`は、保存なしでvimを終了したい時に使用します。



また、`cd`や`ls`などのUNIXコマンドもコマンドラインモードで一部用意されております。


# Vim Adventuresでノーマルモードのコマンドを履修する

これで最低限Vimの起動・テキスト入力・保存・終了の部分はおさえることができました。
お待たせしました。ここからはVim Adventuresを遊びながら、Vimのノーマルモードのコマンドを学びたいと思います。
今回、Stage1-10に登場するコマンドをステージごとにまとめてみました。ゲームを遊びながら以下のコマンドを順番に覚えていきたいと思います。

:::note info
Vim Adventuresを遊ばずに本記事の内容を見た場合、コマンドを紹介する順番が種類別に完全にソートされているわけではないので、かえって理解しにくく感じるかも知れません。
実際にVim Adventuresを遊びながら、コマンド内容の振り返りとして本記事を見てもらえると幸いです。
:::

:::note info
とはいえ、ステージごとに完全に登場コマンドを分けると、解説の分類を行うのが難しいコマンドがあったため、紹介順が実際のゲームとは異なっているコマンドが一部あります。ご了承ください。
:::


### Level 1 十字移動
vimの基本的な１文字単位のカーソル移動は、H、J、K、Lキーで行います。

| コマンド | 効果 |
|:--|:--|
| `h` |  左移動(←) |
|  `j` |  下移動(↓) |
|  `k` |  上移動(↑) |
|  `l`  |  右移動(→) |


一応矢印キーでも同様の操作は可能ですが、英字キーによる操作を行うことで指を動かす範囲が狭くなるためタイピング速度が向上します。
十字ではなく一列に並んだキーボードで4方向の移動操作をするのは難しいですが、少しずつ慣れていきましょう。

### Level 2 単語単位の移動
１文字単位だけではなく、単語単位で移動することもできます。

| コマンド | 効果 |
|:--|:--|
| `w` |  次の単語の先頭へ移動 |
| `e` |  現在の単語の終端へ移動（単語の終端にカーソルがある場合は次の単語の終端へ移動） |
| `b` |  ひとつ前の単語の先頭へ移動 |


以上のコマンドは英数字・アンダーバー( _ )の連なりを1単語として認識しますが、このコマンドを大文字(`W`,`E`,`B`)で入力すると、アンダーバー以外の半角記号を含めた文字の連なりを1単語として認識します。

例えば、

**Auto-CAD**

この単語の「A」で小文字`e`キーを押すと「**o**」に移動しますが、
大文字`E`キーを使用した場合、Auto-CADを一つの単語とみなすため、「**D**」に移動します。


### Level 3,4 文字の削除・上書き
削除、上書きもノーマルモードで実行することができます。

| コマンド | 効果 |
|:--|:--|
| `x` |  カーソルが載っている場所の文字を削除 |
| `r` + (任意の文字) | 現在のカーソル上の１文字を(任意の文字)に上書き |


### Level 5 文字の一括削除

コマンド`d`によって文字を削除することができます。
この`d`は単体では使用せず、続けて他のコマンドを入力することによって使用することができます。
以下コマンド例です。

| コマンド | 効果 |
|:--|:--|
| `dw` |  次の単語の先頭まで一括削除 |
| `de` |  現在の単語の終端まで一括削除 |
| `db` |  ひとつ前の単語の先頭まで一括削除 |

以上のように、コマンド`d`にLevel 2 で紹介したコマンドを組み合わせることで、範囲指定した上で文字を一括削除することができます。
これは、Level 2で紹介した大文字のコマンド`W`,`E`,`B`にも対応しております。

さらに以下のコマンドにより、単語に関係なく1行、あるいは複数行をまとめて削除することができます。

| コマンド | 効果 |
|:--|:--|
| `dd` |  次の単語の先頭まで一括削除 |
| `dj` |  現在の単語の終端まで一括削除 |
| `dk` |  ひとつ前の単語の先頭まで一括削除 |


### Level 6 カーソルの一括移動

単語単位のカーソル移動だけではなく、一括でカーソル移動するコマンドは他にもあります。

| コマンド | 効果 |
|:--|:--|
| `$` |  現在のカーソルの行の終端に移動 |
| `0` |  現在のカーソルの文頭に移動 |

行単位の移動は頻繁に使いそうですね。`h` `j` `k` `l`キーの移動だけではなく、上記の一括移動にも早いうちに慣れておきたいところです。

以上のキーはLevel5で登場したコマンド`d`とも組み合わせることができます。

| コマンド | 効果 |
|:--|:--|
| `d$` |  現在のカーソルの位置より後の行の終端の文字まで削除する |
| `d0` |  現在のカーソルから文頭までの文字を削除する |


### Level 7-1 検索移動(その1)

同じ行の中で特定の文字まで移動したい場合は検索移動が便利です。

| コマンド | 効果 |
|:--|:--|
| `f` + `(任意の文字)` |  現在の行のうちカーソル以降の(任意の文字)に合致する最も近い箇所を検索し、その箇所に移動する |
| `F` + `(任意の文字)` |  現在の行のうちカーソル以前の(任意の文字)に合致する最も近い箇所を検索し、その箇所に移動する |
| `t` + `(任意の文字)` |  現在の行のうちカーソル以降の(任意の文字)に合致する最も近い箇所を検索し、その箇所の１文字前に移動する |
| `T` + `(任意の文字)`  |  現在の行のうちカーソル以前の(任意の文字)に合致する最も近い箇所を検索し、その箇所の１文字後に移動する |

一度上記の4種のコマンドを使用した後、以下のコマンドを使用することで、繰り返し検索移動を実行することもできます。

| コマンド | 効果 |
|:--|:--|
| `,` |  現在のカーソル以降にある、前回検索した文字に合致する最も近い箇所を検索し、その箇所に移動する |
| `;` |  現在のカーソル以前にある、前回検索した文字に合致する最も近い箇所を検索し、その箇所に移動する |

以上のコマンドは削除コマンドdとも組み合わせることができます。

`d` + `f`,`F`,`t`,`T` + `(任意の文字)` を実行することで、現在のカーソル位置から最も近い`(任意の文字)`までの範囲を一括で削除することが可能です。


### Level 7-2 画面移動

現在のカーソル位置を基準に、vimの画面範囲の移動もコマンドで操作することができます。

| コマンド | 効果 |
|:--|:--|
| `zt` |  現在のカーソル位置が最上部になるように画面移動する |
| `zz` |  現在のカーソル位置が中央になるように画面移動する |
| `zb` |  現在のカーソル位置が最下部になるように画面移動する |

`t`は**top**の**t**、`b`は**bottom**の**b**と考えると覚えやすいです。


### Level 7-3 文頭・文末一括移動

文章全体の一括移動をするときは`g`コマンドを使用します。

| コマンド | 効果 |
|:--|:--|
| `gg` |  文章全体の文頭にカーソルを移動する |
| `G` |  文章全体の文末にカーソルを移動する |

このコマンドは頻繁に活用しそうです。


### Level 7-4 カッコ()間のカーソル移動

カッコ間の一括カーソル移動は%コマンドで可能とします。

| コマンド | 効果 |
|:--|:--|
| `%` |  現在のカーソル位置以降の最も近いカッコの**対の位置**に移動する。カッコにカーソルを置いている場合は**対のカッコの位置**に移動する。 |

現在位置のカッコの対となる位置に移動ができるのがポイントです。このコマンドはコードを記述する際に重宝しそうです。


### Level 8 検索移動(その2)

Level 7-1で紹介したfやtのコマンドは同じ行内のみの検索移動でした。
本項で紹介する`*`や`#`を使用することで、単語を介した行間の検索移動も可能とします。

| コマンド | 効果 |
|:--|:--|
| `*` |  現在のカーソル位置の英単語と同じ単語を**前方向**に検索し単語先頭にカーソル移動する |
| `#` |  現在のカーソル位置の英単語と同じ単語を**後方向**に検索し単語先頭にカーソル移動する |

文章中に検索単語が複数ある場合、コマンドを実行するたびに近い順に検索移動し、一通り一周したらまた同じ位置に戻ってきます。

また、一度`*`や`#`のコマンドを実行した後、再度同じ単語で検索移動を行いたい場合、以下の2つのコマンドを使用します。

| コマンド | 効果 |
|:--|:--|
| `n` |  前回検索した単語を**前方向**に検索し単語先頭にカーソル移動する |
| `N` |  前回検索した単語を**後方向**に検索し単語先頭にカーソル移動する |

このコマンドの特徴は、文章中どの位置にカーソルがあっても、一度`*`や`#`で検索したワードの検索を行い移動ができることです。
上手く使いこなせれば、コード中の変数間で移動するなど便利な使い方ができます。


### Level 9 数字(count)の活用

vimはコマンドとして`0`~`9`の数字を使用することも可能です。(0単体はLevel 6 で紹介した通り行頭に移動するコマンドのため別です)

`(数字)` + `(任意のコマンド)`

と入力することで、`(任意のコマンド)`を`(数字)`回繰り返し実行することができます。

例えば、`3j` と入力すると、3文字分下へ移動します。
また、`4w` と入力すると、4単語先の文頭へ移動します。

そのほかにも、

`(数字)` + `dd` : 現在の位置より以下の行を`(数字)`の数だけ一括削除
`(数字)` + `$` : `(数字-1)`行下の終端に移動

・・・等々、コマンドの前に数字を挿入することで繰り返しコマンドを実行することができます。

このコマンドの使い方は、**Level1 ~ 8 で紹介したコマンド全般**に使用することができます。
まとめてコマンドを実行したいときに使用しましょう。

### Level 10-1 コピー(yank)・ペースト(put)

vimのコマンドにより**コピーペースト**を行うこともできます。

:::note info
なお、vimではコピーをヤンク(yank)、ペーストを(put)と表現します。
テキストデータをレジスタに**引っ張る(yank)**、レジスタのデータをテキスト中に**置く(put)**、という流れがあることからこのように表現する・・・らしいです。
:::

テキストのペースト(put)は`p`や`P`によって実行することができます。

| コマンド | 効果 |
|:--|:--|
| `p` |  カーソル前位置にレジスタの内容をペースト(put)する |
| `P` |  カーソル後位置にレジスタの内容をペースト(put)する |

Level 3-5で削除のコマンドを説明しましたが、実は正確にはただ削除しているのではなく、**削除したテキストはレジスタに格納されております。**
このレジスタの内容は`p`や`P`を実行することにより、ペースト(put)することができます。

つまり、d等のコマンドを使った後`p`を使用することでカット&ペーストができるということですね。

例えばコマンド　`3dw`　で、3単語分削除した後、テキスト中の別の場所でコマンド`p`を使用すると、削除した3単語をペースト(put)することができます。


また、テキストを削除せず、コピー(yank)を行う場合はyコマンドを使用します。

| コマンド | 効果 |
|:--|:--|
| `y` + `(移動系のコマンド)` | 現在のカーソル位置から`(移動系のコマンド)`の移動先までの範囲をyankする  |
| `yy`または`Y` |  現在のカーソル位置の行全体をyankする |

例えば、現在のカーソル位置から3単語先の末尾までyankしたい時は、y3eと入力します。
Level1 ~ 9に登場したコマンドを組み合わせることで、慣れは必要ですが、自由自在にyank範囲を指定することができます。

### Level 10-2 レジスタの取り扱いについて

通常のテキストのコピペでは1つしか情報を保持できませんが、vimはレジスタという記憶領域に複数のデータを保持することができます。

このレジスタの仕組みですが、ちゃんと説明しようとすると難しく奥深い内容のため、この話題だけで記事が1本書けてしまう内容です。。

本記事では最低限の内容だけ触れたいと思います。


vimで行単位の削除を行った時、削除した順に番号が1から振られてレジスタに格納されております。
この行単位のレジスタを呼び出してputするときは、
`"` + `(1 - 9のレジスタ)` + `p`(または`P`)
を使用します。
新たに行単位の削除を行うと、その行のレジスタが新たに1となり、一つ前に削除した行は2となります。
例えば、4回前に行削除したものをputするときは、`"5p`　とコマンド入力します。

レジスタは9まで用意されているため、これ以降のレジスタは自動削除されます。

なお、レジスタの0は、yankしたテキストが一つのみ保持されております。

このレジスタの内容は、vimのコマンドラインモードで:reg と入力することで、以下の画面のように一覧を閲覧することができます。レジスタ内容を確認したい時に使用します。

ほかにも、多数のレジスタの操作が用意されています。

以下の記事（≠筆者）はvimのレジスタに関して簡潔にわかりやすくまとめております。
ぜひ参考にしてください。

https://qiita.com/0829/items/0b3f63798b6910623efc



## (補足)　ビジュアルモードについて

vimのモードの説明で少しビジュアルモードに触れましたが、Vim Adventures Level1-10の内容では登場しないモードの割に、有用なモードであるため、最後に補足として解説します。
ビジュアルモード時にVim Adventures の Level 1-10で学んだコマンドを組み合わせることでテキストを色々編集することができます。

ビジュアルモードは前述の通りノーマルモード時にコマンド`v`で移行します。ビジュアルモード時は画面最下部に -- VISUAL -- と表示されます。また、この状態でカーソルを移動系コマンドで移動すると、テキストが網掛け状態になります。(下画像)

![スクリーンショット 2023-09-18 21.45.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3534301/8bcdc379-75c8-a65c-4d3c-30f659e31709.png)

この網掛けに対して、例えば
削除のコマンド`x`を実行すると網掛け範囲の削除、
yankのコマンド`y`を実行すると網掛け範囲のyankを行うことができます。


これらのコマンドはコマンドだけの組み合わせでも範囲実行が可能ですが、ビジュアルモードは名前の通り選択範囲が可視化されるので、ミスなく範囲選択することができます。



# まとめ

以上、Vim Adventures の Level 1-10で登場した内容を振り返ってみました。
実はVim Adventuresは　Level 11, 12も残ってはいるのですが(最終ステージはチャレンジステージ)、ボリュームが多大であるのとLevel 10までの内容で基礎は抑えられると判断し、この内容にさせていただきました。

Vim Adventuresは要所要所で難しい場面がありますが、Vim操作を覚えるツールとして良教材です。Vim初心者は試しに触ってみてはいかがでしょうか。