[Windows]Clinkディープカスタマイズ

## Clinkのさらなる深層を探求する

https://qiita.com/Q-Lazy/items/26eb3dde84032d80880d

[前回](https://qiita.com/Q-Lazy/items/26eb3dde84032d80880d)は必要最低限の設定および、基本的な機能の概要とその操作方法を中心に解説しました。
今回はさらに一歩踏み込んだ設定によるカスタマイズと、その機能を引き出すことでClinkの付加価値をより高めることを目指します。

### Clinkを自分好みにカスタマイズ

設定ファイル`settings`をコマンドにより変更することにより、様々な動作をカスタマイズできます。下記のように`set`サブコマンドで現在の設定をリストアップできます。

```text
>clink set
Available options:

ctrld_exits ............... 1      Pressing Ctrl-D exits session
esc_clears_line ........... 0      Toggle if pressing Esc clears line
match_colour .............. -1     Match display colour
exec_match_style .......... 2      Executable match style
space_prefix_match_files .. 1      Whitespace prefix matches files
prompt_colour ............. -1     Colour of the prompt
terminate_autoanswer ...... 0      Auto-answer terminate prompt
history_file_lines ........ 10000  Lines of history saved to disk
history_ignore_space ...... 0      Skip adding lines prefixed with whitespace
history_dupe_mode ......... 2      Controls how duplicate entries are handled
history_io ................ 0      Read/write history file each line edited
history_expand_mode ....... 4      Sets how command history expansion is applied
use_altgr_substitute ...... 1      Support Windows' Ctrl-Alt substitute for AltGr
strip_crlf_on_paste ....... 2      Strips CR and LF chars on paste
ansi_code_support ......... 1      Enables basic ANSI escape code support
```

`set`にパラメータとして設定項目名を与えると、指定した項目の設定値のみを表示し、設定値も併せて与えることにより、その設定値で上書きします。
まずはちょっとした気分転換レベルですが、プロンプトと入力補完候補リストのフォントのカラーを変えてみましょう。

```powershell
>clink set prompt_colour 6
Settings 'prompt_colour' set to '6'

>clink set match_colour 2
Settings 'match_colour' set to '2'
```
いったんClinkを終了して起動し直すと、設定が反映されます。上記の例であれば下図のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513692/13e127c4-bf9e-0b82-4dfb-e3dc13c59fdd.png)

ターミナル画面の可読性の改善に割と効果的だと思います。プロンプト自体の設定は自由ですが、`$P$_$G`などがお勧めです。
次に入力履歴ほ保存するファイル`.history`の入出力方法の変更です。規定が`0`のところを下記のように`3`に書き換え、Clinkを再起動します。

```powershell
>clink set history_io 3
Settings 'history_io' set to '3'
```

これによりClinkを同時に2つ以上起動していても、それぞれの入力履歴を統合し、共有できるようになります。Bashで同様の設定をするには結構な分量のコードを書かなければなりませんが、Clinkの場合はこれだけで済みます。
なぜ既定が無効になっているのか疑問に思いますが、過去に遡ればフロッピーディスクで運用しているケースもあったと思われ、入出力によるオーバーベッドを抑えるための措置ではないかと思います。


### 失われた能力を取り戻す

Clinkをインストールしたフォルダの中を調べてみると、Readlineの設定ファイル`clink_inputrc`のテンプレートとして、`clink_inputrc_base`というファイルが見つかります。その末尾に、ちょっと気になる設定がコメントアウトされています。

```text:clink_inputrc_base
# Uncomment these two lines for vanilla cmd.exe style completion.
# "\t": clink-menu-completion-shim
# "\e`Z": clink-backward-menu-completion-shim
```

これらの設定のコメントを外して有効化すると、どうなるかということですが、cmd.exeが本来備えている、`TAB`キーによるインラインでの入力補完機能を復活させることが出来ます。
Bashの補完機能（以下Bash補完）では、補完候補が複数あった場合は、候補を一覧表示して続きの入力を促すのに対して、cmd.exeの補完機能（以下インライン補完）では、`TAB`キー押下するごとに、候補を順番にカーソル以降に直接補完するという動作になります。

それぞれに長所短所はあり、Bash補完は候補が1つに絞り込めるまでは手入力で補わなければなりませんので、候補が少ないケースでは面倒に思えます。逆に候補が多ければ、手入力で絞り込んだほうが早く確定できるし、候補の中に所望のものが無ければ、事前に判ります。
インライン補完の場合は候補が少ないケースではタイプ数を削減出来て楽ですが、逆に候補が多ければ、なかなか正解にたどり着けなかったり、最悪正解が元々含まれていなければ結局出て来ない、という悲劇も有り得ます。

しかしながら、cmd.exeをパワーアップするためにClinkを導入したにもかかわらず、元々備わっていた便利な機能を失ってしまうのはいかがなものかと思います。どちらの補完機能を選ぶべきかという問題に対しては、両方とも生かして併用するというのが最適解であると考えます。

テンプレートのコメントを外してそのままで有効化すると、`TAB`キーが上書きされてしまうため、別の空いているキーをバインドします。
自分が押しやすいキーでよいと思いますが、下記に一例を示しておきます。

```text:clink_inputrc
M-x:                clink-menu-completion-shim
M-z:                clink-backward-menu-completion-shim
```

ここからは、この設定を前提に、dirコマンドの結果が下記となるケースでの補完操作を見ていきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513692/fb19bbd0-4aee-1f12-9f7d-de430119458b.png)

まず下図のようにコマンドラインを途中まで入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513692/11a5e5d0-356a-dc5a-3835-003e76688446.png)

次に、パラメータとしてファイル名を取得するために`TAB`キーを3回押下すると、下図のように最長一致するところまで補完した上で、候補をリスト表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513692/fb614726-a022-800e-fb50-1956547d7c15.png)

ここで`Alt+X`（順方向インライン補完）か`Alt+Z`（逆方向インライン補完）を押下してインライン補完を起動しますが、すぐには移行出来ません（出来ることもある）。
これはBash補完モードで動作中であるための制約によるものです。
いったんBash補完モードを中断しなければなりませんが、操作はEmacsに倣い`Ctrl+G`の押下となります。これによりインライン補完が可能となります。

インライン補完ではリストの列方向の順序に従ってピックアップされますので、目標が仮に`2022-01-01_13-15-33-917.log`であれば先頭からのほうが近いので`Alt+X`を3回押下してたどり着けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513692/677f6c1b-748b-62c7-f644-7ee41ef46f26.png)

目標が`2022-01-01_14-54-25-142.log`の場合は末尾から遡ったほうが早いので、`Alt+Z`を2回押下してゴールになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513692/6236d81b-3a81-0117-e264-ad494fb7a153.png)

この2つの補完機能は併用することを前提に開発されていないと思われるので、常にこのように目論見通りの結果が得られるとは限りませんが、ユースケースを見極めることが出来れば、かなり省力化が期待できるのではないかと考えられます。

## 最後に

今回の記事ではプログラミング言語Luaによるスクリプティングまではカバー出来ませんでしたが、インタラクティブ・シェルとして、PowerShellにも引けを取らないClinkの魅力を感じていただきたいと思い投稿しました。