「怖くないLinux」Vim編


# 熱狂vim塾
みんなだいすきVim.
というかハードルが高すぎるんだよね。実はかなり高機能エディタなので、正直使わないのはもったいない。
一応今回の目標は「vimでの不自由ない修正作業」だけど、vimの高機能っぷりを教えておきます。
[Windows向け](https://www.kaoriya.net/software/vim/) もあるんやで。

※ここから、コマンドっぽいところは`a``B``C-c`みたいに書きます。それぞれ
`a` ←普通に[a]キーを押す
`B` ←`Shift`キーを押しながら[b]キーを押す
`C-c` ←`Ctrl`キーを押しながら[c]キーを押す

みたいになってます。わかりづらいと思いますが結構技術書なんかもこの書き方が多いハズ。頑張ろう。


## mode解説

さて、vimを最も難しく、そして高機能化しているもの、それが[mode]という概念だ。

#### Normal Mode
すべての基本。とりあえずコマンドのうちはじめはここ。
まず覚えておくべきは「Escを連打すれば必ずNormal Modeになる」ということだ。
たいていの状況からでもEsc連打でNormal Modeになるぞ。そこから落ち着いて色々コマンドなんか打てばいい。

とりあえず以下のコマンドを打鍵して、カーソルを自由に動かしてみよう。
`h``j``k``l`
これ、私は実際結構わかりづらいと思ってる。
`j``k`が上下どうなっているか結構忘れると思う。というかこれで移動すること実際そこまでないしね。別にカーソルキーでも動けるからいいのだ。



#### Insert Mode
もちろんエディタなので、文字が打てなければ行けない。
Normal Modeから特定のキーを打鍵することによりInsert modeとなり、キーボードに書いてある文字を入力できる状態となる。

insert modeになるためには下記のキーのいずれかを押すことでinsert modeになる。
左下に -Insert- って現在のモードが表示されると思うので、そこを見ながら頑張ろう。

`i` インサート、挿入(カーソルの場所の左から文字が打てる)
`I` 行頭に挿入
`a` アペンド、追加(カーソルの場所の右から文字が打てる)
`A` 行末に追加
`o` オープン、1行下に行を追加(カーソルの場所の次に行が開いて文字が打てる)
`O` 1行上に行を追加(カーソルの場所の前に行が開いて文字が打てる)

`o` とか `O` はあんまり触らないんじゃなかろうか。結構これだけでも便利よ。

Insert modeでもカーソルキーなら移動できる。すごいやん。でもvimを結構使っていると、カーソルキーではないところで移動したほうが楽じゃん！って気づく。気づいてからじゃ遅いので、insertが終了したら`Esc`を連打してnormal modeにしておこう。

#### Visual mode
さてここからが本番。

`v``V``C-v`のどれかでvisual modeに入ることができます。抜けるのは`Esc`。いつも心に`Esc`。
さて、visual modeに入ったあと、上のカーソル移動キーで自由に移動してみよう。わかりやすく言うとマウスでドラッグしている状態、になっているかな？
これがvisual modeで、わかりやすくコマンド対象を選択することができます。
もちろんこれだけでは効力を発揮できず、いろんなコマンドと組み合わせることで真価を発揮するタイプのものです。

以下、visual modeで選択している状態から

* `y` ヤンク、コピー
* `Y` 一行ヤンク
* `d` デリート、じゃなくて切り取り
* `D` 行末までデリート
* `c` チェンジ、選択部分を削除して挿入モードへ
* `C` 行末までチェンジ
* `p` ペースト、貼り付け、y,d,cなどで切り取った内容をカーソルの次に挿入
* `P` ペースト、貼り付け、y,d,cなどで切り取った内容をカーソルの前に挿入

などだけ覚えておくだけでも割りと使えます。
コピー、切り取りしたところは`p``P`で貼り付けられるぞ。
さて、それぞれ違いをかんたんに説明しておきましょう。これを覚えているだけで随分変わってくると思われますので。

1. `v`で選択した場合
普通に選択開始箇所から、マウスでドラッグした風の選択範囲を対象として動作します。

2. `V`で選択した場合
やってみれば分かり易いです、いわゆる「行選択」状態になります。上の切り取り、なんかと組み合わせるとX行だけ切り取り！なんてことがかんたんにできます。マウスなしでも。

3. `C-v`で選択した場合
いわゆる「矩形選択モード」となる。
サクラエディタで言うところの`Shift`+`F6`、秀丸エディタとかだと`Alt`+マウスドラッグ、みたいな？
これのポイントは切り取り、貼付け時になるべく切り取った状態のまま貼り付けようとするところです。
といってもその他のエディタとそこまで変わらないです。

visual modeはこの次のmodeと組み合わせるとすっごい便利なのでぜひ覚えよう！

#### Command Line Mode
`:`から始まるコマンドを使うmodeです。
Normal modeでとりあえず`:`を打ってみてください。
これは左下なんかにMode名が出ないはずです。`:`は出てると思いますが。

ここで色々入力することで特殊コマンドなんかができます。これがcommand line modeだ！

`:set [target]`って打つことでvimの設定を変更したり、
`:%s/before/after/g`って打つと[before]って文字列が[after]に変換できたりするぞ！

そしてなにより`:help [command]`でvimコマンドのhelpが開けるぞ！

この辺から妙に難しく感じるかも知れないが、linuxコマンドとそこまで変わらない。実際覚えておくべきことは少ないので、大丈夫大丈夫。
とりあえず`:set nowrap``:set list``:set cursorline`とかを打って設定を変えて見よう。
これ、結構色々見た目変えられるし、結構色々できるんです。すごいんです。

そして検索、`/`でコマンドラインみたいに下に検索窓？が出てくるから、そこへ検索する文字列を入力して文字検索だ。
文字検索結果は`Enter`で次の結果。。。には行かない。

あくまでコマンドラインモードとしては「検索を実施した」なのだ。それ以降はnormal modeとして結果を引き継ぐ必要がある。
といっても難しくない。`n`で次の結果を表示、`N`で前の結果を表示する。
わかりやすいね！

検索系、類似コマンドを上げておこう。検索と置換はvimの華！

`*` カーソルのある位置の単語を検索する
`#` カーソルのある位置の単語を逆に検索する
これ、`n`と`N`が逆になるのがミソ。ってかわかりづらい。なんでこうなった。

これ知ってるだけでかっこいい！ってなるはず。ならんか。


## オペレータについて(コマンドの構成、作り方について)

さて、ここまでvimの各種モードの解説、またそれなりに程々なコマンドの説明等をしてきましたが、normal modeにおけるコマンドの構成についてここで少し語ります。

normal modeにおけるコマンドについては通常復数のキーの組み合わせで構成されており、それぞれ意味を持っています。分けて解説します。

例えば、カーソルの有るところから単語1個分削除(実際は切り取りの為貼り付けが可能)のnormal mode コマンドは
`dw`となっています。

もちろん上記コマンド、`d`と`w`で分割でき、それぞれ`d`部分がオペレータ、`w`がモーション、というものです。

`d`がdeleteのオペレーションを決定し、`w`でword,つまり単語単位で実行してね、となっています。
これ、今まで出てきたものとそれぞれ組み合わせることが出来ます。

例えば`2cw`。これは`2`と`change`と`word`の組み合わせなので`単語2個分変更(削除して挿入モードへ)`となります。

ある程度、この構成で出来ている、というのが分かりさえすれば結構スムーズにどのコマンドを打てば狙っている事ができるか、というのが出来てくると思います。

またvisual modeとの組み合わせが強力です。
visual modeで選択している時にnormal modeと同じコマンドを実行しようとした場合、visual modeで選択している部分がモーション扱いになり、オペレータのみを入力すればコマンドが実行されます。

大体のvim教本などで最初にコマンドで`dd`(1行分削除)や`yy`(1行分コピー)に数字を頭につけて複数行、なんてのがよく紹介されるのですが実際使いづらいです。

`10dd`とか書いても実際10行消したいのかどうなのか、行数を数えてから実行、なんてよくあると思います。
だったら`V`で行選択visual modeにしてからカーソルを下に移動して行き、目標の箇所までたどり着いたら`d`で削除ってやったほうが自然です。

とにかくvimのnormal modeのコマンドについてはオペレータ、モーションの構成(逆に打っても大体動きます)がありますよ、ってところを覚えておきましょう。

数字を頭につけるのは`gg`は便利かもしれません。
特に数字を付けない場合は最初の行へカーソルを移動、ですが数字をつけることにより指定行へ移動、となります。
`100gg`なら100行目へ移動、です。
eclipseなら`C-l`→`100`→`Enter`ですかね。

1つオススメを教えておきます。
`ci(`や`di'`とか`cit`とかの`なんとかiなんとか`です。
これ、構成的には最初の一文字がオペレータ、あと二文字モーションになるのですが、
`iなんとか`がすごいんです。
簡単に言うと`in nantoka`で、最後の文字で括られている部分すべてを対象として動作することが出来ます。
ちなみに最後の`cit`は`change in tag`です。HTMLタグが該当します。
これ覚えていただけば今日の研修は成功です。と言ってもいいくらい、皆さんに伝えたいしみんな知らないものです。

例文書いておきます。

```java
    public static String getDefaultDate(int addMonth, int defaultDay) {
        Calendar calendar = new GregorianCalendar();
        calendar.add(Calendar.MONTH, addMonth);
        calendar.set(Calendar.DAY_OF_MONTH, defaultDay);
        Date targetDate = calendar.getTime();
        return DateFormatUtils.format(targetDate, "yyyy/MM/dd");
    }
```

ってどこにでもありそうなJavaの日付変換メソッドが合ったとします。
例えば`return DateFormatUtils.format(targetDate, "yyyy/MM/dd");`の`"yyyy/MM/dd"`部分を変更したい！ってなった場合、

1. 対象部分(今回は`"yyyy/MM/dd"`の内部)にカーソルを移動する
2. `ci"`
3. `yyyy/MM/dd`が消え、
`return DateFormatUtils.format(targetDate, "|");`の状態で縦棒の所にカーソルがinsert modeで！

・・・うん。伝わらない気がしてきました。

これ、HTMLファイルを直したりする時に便利なんです。
HTMLファイルの特定タグの内部を変更するとき、`cit`でタグ内部の文字列を全部消して、そこから変更後内容を書き始める、という事をやるときなどに割と便利です。

#### リピート`.`

ちょっとの労力で強力なコマンドのリピートコマンドについて教えておきます。
と言っても上に表示されているとおり、`.`キーを押すだけです。
これで「直前に実行したコマンド」を再度繰り返します。
例えば上の方の例、`dd`で1行削除、なんかも1行消してから`.`を連打して少しずつ消していく、っていうのも自然な感じになるかと思います。

vimは自由度が高すぎて、特定の目標への手段が多すぎるのが良い点でもあり悪い点でもあります。
まあ色々覚えるのが一番ですが、よく使うやつから覚えていけば全然普通のエディタと遜色ない、どころかかなり使い勝手の良いものになっているのでは無いでしょうか。


## タブ、バッファについて

vimは基本画面上に1つのファイルしか開けません。と思いがちですが、いっぱい開けます。
しかもタブ使えます。実はタブエディタなんです。すごいでしょ。
command line modeのコマンドでタブ開き等を実行します。
`:tabe [target file]`で別タブとして指定ファイルを開きます。ファイル指定がない場合はとりあえずタブだけ開きます。
画面上部にタブが表示されるかと思います。テキストだけのCLIなのにタブとか表現しちゃうんです。すごいでしょ。
`:tabn(ext)`で次タブへ遷移したり出来ます。

ちなみにタブじゃなくて同じ画面内を分割して開いたりもできます。
`:sp [target file]`か`:vsp [target file]`です。
これ、開くのはいいんですが困るのがカーソルを別画面へ移動できないーって大体なります。
コマンド`C-w C-w`で隣の画面にカーソルが動きます。
`C-w h`で左の画面に移動します。`C-w j`で下の画面に移動します。カーソル移動と一緒ですね。

| 項目名   | デフォルト |
|:---------|:-----------|
| 左に移動 | `<C-w>h`     |
| 下に移動 | `<C-w>j`     |
| 上に移動 | `<C-w>k`     |
| 右に移動 | `<C-w>l`     |
| 次に移動 | `<C-w>w`     |

ちなみにそれぞれの画面のサイズも変えられます。

| 項目名         | デフォルト   |
|:---------------|:-------------|
| 縦に最大化     | `<C-w>_`   |
| 横に最大化     | `<C-w>ぱいぷ`  |
| 縦横最大化     | `なし`     |
| 大きさを揃える | `<C-w>=`   |
| 幅を増やす | `<C-w>>`   |
| 幅を減らす | `<C-w><`   |
| 高さを増やす | `<C-w>+`   |
| 高さを減らす | `<C-w>-`   |


それぞれ分割している所、タブで開いているところは別のものを開いている扱いなので、通常通り`:q`で終了するとカーソルがある所を閉じます。

あと実はバッファ、っていうものもあります。これ大体ミスった！って思うかもしれません。
vimの起動時に復数のファイルを対象として開いたりした場合にバッファ内に復数ファイルが読み込まれ、順番に開いていく、という挙動となります。
ですがめっちゃくちゃ判りづらく、とりあえず一旦閉じてから1個ずつタブなり画面分割なりで開いていった方がいいと思います。正直。。
バッファについては余力があれば書きます。

## レジスタについて

レジスタ。何のこと？とお思いかと思いますが、わかりやすく言うと「クリップボード」です。
windows等も通常コピーできるところ(クリップボード)のサイズは1しかありませんね。それがわかりやすくてあれなのですが、実はvimクリップボードいっぱいあります。名前もつけられています。

実は普段コピー(vimだとyank)したり削除したりしたものは「無名レジスタ」というところに入ります。
何も指定していないで貼り付けを行うとこの「無名レジスタ」から貼り付けられます。
だから特に何も指定しなければ通常どおりサイズ1のクリップボードがある、と思ってもらって構いません。

あとは面倒になっちゃったのでhelp貼っておきます。

```
レジスタには 10 種類ある:				*registers* *E354*
1. 無名レジスタ ""
2. 10個の番号付きレジスタ "0 から "9
3. 小削除用レジスタ "-
4. 26個の名前付きレジスタ "a から "z または "A から "Z
5. 3個の読み取り専用レジスタ ": と ". と "%
6. 代替バッファ用レジスタ "#
7. expression 用レジスタ "=
8. 選択領域用レジスタ "* と "+ と "~ 
9. 消去専用レジスタ "_
10. 最終検索パターン用レジスタ "/
```

全部覚えるとそれだけで吐き気がしてきそうなので、`2.`と`4.`だけ覚えておきましょう。

```
2. 番号付きレジスタ "0 から "9

これらのレジスタには、コピーや削除コマンドによってテキストが蓄えられる。
番号付きレジスタの 0 には、一番最近にコピーしたテキストが蓄えられるが、コピー
の際に ["x] として別のレジスタ名を指定したときは、これには蓄えられない。
```

```
4. 名前付きレジスタ "a から "z または "A から "Z

これらのレジスタが使われるのは、ユーザーに指定されたときのみである。コピーや削
除の際にこれらのレジスタを小文字で指定すると、コピーや削除されたテキストが蓄え
られ、元から入っていたテキストは消える。大文字で指定すると、元から入っていた内
容の後ろに新しいテキストを付け加える。
```

ということで、つまり

1. レジスタ1~9は過去の履歴が入るイメージ
2. レジスタa~zは自由に使えるクリップボード

と覚えてもらえば十分です。
使い方としては通常のオペレータの前にレジスタ指定を入れつつ、という使い方になります。

駆使すれば20個以上のクリップボードが貴方のもとに！すげぇ！
とここまで書いて絶対使うことないだろうな、と思いました。無理だよこんなの。