完璧Vimmerでなくても良いのでVimを使おう

# 概要
みなさんこんにちは、今回はVimを使ったことのない私が、Vimのエディタを使ってみて、これは全エンジニアが知る必要がある、と感じたことを書きます。今日からでもできる内容なので、休み時間に試したり、大型連休で試すのもよいと思います。
また、私は最終的に完全Vimmerになるのではなく、VSCodeにVim拡張を入れることで決着しました。このような道もあると思うので、完全Vimmerにならなくても気軽に始めてみてはいかがでしょうか。

# まず、Vimに対してどんなイメージを持っていたか？

私のVimに対するイメージ、というかVimについて知っていたことはせいぜい以下のことでした。

- 画面が黒い(小並)
- hjklで上下左右の移動をする
- モードがいくつかあるので複雑
- Insertモードから抜けるときにEscを押す

特に、「hjklで移動するなんて意味不明」「モードが複雑そうでいやだ」「Escキーって地味に遠いじゃん、押しにくいじゃん」みたいな感じで、Vimを使おうとは全く思わなかった、というのが1か月前の私です。

その私ですが、たまたま「実践Vim」という本に出会い、Vimがなぜこんなにも長きにわたって使われ続けているか、ということを理解しました。残念ながら、「実践Vim」は現在出版していないことと、重版は予定していないと出版社の方から連絡をいただいたので、皆さんに簡単には勧めることはできませんがぜひ興味を持ったらVimでできることについて調べてみると面白いと思います。また、Kindle版はあるみたいなので興味を持った方はぜひ読んでみてください。

それでは本題に入っていきましょう。

# 目次
知っておいて損はない、以下のことについて書きます。

- ciwで文字を置換できる
- hjklで移動ということについて
- 移動の仕方
- Escが遠い、のはなんとかできる
- . で繰り返し

# ciwで文字を置換できる

おそらく、IDEを使っている方は文字列を置換するときや削除をするときは`Ctrl + shift + 矢印`で単語を選択してからBackspaceを押したり、マウスでダブルクリックをして単語を選択してから、Backspaceを押しているものと思います。
Vimではこの置換操作をホームポジション近辺のキーで様々な操作を行うことができることのほかに、Vimではある程度のことさえ覚えてしまえば、応用して幅広い操作ができることを知っていただきたいです。ciwを例としてあげますが、これを軸として様々な操作をすることができます。

## その前にノーマルモードとは

ciwを入力するのはVimがノーマルモードの状態の際に行います。Vimにはいくつかのモードがありますが、普段、IDEを利用している方の多くはVimでいうところのinsertモードで常にコードを記述しているものと思います。しかし、Vimでは多くの時間をノーマルモードで過ごすことになります。実は、このノーマルモードでは、さまざまなコマンドを受け付けるようになっており(コマンドラインモードもあるみたいなのであまり大きい声で言えませんが)、「j」キーを押下するとカーソルが上に移動する、というのもコマンドの一つだと思うとわかりやすいと思います。

## ciwを入力する

そのため、ノーマルモードで`ciw`と入力すると、何かしらのコマンドが実行される形となり、現在カーソルが置かれている文字(カーソルは文字列先頭でなくても可)が削除されてInsertモードに移ります。その後、文字を入力してEscを入力することで置換が完成します。簡単に例を以下に書きます。

```vim:ciwを実行した様子
* はカーソル位置

[初期状態(ノーマルモード)]
hello world !!
        *

[ciw入力後(insertモードに切り替わる)]
hello  !!
      *

[適当な文字を入力(insertモード)]
hello hoge !!

Escして完成！
```

見ての通りですが、「ciwコマンドを実行してくれれば置換ができます」だけだと、Vimを使おうという気にはならないと思うので、ここで説明のために、ciwコマンドをc+iwとして分けます。cは`operator`でiwは`text-object`と分類することができ、「どんな操作を(`operator`)」+「どの範囲に(`text-object`)」ということを組み合わせることで操作を表現することができます。また、コマンドで使われる文字は何かしらの略字として捉えることができ、今回のciwコマンドについて言及すると、cは「**C**hange」でiwは「**I**nner **W**ord」の略されていると理解できます。そのため、直感的なキーの組み合わせでコマンドを作ることができます。

## ついでにdawも

dawも先の説明と要領は同じですが、dは「**D**elete」でiwは「**A** **W**ord」とのことなので、1単語消す操作になります。

```vim:dawを実行した様子
* はカーソル位置

[初期状態(ノーマルモード)]
hello world !!
        *

[daw入力後(ノーマルモード)]
hello !!
      *
```

dを利用した場合は、削除するだけの操作なので、insertモードには移動しません。

ところで、先ほど登場した`text-object`の`iw`と今回登場した`aw`の違いですが、文字の隣の空白を1つ削除するかどうかが違います。`aw`のほうは隣の空白を1つ消し、`iw`のほうは隣の空白は消しません。そのため、`daw`ではなく`diw`を実行すると、以下のように空白が2つ連続してしまいます。`ciw`を利用した場合は逆に、本当は空白が1つ空いていてほしいのに、2つの単語がくっついてしまう状態になります。　

```vim:diwを実行した様子
* はカーソル位置

[初期状態(ノーマルモード)]
hello world !!
        *

[diw入力後(ノーマルモード)]
hello  !!
      *
```

## この調子でda"の説明も

先ほど、`daw`は「**D**elete **A** **W**ord」と説明しましたが、`da"`という使い方もできます。これは「**D**elete  **A**rround **"**」と解釈することができ、以下のように、`""`で囲まれた文字列をダブルクォーテーションごと削除できます。これがもし、`di"`であれば、ダブルクォーテーションの中身を削除することができます。

```vim:da"を実行した様子
* はカーソル位置

[初期状態(ノーマルモード)]
hello "world" !!
        *

[da"入力後(ノーマルモード)]
hello  !!
      *
```

```vim:di"を実行した様子j
* はカーソル位置

[初期状態(ノーマルモード)]
hello "world" !!
        *

[da"入力後(ノーマルモード)]
hello "" !!
      *
```

なので、もし`[]`の中の文字を置換したい場合は、`ci[`と入力するのかな、と想像することができます。このように、Vimでは様々な編集操作をコマンドのように行うことができ、矢印キーやマウスキーを触らずホームポジションを崩さないため、編集の効率や快適さが格段に変わります。

ところで、`operator`では、`c`と`d`を説明しましたが、`y(yank)`というコピー操作もよく利用するので覚えておくとよいでしょう。

# hjklで移動ということについて
Vimではhjklで上下左右を移動します。Vimmerではない方にとっては、これはたぶん操作がしにくいと思います。ただ、これはある考え方をするだけで、劇的にhjklでの移動について考え方が変わります。それは、あんまりhキー(左移動)での移動は多用しないんです。この事実を頭の中に入れておいて、私たちのキーボードとjklのキーの位置を照らし合わせてみると、ポッチのついた「j」キーに人差し指、「k」キーに中指、「l」キーに薬指が乗っていると思います。なんと、ホームポジションから指１本を動かすこともなく移動できます。矢印キーのような遠くにあるキーを押さなくてよいことは本当にストレスがなくなります。

# 移動の仕方
先にも説明した通り、Vimではhjklで移動することができますが、Vimでは単語単位の移動や行内移動ができ(というか、これが強力)、`w`で単語1つ分移動、`b`で前の単語に移動、`e`で単語1つ分移動するが単語末尾にカーソルを合わせる、`f`で行内移動ができます。IDEでも`Ctrl+矢印`で単語単位での移動はできますが、矢印キーのような遠い場所にあるキーを押すのは面倒です。
また、`f`での行内移動について説明すると、fの直後に検索したい文字を入力することでそこへ移動することができます。
ページ送りや、カーソル位置を画面の中央に持ってくることもできます。調べるだけでもワクワクします。[この記事](https://qiita.com/takeharu/items/9d1c3577f8868f7b07b5)がわかりやすいです。

```vim:fでの行内検索移動(rの文字の場所に移動することを想定)
* はカーソル位置

[初期状態]
hello world !!
*

[fr入力後(ノーマルモード)]
hello world!!
        *
```

ちなみに、wはword、bはback、eはend、fはfindの略でしょう。

# Escが遠い、のはなんとかできる
Vimを使っている際はEscは無くてはならない存在です。しかしながら、左上に居座っていて非常に押しにくいですよね。デフォルトでもEscキーは「Ctrl+[」で代用できますが、日本語キーボードは押しにくかった記憶があります。VimではこのEsc操作を`j+j`を押すだけでできるようにすることができます。

## ~/.vimrc を編集する
Vimでは自分で文字入力とコマンドを制御することができます。`.vimrc`の編集は以下のようにします。

```
vim ~/.vimrc
```

このファイルに、以下を記述するだけで`j+j`でEscにすることができます。

```
inoremap <silent> jj <ESC>
```

このことからわかるように、`.vimrc`を編集することで自分でキーに対する操作を定義できます。
VSCodeでもキーバインドをカスタマイズすることができますが、Vimでももちろん行うことができます。

そのため、`.vimrc`を編集するだけで最強の自分用Vimにすることができることができるため、自分流にアレンジしたり、GitHubやQiitaで様々なエンジニアの方が自身のVimの設定ファイルをアップしているため、コピペして真似したりするのもよいと思います。

# . で繰り返し

どんな面倒な動作も、.で直前の操作を繰り返すことができます。これほど楽なことはありません。ぜひ覚えておいたほうがよいでしょう。

```vim:ciwを実行した様子
* はカーソル位置

[初期状態(ノーマルモード)]
hello world !!
        *
hello world !!
hello world !!

[ciw入力後(insertモードに切り替わる)]
hello  !!
      *
hello world !!
hello world !!

[適当な文字を入力(insertモード)してEscを押す]
hello hoge !!
hello world !!
hello world !!

[.を押す(ノーマルモード)]
hello hoge !!
hello hoge !!
hello world !!

[.を押す(ノーマルモード)]
hello hoge !!
hello hoge !!
hello hoge !!

```

# なぜ私はVSCodeに戻ったか

私がVSCodeに戻った理由は、Vimで複数ファイルをいじるときに馴染めない部分があったことと、プロジェクト全体のgrepが明らかにVSCodeの速いし、見やすい、ということがありIDEに戻りました。ただVimでの編集を一度経験すると、もとのエディタには戻れないくらいの快感を感じることができます。そのため、私はIDEに戻るがVim拡張でエディタ機能の恩恵を受けるという選択をしました。

# その他

- ちなみに、Macユーザの方はCtrlキーも左小指で簡単に押せちゃうので問題ありませんが、WindowsではCtrlが押しにくい位置にあるので、私はCapsLockをCtrlキーに変えてしまいました。Ctrlキーを押す際も左下に指をずらさなくてもよいので便利です。
- [脱初心者を目指すなら知っておきたい便利なVimコマンド25選 (Vimmerレベル診断付き)](https://qiita.com/jnchito/items/57ffda5712636a9a1e62#cidatviya%E3%81%AE%E3%82%88%E3%81%86%E3%81%AA%E3%82%B3%E3%83%B3%E3%83%93%E3%83%8D%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%BF%E3%81%84%E5%88%86%E3%81%91%E3%81%A6%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%82%92%E7%B7%A8%E9%9B%86%E3%81%99%E3%82%8B)はすごくまとまっているので、こちらも読んでみると面白いと思います。

# おわりに

Vimの全機能を使いこなさなくても、たったこれだけを使うだけでも開発効率は格段にあがります。
年末年始の長期休みでVimを使ってみてはいかがでしょうか。楽しいですよ。

# 参考資料
[脱初心者を目指すなら知っておきたい便利なVimコマンド25選 (Vimmerレベル診断付き)](https://qiita.com/jnchito/items/57ffda5712636a9a1e62#cidatviya%E3%81%AE%E3%82%88%E3%81%86%E3%81%AA%E3%82%B3%E3%83%B3%E3%83%93%E3%83%8D%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%BF%E3%81%84%E5%88%86%E3%81%91%E3%81%A6%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%82%92%E7%B7%A8%E9%9B%86%E3%81%99%E3%82%8B)
[便利なVimのOperatorをマスターする](https://www.infiniteloop.co.jp/blog/2011/11/vim-operator/)