VSCodeで始めるVim

__※本記事で言う「Vim」とは「Vimキーマップ」のことです。__

# Vim、使ってますか？

Vimって使ったことのない人からすると何がいいのかよくわからないですよね。特に「移動はhjklで行う」あたりが最高に意味不明でした。
私もつい最近まではなんで皆vimにこだわるんだと思っていた口です。別に無くてもいいじゃないかと。
しかし、物は試しということで1週間ほど使ってみたら……びっくりするほど手に馴染みました。
まだ2か月程度しかVimを使っていない[小学生](https://qiita.com/hachi8833/items/7beeee825c11f7437f54)ですが、それでも以前と変わらない速度で編集できています。また、マウスやカーソルキーに手を伸ばす機会が減り、他のマウス必須な操作をキーボードで行えるようにカスタマイズするきっかけにもなりました。
そんなわけでVimが思ったより良かったこと、そしてVim入門にはVSCodeが向いているんじゃないかと感じたことから、何番煎じかわからないですがこの記事を書いています。

## Vimプラグインの導入

[まずはVimのプラグインを導入しましょう](http://aka.ms/vscodevim)。これが無ければ始まりません。
プラグインが導入できたら、何も言わずに`settings.json`を開いて以下の項目を追加してください。

```json:settings.json
  "vim.insertModeKeyBindings": [
      {
          "before": ["j", "j"],
          "after": ["<Esc>"]
      }
  ],

  "vim.hlsearch": true
```

個人的に上記2つの設定は必須だと思っています。特に`jj`。

## Vimの基本

### モード

Vimには`モード`と呼ばれる概念があります。とりあえず下記の4つがあるということだけ覚えておいてください。

- 通常モード
- 挿入モード
- ビジュアルモード
- コマンドモード

### 基本のキ

ごく基本的な操作からです。

#### カーソル移動の基本

| コマンド | 説明 |
|:-:|---|
| h | 左にカーソル移動 |
| j | 下にカーソル移動 |
| k | 上にカーソル移動 |
| l | 右にカーソル移動 |

出ました。Vimをキモいと言わしめる最初にして最大の難関。
ですがこれ、__最初は無理に覚えなくていいです__。カーソルキーに慣れている人は最初はカーソルキーぽちぽちの方が早いでしょうし。
なぜ覚えなくていいかというと、__すぐ覚えたくなるから__ です。Vimは移動系のキーマップが頭おかしくなるくらい存在するので、ホームポジションからほとんど手を動かさずにあっちこっちへ移動できます。Vimの移動に慣れ始めるとすぐにカーソルキーなんて遠いものを使うのが馬鹿馬鹿しくなります。いやホントに。

#### 挿入モードの基本

| コマンド | 説明 |
|:-:|---|
| i | カーソルの左から挿入モードへ |
| a | カーソルの右から挿入モードへ |
| I | 行の先頭から挿入モードへ |
| A | 行の終端から挿入モードへ |
| Esc | 通常モードへ戻る |
| Ctrl-c | 通常モードへ戻る |

挿入モードは普段見慣れたテキスト編集だと思ってください。通常モードではカーソルは常に文字を選択しているため、右か左かを選ぶ必要があります。最初は`i`と`a`の使い分けが厄介ですが慣れましょう。
Vimはモードがわかりにくいとよく聞きます。VScodeのプラグインでは画面下部にモードが表示されているので、困ったら画面下を見ればいいのですが、それでもよくわからなければ`Esc`連打で通常モードへ戻れます。

挿入モードから通常モードにもどるには`Esc`か`Ctrl-c`をコマンドする、若干押しにくいです。嫌ですね。
でも大丈夫、この記事通りに進んでいるなら __`jj`で挿入モードから通常モードに戻れます__。`settings.json`でキーバインドを追加しましたから。
__通常モードで移動、編集したい場所にたどり着いたら挿入モードへ、編集が終わったら通常モードへ__、という流れがVimの基本のようなので慣れていきましょう。

#### 編集の基本

| コマンド | 説明 |
|:-:|---|
| u | アンドゥ |
| Ctrl-r | リドゥ |
| x | 一文字削除 |
| dd | 一行削除 |
| yy | 一行コピー |
| p | カーソルの右(下)に貼り付け |
| P | カーソルの左(上)に貼り付け |

アンドゥとリドゥが無ければ生きていけない。
`dd`と`yy`はよく使います。なお、__ここでコピーしたものはクリップボードではなくレジスタに登録されます__。加えて、__削除したものはすべてレジスタに登録される__ ので、一行コピー → 一行削除 → 貼り付け のように操作すると、削除した行が挿入されるので注意してください。

なお、Vimでは`Ctrl-c`も`Ctrl-v`もキーバインドされているので、コピーペーストがしたければ`Ctrl-Insert`、`Shift-Insert`の利用をお勧めします。

#### コマンドの基本

| コマンド | 説明 |
|:-:|---|
| :q | ファイルを閉じる |
| :q! | 保存せずに閉じる |
| :w | 上書き |
| :w! | 強制的に上書き |
| :wq | 上書きして閉じる |
| :wq! | 強制的に上書きして閉じる |

頭に`:`を付けるとコマンドモードになります。抜けたいときは挿入モードと同じく`Esc`、もしくは`Ctrl-c`ですね。`jj`は登録していないので使えません。
`!`を付けると問答無用で実行します。

### 基本のホ

これまでのコマンドだけでは「ただ面倒になっただけじゃねーか！」と言われそうですね。ですが、面白いコマンドはこれからですよ。

#### 横移動いろいろ

| コマンド | 説明 |
|:-:|---|
| w | 次の単語の頭へジャンプ |
| e | 次の単語の末尾へジャンプ |
| b | 前の単語の頭へジャンプ |
| ge | 前の単語の末尾へジャンプ |
| W | 記号を無視して次の単語の頭へジャンプ |
| E | 記号を無視して次の単語の末尾へジャンプ |
| B | 記号を無視して前の単語の頭へジャンプ |
| gE | 記号を無視して前の単語の末尾へジャンプ |

単語ジャンプです。ポンポン横移動できるのでカーソルキーをポチポチするより断然早いです。
大文字になると記号を無視します。記号を多く含む行の場合はサクッとジャンプして微調整が便利ですね。

| コマンド | 説明 |
|:-:|---|
| f{文字} | 右方向で最初の{文字}にジャンプ |
| t{文字} | 右方向で最初の{文字}の手前にジャンプ |
| F{文字} | 左方向で最初の{文字}にジャンプ |
| T{文字} | 左方向で最初の{文字}の手前にジャンプ |

今度は文字ジャンプですね。単語のど真ん中に移動したいとき等に便利です。
大文字になると逆方向になります。Vimは大文字になると大げさになるか逆の効果になるコマンドが多いそうです。

| コマンド | 説明 |
|:-:|---|
| 0 | 行の先頭へジャンプ |
| ^ | 空白を除く行の先頭へジャンプ |
| $ | 行の末尾へジャンプ |

行の先頭と末尾へのジャンプですね。`$`が押しにくく感じるかもしれませんが、文末へ移動して編集を行う場合は`A`を使えばいいので、あまり使う機会はありません。

#### 縦移動いろいろ

| コマンド | 説明 |
|:-:|---|
| Ctrl-u | 上に画面半分だけ移動 |
| Ctrl-d | 下に画面半分だけ移動 |
| {数字}G | ｛数字｝行へ移動 |
| gg | ファイルの始端まで移動 |
| G | ファイルの末端まで移動 |

ここからは縦移動です。
`Ctrl-u`と`Ctrl-d`は画面を見ながらガッツリ移動したいときに便利ですね。これとは別に1画面分移動する`Ctrl-f`、`Ctrl-b`コマンドもありますが、VScodeの検索コマンドと被っていることと、移動が速すぎて扱いにくく感じるので載せていません。
`g`移動もよく使います。最近のエディターやIDEには行番号表示がデフォルトでついているかと思いますが、VScodeも例に漏れずついているのでガッツリ利用してやりましょう。

| コマンド | 説明 |
|:-:|---|
| H | 画面に表示されている一番上の行へ移動 |
| M | 画面に表示されている中央の行へ移動 |
| L | 画面に表示されている一番下の行へ移動 |

画面を見ながらパッと移動するのに便利です。他のコマンドで不便ながらも代用できるときが多いので、なかなか覚えられないのですが……

#### ビジュアルモードの操作

| コマンド | 説明 |
|:-:|---|
| v | ビジュアルモードへ/通常モードへ |
| V | カーソル行を全選択してビジュアルモードへ |
| （ビジュアルモードで）d | 選択範囲を削除して通常モードへ |
| （ビジュアルモードで）c | 選択範囲を削除して挿入モードへ |
| （ビジュアルモードで）y | 選択範囲をコピーして通常モードへ |

ビジュアルモードでは特定の範囲を選択し、様々な処理を行うことができます。
ファイル全体を選択したい場合は`ggVG`です。`Ctrl-a`もキーバインドされているため、よくお世話になるので覚えてしまいましょう。

#### 便利な編集コマンド

| コマンド | 説明 |
|:-:|---|
| o | カーソルの下に空行を挿入して挿入モードへ |
| O | カーソル行に空行を挿入して挿入モードへ |
| s | カーソルの下の文字を削除して挿入モードへ |
| S | カーソル行を削除して挿入モードへ |
| D | カーソルから右側を削除 |
| C | カーソルから右側を削除して挿入モードへ |
| ci" | カーソルがいる""の中身を削除して挿入モードへ |
| cw | カーソルの下の文字から次の単語の手前まで削除して挿入モードへ |
| r{文字} | カーソルの下の文字を書き換え |

どれもめっちゃ使います。
`o`、`O`はカーソルが行のどこにいても空行を挿入してくれます。VScodeなら`Ctrl-Enter`でカーソル行の下に空行を挿入できるため、挿入モードに入りたいかどうかで使い分けています。
`ci"`はとても便利です。`ci"`だけでなく、`ci'`、`ci<`、`ci{`、`ci(`、`ci[`とコマンドすればそれぞれ対応した範囲で削除してくれます。無ければ生きていけない。
ちなみに`cit`でタグの中身を削除してくれます。HTMLやXMLの編集をするときに重宝します。

#### 繰り返しコマンド

| コマンド | 説明 |
|:-:|---|
| {数字}{コマンド} | {コマンド}を{数字}回繰り返す |
| . | 直前の編集系操作を繰り返す |
| ; | 直前の検索系操作を繰り返す |

繰り返しですね。これもめっちゃ使います。
コマンドの頭に数字を付けると繰り返しになります。例えばこんな感じ。

- 5dd …… 5行削除
- 22j …… 22行下へ移動
- 3w …… 3つ先の単語の頭にジャンプ

`.`と`;`はどちらも繰り返しですが、繰り返す対象のコマンドが異なります。どっちのコマンドが何を繰り返すのかよくわかっていませんが、キー一発で繰り返してくれるので便利ですね。

#### 可視領域の操作

| コマンド | 説明 |
|:-:|---|
| zt | カーソル行が画面最上部になるようにスクロール |
| zz | カーソル行が画面中央になるようにスクロール |
| zb | カーソル行が画面最下部になるようにスクロール |
| Ctrl-y | 画面を下方向にスクロール |
| Ctrl-e | 画面を上方向にスクロール |

カーソルを動かさずに見える範囲を変えるコマンドです。個人的にzzはよく使います。

#### 文字列検索

| コマンド | 説明 |
|:-:|---|
| /{文字列} | {文字列}の検索 |
| * | カーソルの下の文字列で検索 |
| n | 次の検索結果へ |
| N | 前の検索結果へ |
| :noh | 検索ハイライトを消す |

検索機能です。正規表現検索が可能なので、うまく使うと便利になると思います。VScodeの検索機能も便利だと思うので、使い分けるといいかもしれません。

### 基本のン

ここからはVimコマンドの雑な理解を紹介していきます。

#### 削除、修正、コピー、選択

一部のコマンドは`{編集コマンド}{移動コマンド}`という規則性を持ちます。このコマンドでは、カーソルの位置から{移動コマンド}での移動先まで{編集コマンド}を実行します。
削除の`d`、修正の`c`、コピーの`y`、選択の`v`と覚えましょう。例えばこんな感じです。

- d5G …… カーソル行から5行目まで削除
- c0 …… カーソル位置から行の先頭まで削除して挿入モードへ
- yfX …… カーソル位置から`X`までの文字列をコピー
- vG …… カーソル位置からファイル終端まで選択してビジュアルモードへ

この4種類のコマンドについて、他にも一部のコマンドで互換性があるようです。
例えば`ci"`は`カーソルがいる""の中身を削除して編集`というコマンドですが、以下の通りに応用が利きます。

| コマンド | 説明 |
|:-:|---|
| di" | ""の中身を削除 |
| ci" | ""の中身を削除して編集 |
| yi" | ""の中身をコピー |
| vi" | ""の中身を選択してビジュアルモードへ |

`オペレータ`と`モーション`の組み合わせがコマンドの基本らしく、ここで行っていることも同じのようです。詳しい仕組みについては把握していないのでここでは説明しません。

#### 一括編集

| コマンド | 説明 |
|:-:|---|
| Ctrl-v | 矩形選択 |
| (矩形選択状態で）I | 選択範囲の左側から一括編集 |
| (矩形選択状態で）A | 選択範囲の右側から一括編集 |
| (矩形選択状態で）s | 選択範囲を削除して一括編集 |
| :%s/{置換前の文字列}/{置換後の文字列}/g | ファイル内の文字列を一括置換 |

Vimには矩形（くけい）選択があります。複数行をまとめてコメントアウト……は`Ctrl-/`で行えますが、同じ編集を複数行に行いたい場合は便利です。
置換機能についてはVScodeの検索からでも行えるので、好みで利用するといいかと思います。Vimではもっと柔軟な置換が行えるようですが、長くなるためここでは載せません。

#### コマンドいろいろ

ここでは分類しにくいコマンドを紹介します。

`<`、`>`はインデントです。`<<`でカーソル行を左にインデントする、といった使い方をします。
もちろん、ビジュアルモードで選択していれば選択範囲をすべてインデントしてくれます。

VScodeなら補完候補が出てくると思いますが、`Ctrl-n`で下の候補へ、`Ctrl-P`で上の候補へ移動できます。無ければ生きていけない。
なお、VScodeでは`Ctrl-n`が新規タブを開くキーバインドと重複していたと思うので、利用したい場合はどちらかのキーバインドを変更しましょう。

`q{a~z}`でコマンドの記録ができます。記録を止めるには`q`、実行するには`@{a~z}`です。
同じ処理を数か所に行いたい場合は`qa`で記録を始め、コマンドを一通り行い、`q`で記録終了、次の編集箇所まで移動してから`@a`といった形で利用します。

カーソル下の数字を`Ctrl-a`でインクリメント、`Ctrl-x`でデクリメントできます。あんまり使う機会はないですが、数字が増えたり減ったりする様子を見るのは楽しいです。
不要な人は`Ctrl-a`のキーバインドを解除して全選択が行えるようにした方がいいかもしれません。

挿入モードで`Ctrl-x, Ctrl-l`をコマンドすると行補完ができます。単語の補完候補と違って`Ctrl-n`で選べないので少々面倒ですが、調べれば多分キーバインドできると思います。多分。

## 参考

- [さっさと帰りたい怠け者エンジニアは vim をマスターしましょう](http://wolfbash.hateblo.jp/entry/2017/08/25/121711)
Vimの各種コマンドについて、覚え方も含めて説明してくれている非常にわかりやすい記事。ここに出会わなければいまだにVimを触ってなかったと思います。

- [Vim幼稚園からVim小学校へ](https://qiita.com/hachi8833/items/7beeee825c11f7437f54)
古い記事ですが、初心者がVimを始めるのに近い目線でコマンドの紹介がされているので、チラチラ見てると勉強になります。