達人プログラマーへの一歩としてvimに熟達する

## サマリ

* vimを[達人プログラマー](https://www.ohmsha.co.jp/book/9784274226298/)でいう"熟達"に至るためのvimの操作方法を一覧にしてみました。
* 数あるエディタの中でvimは比較的使われる機会が多いと思ったため改めてまとめてみました。（今回紹介しているのはプラグインなしの素のvimです。）

## 想定読者

* vim初級者
* 達人プログラマーになりたい人

## vimに熟達しておくと良いと考えた理由

Linuxでなにかしらファイル編集をする機会がある方はvimを使ったことがある人は少なくないと思います。
また、たまに使うことになるため、vimをメインエディタにしていなくともインサートモードとビジュアルモードの違いやファイル保存方法などの基本を学んで最低限は使えるようにした人も少なくないと思います。

わたしもそうです。そして、いつも使っているエディタならもっと楽にやれるのにvimめんどくさ・・・などと若干のストレスをためつつ作業をしていました。

しかし、最近達人プログラマーの中の一節「Tips 27 エディターに熟達すること」を読んで、たしかに作業時間の面でも作業の質を高める面でもエディターを一定レベル以上使いこなせるようになることに価値をあると感じました。とくに、使う頻度が高いvimは高めておこうと思い、あらためてまとめてみました。

David Thomas（著）、Andrew Hunt（著）、村上雅章（翻訳）2020年11月21日 達人プログラマー（第2版）熟達に向けたあなたの旅　オーム社 P104

> 真のメリットは、エディターに熟達することで、編集の方法について意識しなくても済むようになることです。

vim程有名なエディターだとまとめは多くの方々がされていますが、この記事では熟達する域にいくまでの内容を自分でも把握できるようにしたかったため、改めてまとめてみました。

## なにができているとvimに熟達していると言えるのか？

vimに熟達しているとは何ができていると良いでしょうか？達人プログラマーは以下のことができれば、エディタに対して熟達しているとしています。

David Thomas（著）、Andrew Hunt（著）、村上雅章（翻訳）2020年11月21日 達人プログラマー（第2版）熟達に向けたあなたの旅　オーム社 P104

```text
・ テキストを編集する際、文字や単語、行、段落で移動や選択を行う。
・ コードを編集する際、さまざまな構文単位（対応する区切り文字や、関数、モジュール）で移動できる。
・ 変更作業以降にコードのインデントを付け直せる。
・ 単一コマンドで、コードブロックにコメントを付けたり外したりできる。
・ 変更のアンドゥとリドゥができる。
・ エディターのウィンドウを複数のパネルに分割し、それらの間で移動ができる。
・ 特定の行番号に移動する。
・ 選択した範囲の行を並び替える。
・ 文字列と正規表現の双方で検索し、以前の検索を繰り返す。
・ 選択範囲やマッチしたパターンに基づいてカーソルを複数生成し、それぞれをまとめて編集する。
・ 現在のプロジェクトで発生しているコンパイルエラーを表示させる。
・ 現在のプロジェクトにおけるテストを実行する。
```

というわけで、ここからはvimでそれぞれのことをやるには何ができればいいかを紹介していきます。

## vimでのファイル基本操作

メインのことに触れる前に基本についても軽く触れておきます。

まずvimでは4つのモードがあります。4つのモードの違いや切り替えについてはこちらの[Vimの4つのモードを使いこなす](https://zenn.dev/mo_ri_regen/articles/vim-four-modes)がわかりやすかったです。

それから基本操作は以下になります。

|操作分類|操作|入力|
|---|---|---|
|ファイル操作|ファイルを開く|:e {ファイル名}|
||ファイルを保存する|:w|
|文字列操作|1行コピーする|yy|
||選択*した範囲をコピーする|（ビジュアルモードで選択した状態で）y|
||1行切り取る|dd|
||選択*した範囲を切り取る|（ビジュアルモードで選択した状態で）d|
||貼り付ける|p|

*選択については[vimでの選択](#vimでの選択)を参照

## vimでテキストを編集する際、文字や単語、行、段落で移動や選択を行う

### vimでの移動

移動はデフォルトモードで操作します。移動については[【入門】Vimで高速で移動~プラグインなしでの移動まとめ~](https://qiita.com/takeharu/items/9d1c3577f8868f7b07b5))がわかりやすかったです。

|操作分類|操作|入力|
|---|---|---|
|文字単位で移動する|左に移動する|h|
||右に移動する|l|
|単語単位で移動する|次の単語に移動する|w|
||前の単語に移動する|b|
|行単位で移動する|上に移動する|k|
||下に移動する|j|
||行頭に移動する|^|
||行末に移動する|$|
|段落で移動する|段落ごとに上に移動する|{|
||段落ごとに下に移動する|}|

### vimでの選択

vimで範囲選択するときはデフォルトモードからビジュアルモードに切り替えます。ビジュアルモードは詳細を言うと3種類あり、文字、行、矩形の選択に応じて使い分けます。ビジュアルモードについては[いまさら聞けないVim（5）ビジュアルモードでテキストを選択し加工する](https://atmarkit.itmedia.co.jp/ait/articles/1106/15/news127.html)がわかりやすかったです。

#### 文字単位で選択

文字単位で選択するときはビジュアルモードで操作します。デフォルトモードからビジュアルモードへの切り替えは`v`を入力します。戻るときは`ESC`キーを入力します。

選択範囲を決めるためのカーソル移動は[vimでの移動](#vimでの移動)と同じです。

#### 単語単位で選択

単語単位で選択するのはビジュアルモードに切り替えてから以下のとおりです。

|操作|入力|
|---|---|
|単語を選択する|iw|

#### 行単位で選択

行単位で選択するときはビジュアルラインモードで操作します。デフォルトモードからビジュアルラインモードへの切り替えはVを入力します。戻るときは`ESC`キーを入力します。選択範囲を決めるためのカーソル移動は[vimでの移動](#vimでの移動)と同じです。

#### 矩形で選択

矩形で選択するときはビジュアルブロックモードで操作します。デフォルトモードからビジュアルブロックモードへの切り替えは`Ctrl-v`、もしくは`Ctrl-q`を入力します。戻るときは`ESC`キーを入力します。選択範囲を決めるためのカーソル移動は[vimでの移動](#vimでの移動)と同じです。

## vimで構文単位（対応する区切り文字や、関数、モジュール）で移動する

|操作分類|操作|入力|
|---|---|---|
|対応する区切り文字に移動する|対となる括弧へ移動する|%|
|関数、モジュールに移動する|関数、モジュールに移動する*|:tag {関数・モジュール名}|

*前提としてctagsを用いて関数、モジュールを定義しておく必要があります。本記事ではプラグインなしでできることにとどめたいためctagsの詳細は割愛します。詳細を知りたい方は、[公式リファレンス](https://vim-jp.org/vimdoc-ja/usr_29.html#29.1)を読んでいただくとよさそうです。

## vimで変更作業以降にコードのインデントを付け直す

ビジュアルモードに切り替える。（3つのモードどれでも実施可能）

[Vim – 複数行を一括でインデント・コメントアウトする方法【削除も】](https://howpon.com/20513)を参考にさせていただきました。

|操作|入力|
|---|---|
|インデントを付ける|>|
|インデントを消す|<|

## vimで単一コマンドでコードブロックにコメントを付けたり外す

こちらも[Vim – 複数行を一括でインデント・コメントアウトする方法【削除も】](https://howpon.com/20513)を参考にさせていただきました。

|操作分類|操作|入力|
|---|---|---|
|コードブロックにコメントを付けたり外す|コメントをつける|[vimで選択範囲やマッチしたパターンに基づいてカーソルを複数生成し、それぞれをまとめて編集する](#vimで選択範囲やマッチしたパターンに基づいてカーソルを複数生成しそれぞれをまとめて編集する)のやり方で入力する文字を#や/などのコメントアウト用の文字を入力|
||コメントを外す|（ビジュアルブロックモードで選択して）d |

## vimで変更のアンドゥとリドゥをする

|操作|入力|
|---|---|
|変更のアンドゥをする|u|
|変更のアンドゥをする|Ctrl-r|

## vimでエディターのウィンドウを複数のパネルに分割し、それらの間で移動する

[https://atmarkit.itmedia.co.jp/ いまさら聞けないVim（4）タイルウィンドウとタブ](https://atmarkit.itmedia.co.jp/ait/articles/1104/22/news137.html)がわかりやすくまとめられていました。

|操作分類|操作|入力|
|---|---|---|
|ウインドウを分割する|ウインドウを水平に分割する|:sp|
||ウインドウを垂直に分割する|:vsp|
||ウインドウを閉じる|:q|
||ウインドウを移動する|Ctrl-w Ctrl-w|

## vimで特定の行番号に移動する

|操作|入力|
|---|---|
|特定の行番号に移動する|Ctrl-G {N:移動したい行番号}|

## vimで選択した範囲の行を並び替える

[Vimで行を並べ替え（sort）する](https://unskilled.site/vim%E3%81%A7%E8%A1%8C%E3%82%92%E4%B8%A6%E3%81%B9%E6%9B%BF%E3%81%88%EF%BC%88sort%EF%BC%89%E3%81%99%E3%82%8B/)を参考にさせていただきました。

|操作|入力|
|---|---|
|選択した範囲の行を並び替える（アルファベット順）|（ビジュアルモードで選択して）:sort|
|選択した範囲の行を並び替える（逆アルファベット順）|（ビジュアルモードで選択して）:sort!|

## vimで文字列と正規表現の双方で検索し、以前の検索を繰り返す

|操作|入力|
|---|---|
|文字列で検索する|/ → 検索文字列入力 → ENTER|
|正規表現で検索する|/ → 検索文字列入力 → ENTER|
|以前の検索を繰り返す（下方に検索）|n|
|以前の検索を繰り返す（上方に検索）|N|

## vimで選択範囲やマッチしたパターンに基づいてカーソルを複数生成し、それぞれをまとめて編集する

|操作|入力|
|---|---|
|選択範囲に基づいてカーソルを複数生成し、まとめて編集（矩形選択と解釈）|（ビジュアルブロックモードで選択して）Shift-i →　編集 → ESC → ESC|

`Shift-i`で選択した状態で編集できる状態になります。編集したあとの`ESC`で編集モードが終了し、その次の`ESC`で選択した範囲に入力がされます、

## vimで現在のプロジェクトで発生しているコンパイルエラーを表示させる

|操作|入力|
|---|---|
|エラーウインドウを表示する|:copen|

こちらは以下の簡単なMakefileを作って動作確認をしました。サンプルのプロジェクトのソースコードはシェルスクリプトであり、コンパイルするものではないため、`make build`では文法チェックのみするようにしています。

サンプルスクリプト
```bash
#/bin/bash

echo "OK"
echo "NG
```
makefile
```makefile
build:
 /bin/bash -n sample.sh
run:
 /bin/bash sample.sh
```

`:make`でvim上でmakeを実行できるため、`make build`でcopenにエラーを出力させた例が以下になります。

```bash
|| /bin/bash -n sample.sh
|| sample.sh: line 4: unexpected EOF while looking for matching `"'
|| sample.sh: line 5: syntax error: unexpected end of file
|| make: *** [build] Error 2
```

## vimで現在のプロジェクトにおけるテストを実行する

こちらも[vimで現在のプロジェクトで発生しているコンパイルエラーを表示させる](#vimで現在のプロジェクトで発生しているコンパイルエラーを表示させる)のようにmakefileを作って、テスト実行のコマンドを`:make test`といった感じで実行することとなりそうです。やることはほぼ変わらないと思うため省略します。

## 参考にさせていただいた記事

いずれもわかりやすくまとまっていて、今回まとめるのに参照させていただきました。ありがとうございます。（それぞれ上記リンクした記事です）

* [いまさら聞けないVim（4）タイルウィンドウとタブ](https://atmarkit.itmedia.co.jp/ait/articles/1104/22/news137.html)
* [Vimの4つのモードを使いこなす](https://zenn.dev/mo_ri_regen/articles/vim-four-modes)
* [【入門】Vimで高速で移動\~プラグインなしでの移動まとめ\~](https://qiita.com/takeharu/items/9d1c3577f8868f7b07b5)
* [Vimの4つのモードを使いこなす](https://zenn.dev/mo_ri_regen/articles/vim-four-modes)
* [いまさら聞けないVim（5）ビジュアルモードでテキストを選択し加工する](https://atmarkit.itmedia.co.jp/ait/articles/1106/15/news127.html)
* [Vim – 複数行を一括でインデント・コメントアウトする方法【削除も】](https://howpon.com/20513)
* [Vimで行を並べ替え（sort）する](https://unskilled.site/vim%E3%81%A7%E8%A1%8C%E3%82%92%E4%B8%A6%E3%81%B9%E6%9B%BF%E3%81%88%EF%BC%88sort%EF%BC%89%E3%81%99%E3%82%8B/)

それからとっても大事な公式リファレンス。

* [help - Vim日本語ドキュメント](https://vim-jp.org/vimdoc-ja/)

## さいごに

一通り紹介いたしましたが、同じことを実施するにももっとよりやり方があるかもしれません。もしアドバイスがありましたらぜひコメントをいただきたいです。
また、今回調べることを通してここで紹介した以外にも便利なコマンドや機能がたくさんありました。奥が深いですねvim。あらためて自分でまとめてみることでvimについていろいろわかって、楽しかったです。