vi キホンのキ

普段、 Windows や Mac を使っている方でも、システム開発を行っていると、 Linux サーバーの設定ファイルを編集するときなど、 vi を使う機会があると思います。
そのように、ときどきしか vi を使わない方に向けて、基本的な vi の操作を解説したいと思います。

# vi のモード

vi には基本的な二つのモード「コマンドモード」「テキスト入力モード」があります。
さらにコマンドモードから「:」(コロン)を打って始まる ex モードがあります。

![vi-mode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/926617/35af349d-9a33-7f76-01fa-2227f844a1fb.png)


# vi 操作の基本的な流れ

まずは、編集したいファイルを指定して、 vi を起動しましょう。

```
vi ファイル名
```

vi を起動すると、最初はコマンドモードで立ち上がります。コマンドモードでは、キー入力によりカーソル移動やコピー・ペーストなどのさまざまな機能を実行することができます。
まずは、1文字ずつカーソルを移動してみましょう。
以下のように QWERTY 配列キーボードのホームポジションで右手のキーに割り当てられています。

| h       | j       | k       | l       | 
| ------- | ------- | ------- | ------- | 
| ← (左) | ↑ (上) | ↓ (下) | → (右) | 

カーソルキーでも同様の操作ができますが、ホームポジションでカーソル移動できるのが vi の大きなメリットですので、 h, j, k, l キーを使ってカーソルを動かすことに慣れましょう。

次にテキストを入力してみます。
テキストを挿入したい位置にカーソルを移動して、 `i` または `a` のキーを押します。
すると「テキスト入力モード」になり、以降は打ったキーが文字としてテキスト内に入ります。
挿入(**i**nsert)コマンド `i` を押せばカーソルの手前から、
追加(**a**ppend)コマンド `a` であればカーソルの後ろから、
テキストが入力できます。

この、テキスト入力モードのときは、画面最下行に
```
-- INSERT --
```
のような表示が出たりします。


テキストの入力が終わったら、 `ESC` キーを押してください。コマンドモードに戻ります。

コマンドモードの状態で「:」(コロン)を打つと、　ex モードになり、ウィンドウの最下行に `：` (コロン)が表示されて ex コマンド待ちになります。
この状態で ex コマンドを入力して `Enter` キーを押すと、その ex コマンドが実行されます。

ここでは、ファイルを上書き保存してみましょう。

`：` (コロン)に続けて `w` と打って、　`Enter` キーを押してください。
編集内容が上書き保存され、コマンドモードに戻ります。

なお、上書き保存してそのまま終了したい場合には、コマンドモードで `ZZ` と打つとよいでしょう。
ex モードでも同様の動作が、 `:wq` でできます。

# コピー、削除、貼り付け

コマンドモードでよく使用するコピー・削除・貼り付けを以下にまとめておきます。


| コマンド | キー操作 | 補足   | 
| -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | 
| 行コピー | `yy`       | y は yank の意味。3行コピーしたい場合は `3yy` のように打ちます。(`y3y` でも可) |
| 文字削除 | `x`     | |
| 行削除   | `dd`       | 削除(delete)コマンド。削除した内容はバッファに入るので Windows や Mac の「切り取り」に近い。<br>3行削除する場合は `3dd` のように打ちます。(`d3d` でも可) | 
| 貼り付け | `p`        | カーソルの後にバッファの内容を貼り付け。 同じ内容を3回貼り付けるには `3p` のように打ちます。<br>なおカーソルの前に貼り付ける場合は大文字の `P` と打ちます。|

なお、 Windows や Mac でいうクリップボード(コピーした内容を保存するところ)を**バッファ**と言います。Mac や Windows ではアプリケーションを超えてクリップボードの内容を貼り付けることができますが、 vi では起動中の vi の中でしか使用できません。


# 検索

ファイル内を検索するときは　`/`(スラッシュ)を打ち、続けて検索キーワードを文字入力して `Enter` を打つことで、カーソル以降のそのキーワードに移動します。そこで `n` を押すと次のマッチ箇所に移動します。前のマッチ箇所に遡る場合は大文字の `N` を押します。

| コマンド       | キー操作    | 補足                                                         | 
| -------------- | ----------- | ------------------------------------------------------------ | 
| キーワード検索 | `/キーワード` | キーワードを検索 (下方向へ)                                  | 
| 次の検索       | `n`           | 上記コマンドで検索したあと、次のマッチする文字列に移動する。 | 
| 前の検索       | `N`           | 前のマッチする文字列に移動する。                             | 

# 置換

ファイル内の文字列を置換する場合は ex モードで置換コマンドを使います。

| コマンド | キー操作                     | 補足                                       | 
| -------- | ---------------------------- | ------------------------------------------ | 
| 置換     | `:行範囲s/文字列A/文字列B/g` | 行範囲にあるすべての文字列Aを文字列Bに置換 | 

行範囲にはカンマ区切りで開始行と終了行を指定できます。

`:10,20s/AAA/BBB/g`

というコマンドは、
10行目から20行目までにあるすべての文字列「AAA」を「BBB」に置換
を意味します。

行範囲において `%` はすべての行、`$` は最終行を表します。

`:10,$s/AAA/BBB/g`

とすれば、10行目から最終行までのすべての文字列「AAA」を「BBB」に置換します。

# カーソル移動

最初の方で解説したように 1文字ずつ1行ずつのカーソル移動は h, j, k, l を使用します。
それ以外の、コマンドモードでのカーソル移動方法についてまとめておきます。

| コマンド | キー操作 | 補足 |
| - | - | - |
| 次の画面 | `Ctrl+f` | 次の画面にカーソル移動するには Ctrl+f を押します。(**f**orward) |
| 前の画面 | `Ctrl+b` | 前の画面にカーソル移動するには Ctrl+b を押します。(**b**ack) |
| 次の半画面 | `Ctrl+d` | 次の半画面にカーソル移動するには Ctrl+d を押します。(**d**own) |
| 前の半画面 | `Ctrl+u` | 前の半画面にカーソル移動するには Ctrl+u を押します。(**u**p) |
| 先頭行 | `gg` | ファイルの先頭行にカーソル移動するには `gg` を押します。 |
| 最終行 | `G` | ファイルの最終行にカーソル移動するには `G` を押します。 |
| 行頭 | `^` | 行の先頭にカーソル移動するには `^` を押します。(0でも可) |
| 行末 | `$` | 行の末尾にカーソル移動するには `$` を押します。 |

`^` や `$` は正規表現においても、行頭・行末を表しますよね。

ex モードであれば、`:`(コロン)のあとに行番号の数字を指定してカーソル移動することができます。

100行目にカーソル移動
`:100`

カーソル移動においても `$` は最終行を表します。

最終行にカーソル移動
`:$`