Bashショートカットキー

# 概要
LinuxのデフォルトシェルBashのショートカットキーについて、便利なのでマニュアルを読み直して覚えておきたいものをまとめました。

### 動作環境
```shell-session
$ bash --version
GNU bash, version 4.4.23(1)-release (x86_64-unknown-linux-gnu)
...
```

# マニュアルページ
インタラクティブシェルで使えるショートカットキーについてはBashのマニュアルページのREADLINEの箇所に記載してあります。`man bash`で参照できます。
本記事のタイトルは「ショートカットキー」としましたがマニュアルページでは「key bindings」という表現となってます。

# ショートカットキー一覧
ショートカットキーはマニュアルページの記載に合わせて以下のように表現します。

- `Ctrl`キーとの同時押しは`C-x`と表現します。
- `Alt`キー(`Meta`キー)との同時押しは`M-x`と表現します。

※`Esc`キーもMetaキーとして使用できます。この場合、同時押しでなくてもショートカットキーとして使用できます。(例: `Alt + f`と`Esc, f`が同じ動作をする。)

<table>
<tr><th>key</th><th>コマンド名</th><th>説明</th>
<tr><th colspan="3"># カーソル移動 ★★★</th></tr>
<tr><td>C-a</td><td>beginning-of-line</td><td>行頭へ移動</td></tr>
<tr><td>C-e</td><td>end-of-line</td><td>行末へ移動</td></tr>
<tr><td>C-f</td><td>forward-char</td><td>１文字進む</td></tr>
<tr><td>C-b</td><td>backward-char</td><td>１文字戻る</td></tr>
<tr><td>M-f</td><td>forward-word</td><td>１単語進む</td></tr>
<tr><td>M-b</td><td>backward-word</td><td>１単語戻る</td></tr>
<tr><td>C-l</td><td>clear-screen</td><td>現在行を残して画面をクリアする。<br>人に説明するときは多用すると見やすいです。</td></tr>
<tr><th colspan="3"></b># 履歴操作</b></th></tr>
<tr><td>C-p</td><td>previous-history</td><td>１つ前に実行したコマンドを挿入する。</td></tr>
<tr><td>C-r</td><td>reverse-search-history</td><td>コメンド履歴を検索※インクリメンタルサーチ<br>※入力練習のためにはあまり使わないほうがいいかも</td></tr>
<tr><td>M-p</td><td>non-incremental-reverse-search-history</td><td>コマンド履歴を検索</td></tr>
<tr><td>M-.</td><td>yank-last-arg</td><td>直前のコマンドの引数を入力</td></tr>
<tr><th colspan="3"></b># テキスト処理</b></th></tr>
<tr><td>C-d</td><td>end-of-file</td><td>EOF(End Of File, ファイルの終端)を入力する。<br>※コマンドラインに何も入力していない状態でやるとターミナルが終了する。</td></tr>
<tr><td>C-d</td><td>delete-char</td><td>コマンドラインに文字列を入力途中の場合、1文字削除する。Deleteキーと同じ。</td></tr>
<tr><td>C-v TAB</td><td>tab-insert</td><td>タブを挿入。<br>Terminalでもタブを挿入できる。使い道はない。</td></tr>
<tr><td>C-t</td><td>transpose-chars</td><td>カーソル前後の文字を入れ替える。カーソルが行末にある場合、最後の2文字を入れ替える。</td></tr>
<tr><td>M-u</td><td>upcase-word</td><td>単語を大文字にする。</td></tr>
<tr><td>M-l</td><td>downcase-word</td><td>単語を小文字にする。</td></tr>
<tr><th colspan="3"></b># コピーペースト</b></th></tr>
<tr><td>C-k</td><td>kill-line</td><td>行末まで削除</td></tr>
<tr><td>C-u</td><td>unix-line-discard</td><td>行頭まで削除</td></tr>
<tr><td>M-d</td><td>kill-word</td><td>次の単語削除(単語の最後まで削除)</td></tr>
<tr><td>M-Rubout</td><td>backward-kill-word</td><td>前の単語削除(単語の最初まで削除)</td></tr>
<tr><td>C-w</td><td>unix-word-rubout</td><td>前の単語削除(スペースで区切られているものを単語とする)</td></tr>
<tr><th colspan="3"></b># 他</b></th></tr>
<tr><td>C-_</td><td>undo</td><td>やり直す</td></tr>
<tr><td>C-]</td><td>character-search</td><td>続けて入力する文字までカーソルを移動する<br>例) 「$ cat hoge fuga」の行頭にカーソルがあるとして、`Ctrl + ], g`を押すと「fuga」のgにカーソルが移動する。</td></tr>
<tr><td>M-C-]</td><td>character-search-backward</td><td>上記「character-serarch」の逆(反対方向へ文字検索)</td></tr>
</table>

## 補足
### end-of-file (C-d)
ファイル終端を挿入するということは、もうそれ以上プログラムに渡すデータがないことを示します。
例)
`cat`コマンドはファイルの内容を出力するコマンドです。
引数にファイルを指定しなかった場合は、プログラムは標準入力から延々入力を受け付けます。
`Ctrl + d`でEOF(ファイル終端)が入力されると正常終了します。
イメージとして、下の例では、`^#`を入力して`Enter`を押した後に`Ctrl + d`でEOFを渡して入力を終了しています。

```
$ cat > regex # 標準入力をregexというファイルにリダイレクトする
self-insert
^#
$ 
```

### 単語
単語の単位で移動したり削除したりするショートカットキーがありますが、大体は連続した英数字(alphanumeric)を単語とします。記号は無視されます。全角ひらがなは単語として扱われましたがそんな使い方する人はいないでしょう。
例えば以下の入力の行末にカーソルがあり、`Alt + BackSpace`を押していくと以下のようになります。

```
$ [ -a hoge ] && echo 'true' || echo 'false'
$ [ -a hoge ] && echo 'true' || echo '
$ [ -a hoge ] && echo 'true' || 
$ [ -a hoge ] && echo '
$ [ -a hoge ] && 
$ ...
```

`Ctrl + w`も同じく前の単語を削除しますが、スペース単位で消します。
上に挙げたコマンドではこれだけ例外です。

```
$ [ -a hoge ] && echo 'true' || echo 'false'
$ [ -a hoge ] && echo 'true' || echo 
$ [ -a hoge ] && echo 'true' || 
$ [ -a hoge ] && echo 'true' 
$ [ -a hoge ] && echo 
$ ...
```

# おまけ
## Ctrlキーが押しにくい
キーバインドをカスタマイズして`Caps Lock`に割り当てる人が多いようです。
日本のキーボードは`無変換`や`変換`がある分、手前のキーが多いので、わざわざ日本語キーボードを買って修飾キーを全部親指で押せるようにカスタマイズしている海外の人もいるそうです。

Linuxの場合、xkbの設定(setxkbmapとか)やxmodmapなどで実現できます。
Windowsはアプリを入れたくなければレジストリエディタで設定できます。

日本人で`無変換``変換`を使わない人は修飾キーを割り当てたり、片方に日本語ON、片方に日本語OFFを割り当てるといいと思います。

## キーバインドを確認する。
`bind -p`で設定されているキーバインドが一覧で表示されます。
効かない場合は確認してみてください。
`\C`が`Ctrl`キー、`\e`が`Esc`キー(Metaキー)のことです。

```shell-session
$ bind -p > bindp
$ grep -E '^"\\[CeM]' bindp
"\C-g": abort
"\C-x\C-g": abort
"\e\C-g": abort
"\C-j": accept-line
"\C-m": accept-line
"\C-b": backward-char
"\eOD": backward-char
"\e[D": backward-char
"\C-h": backward-delete-char
(省略)
"\C-x\C-u": undo
"\C-_": undo
"\C-u": unix-line-discard
"\C-w": unix-word-rubout
"\eu": upcase-word
"\C-y": yank
"\e.": yank-last-arg
"\e_": yank-last-arg
"\e\C-y": yank-nth-arg
"\ey": yank-pop
```

普段使わないだろうというのもたくさんあります。
`Esc, O, D`で「一文字戻る」、など。

## ターミナルエミュレータの設定
シェルを使うためのソフトウェア・アプリケーションによってはツールバーのショートカットキーが優先されてしまうことがあります。
１単語進めようとして`Alt + f`を入力したら、ツールバーのファイルタブが開いてしまうなど。
シェルを使うことを前提にしているのであれば、ツールバーを非表示にするか、エミュレータのショートカットキーを無効にする設定が必ずあります。