[Windows]Clinkリスタートマニュアル

## そもそもClinkとは何か

[Clink][1]とは、Windowsのコマンドプロンプトで、Linuxで標準のシェルである[GNU Bash][2]と同様の操作性の実現を目指し、行編集ライブラリ[GNU Readline][3]を実装することにより、コマンドプロンプトの機能を拡張して利便性の向上を実現出来るユーティリティです。

[1]:https://mridgers.github.io/clink/
[2]:https://www.gnu.org/software/bash/
[3]:https://ja.wikipedia.org/wiki/GNU_Readline

https://mridgers.github.io/clink/

私自身もWindows PCをシンクライアントとして、クラウド上の仮想マシンでLinuxを利用している。今では標準的といえるLinuxユーザーです。<br>
そのためWindowsのコマンドプロンプトを使用する際、Bashとは大幅に操作性が変わってしまうと、違和感でストレスを感じてしまうため、そのギャップを緩和するためにも、大いに役立ってくれています。

「LinuxもWindowsも両方[PowerShell][4]に統一すればいいのでは」という声が聞こえてきそうですが、今のところLinuxではBashの標準のシェルとしての地位が揺らぎそうな様子は見当たりません。

[4]:https://docs.microsoft.com/ja-jp/powershell/

またClinkにはcmd.exeにもBashにも備わっていない独自の機能も用意されており、導入する価値は十分に感じられています。

## 導入と起動方法

まず[公式サイト][1]から[インストーラー][5]または[ZIPファイル][6]をダウンロードしますが、ここではZIP版を使います。

[5]:https://github.com/mridgers/clink/releases/download/0.4.9/clink_0.4.9_setup.exe
[6]:https://github.com/mridgers/clink/releases/download/0.4.9/clink_0.4.9.zip

ZIPファイルを展開すると`clink.bat`というバッチファイルが有るので、これを実行すれば新しウィンドウでClinkが起動します。<br>
既に開いているウィンドウで起動する場合は、下記のようにコマンドを実行します。exeファイルがあるディレクトリ以外から起動する場合は、exeファイルをフルパスで指定します。

```powershell
cmd /k clink_x64.exe inject --nolog
```

64bit環境の例です。またログファイルを出力しないようにオプションを指定しています。指定しなければ、ユーザーディレクトリにログファイルが保存されて残ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513692/e3fd2a80-df66-9ae7-1b45-df9446a28252.png)

## 基本的な操作方法

ここからはキーマップはデフォルトのEmacsモードを前提とした基本操作です。なお、ここに挙げたものはほんの一部。後述のヘルプ機能を使いましょう。

#### 〈行編集機能〉

|キー              |機能
|:----------------:|:------------------------------------------------------
| カーソル←・→      |それぞれ一文字ずつカーソルを戻す・進める
| Alt+F・Alt+B     |それぞれ1ワードずつカーソルを進める・戻す
| Ctrl+A・Ctrl+E   |それぞれ行の先頭・末尾にカーソルを移動
| BS・DEL          |それぞれカーソルの直前・直下の一文字を削除
| Alt+BS・Alt+D  　|それぞれカーソルの直前・直下から単語の先頭・末尾までを削除
| カーソル↑・↓　    |それぞれ行の入力履歴を時系列の過去・現在向きで参照
| TAB              |コマンド名・ファイル名・環境変数名の補完および候補の一覧
| Ctrl+U・Ctrl+K   |それぞれ直前・直下から行の先頭・末尾までを削除
| Ctrl+R・Ctrl+S   |入力履歴に含まれる文字列で過去向き・現在向きで検索しインクリメンタルに候補を参照
| Alt+R            |履歴から修正したコマンド行を元の状態に戻す。

#### 〈よく使うショートカットキー〉

`Ctrl+L`　画面クリア。`cls`コマンドは3文字なのでタイプが苦にはならないのですが、これが入力履歴に残ってしまうと、ちょっと煩わしく感じます。また、こちらは途中までコマンドを入力している途中でも、それは残したままで、ターミナルに残っている過去の出力を消去できます。

**【注】** 時々、入力履歴の参照中に動作が不安定になり、コマンドラインの表示が乱れることがありますが、その際にはいったん`Ctrl+C`などで中断した上で`cls`コマンドを実行すると多くの場合回復できます。`Ctrl+L`は`cls`コマンドほど強力ではないため、使い分けなければならないこともあります。

`Ctrl+D`　ターミナルの終了。これも`exit`を入力履歴に残したくないので、積極的に使いたいものです。

`Alt+H`　キー割り当ての一覧表示。`Ctrl+L`と同じく、コマンド入力の途中でも可。

## 使いこなすためのノウハウ
ここまでのところで感じられるメリットとしては、「Bashと併用し易い」「入力履歴が消去されず永続化できる」といったところでしょうか。<br>
ここからは、今までフィーリングである程度は使っているが、あまり深くは踏み込むことが無かったという方を想定し、いわゆる「今さら聞けない」シリーズに倣った再入門編へと進みます。

さらに使い勝手を向上するためには、設定ファイルの編集が必要になってきます。Clinkにはメインとなる設定ファイルが2つ用意されています。<br>
設定ファイルの構成にはいくつかバリエーションが有りますが、この記事では、いずれもインストールしたディレクトリ直下の`profile`ディレクトリに配置されていることを前提にします。

|ファイル名         |設定内容
|:-----------------|:----------------------------------
|settings          |Clink本体の動作をカスタマイズ
|clink_inputrc     |Readlineのキーバインドのカスタマイズ

#### キーバインドに関する考察

まず`settngs`の設定ですが、基本的に直接ファイルを編集せず、`clink`コマンドで行います。下記のコマンドで設定します。

```powershell
>clink set esc_clears_line 0
Settings 'esc_clears_line' set to '0'
```

これはコマンドプロンプトでは本来、`ESC`キーに割り当てられている入力中のコマンド行を消去する機能を無効にする設定です。`clink set`コマンドで設定を変更した際は、いったんClinkを終了して再度起動することにより、実際に反映されます。<br>
これで`ESC`キーを他の目的で利用できるようになります。この設定を前提として、ここからさらにの機能について述べていきます。

#### 〈その他便利な機能〉
|キー　　　                 |機能
|:-------------------------|:----------------------------------
|Alt+Ctrl+U                |一つ上のディレクトリへ移動＊
|Alt+Ctrl+E                |環境変数のインライン展開
|Alt+Ctrl+]                |カーソルより前の特定1文字の検索
|Alt+Ctrl+J（Emacsモード時）|キーマップをviモードに移行＊
|Ctrl+E（viモード時）       |キーマップをEmacsモードに移行＊

＊マークはClink独自の追加機能  

まず目につくのは装飾キーを2つ併用するキーバインドだと思いまが、Emacsユーザーなら見慣れたものだと思います。しかし、あまり馴染みがない方も割と多いのではないでしょうか？　そういう方のために、このキーバインドに関しては少し解説しておきます。<br>
なお、私がMacに関しては知識を持ち合わせていないため、ここでは触れませんのでよろしくお願いいたします。

私もEmacs使用時は正規表現での検索機能がバインドされている`Alt+Ctrl+S`などはよく使っていますが、実際に3つのキーを同時押しするような押し方をしている方というは、まずいないのではないかと思います（いたら、すみません）。

これらのキーの表記は、`Alt`キーを必ず備えているWindows PCを前提にしていますが、メインフレーム系の端末などでは代わりに`Meta`キーをこのキーに割り当てています。
文字キーと違い、装飾キーはさまざまなバリエーションが存在し、一概には当てはめることが
出来ません。

またEmacsはもともとはLinuxなどでメジャーなエディタなので、`Alt`キーを使わない代替手段で対応出来るようになっています。<br>
`Alt`キーが無い、または使いたくない場合は、プレフィックスとして`ESC`キーを押下することにより代用します。`ESC+Ctrl+E`といった押し方ではなく、`ESC, Ctrl+E`という2ストロークでの操作になります。
これにより、3キー同押しのたびに、視線を手許に移さなければならないという問題は避けられますが、代わりに`ESC`の位置が遠いために「使うのが億劫になる」という懸念が生じてくると思います。

そこで、さらにキーの解釈を広げます。`ESC`キーが無いキーボードというのが存在するかどうかは存じませんが、そもそも`ESC`キーとは、エスケープシーケンスの開始となる`Ctrl+[`のキーコードを送出するためのショートカットの役割を持っているものです。
この解釈に基づき、先の例でいうと`Ctrl+[`, `Ctrl+E`というキーバインドに展開することができます。より実践的には`Ctrl`押しっぱなしでの操作、少し強引ですが算術演算子を使って表すと`Ctrl+([, E)`という押し方が多くなってくると思います。

さすがに`Shift`と`Ctrl`キーが備わっていないキーボードというのは考えられませんが、もしそれが有り得た場合は、こればかりは為す術べが無く、もはやお手上げになるものと思います。
話を戻しますが、上記の説明はEmacsユーザーには蛇足だったかもしれません。しかし便利な機能を使うためなので、念のために入れておきました。親ディレクトリへの移動機能も、やはり履歴に残さないためにも役に立ちます。

#### 入力履歴の検索操作

このセクションはBashと共通のノウハウになりますが、多くの資料ではリファレンスの提示にとどまっていることが多いため、ここではユースケースに沿った、操作方法を解説したいと思います。
まず履歴検索をフルに活用するため、設定ファイル`Clink_inputrc`をメモ帳などで下記の内容で作成し、所定のディレクトリに保存しておきます。

```text:clinck_inputrc
M-p:                history-search-backward
M-n:                history-search-forward
```

この設定により履歴のインクリメンタル検索だけでなく、前方一致検索も利用できるようになります。
インクリメンタル検索の場合は、検索動作中に入力した文字が行のどこか一部と一致する履歴を候補として提示しますが、前方一致検索とは現在行のカーソルの位置までの文字列と、行の前方が一致する履歴のみを検索結果として提示する機能を指します。
上記の設定では`Alt+P`で時系列の過去へ、`Alt+N`で現在へ向かって検索します。

履歴検索機能が2種類になり、ケースバイケースで使い分けることにより利便性が向上できますが、両方を組み合わせて利用することにより、さらに利便性を向上できます。

目的の履歴の行の始まりが判らない場合、または初めから前方一致検索では候補が多くなりすぎる場合は、まずはインクリメンタル検索から始めます。具体的にはパスの一部やオプション、パラメータ、ファイル名といったものを検索の手掛かりにすることになると思います。<br>
下図はインクリメンタル検索を開始し`note`までタイプした例です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513692/dd55318c-a3c3-c850-8594-c4c6c926b180.png)

検索文字を修正したり、`Ctrl+R`や`Ctrl+S`押下での再検索を実行しつつ、カーソルの前方に目的の文字列を呼び出すようにします。とにかく行の前方から確定していくのが基本方針です。
下図は求めていたコマンドオプションが呼び出せたところです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513692/dbe6fbdf-e00c-7368-07d7-c37d3b9c3a2c.png)

カーソルの前方が目的の文字列となったところで、今度は前方一致検索を開始します。いったんインクリメンタル検索を終了する必要もなく、即`Alt+P`押下で検索方法を切り替えられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513692/25d90037-c2ff-206f-f601-949fa9b68b12.png)

その際、必要に応じてカーソルを前後に移動して、前方一致させる文字列を調整し、効率よく検索できるよう工夫します。カーソルを前方に戻すほど、ヒットする候補が増え、後方に進めるほど減っていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513692/8cab6ee4-c6de-993b-5432-b73b669498f5.png)

最終的にコマンド行が希望のものと一致したところで`Enter`押下で実行するか、または最も希望に近い文字列となったところで、入力履歴を適宜修正して実行します。


#### 〈Clinkの残念なところ〉
LinuxなどでBashを使っている方は`clink_inputrc`にあたる`.inputrc`に下記のような設定を追記しているケースがあると思います。

```text:.inputrc
"\e[A":history-search-backward
"\e[B":history-search-forward
```

前方一致検索を、時系列による履歴参照と同じカーソル↑・↓というキー操作に割り当てるための設定です。このように設定しておいても、カーソルを行の先頭にもっていけば、時系列による履歴参照機能を使えるため、この設定を好む方もいるようです。

しかし、Clinkではカーソルキー単体に任意の機能を割り当てることは出来ないようなので、この設定は機能しません。
私の場合はLinuxとWindowsでなるべく操作感覚を共通にしたいので、Clinkのほうに合わせています。上記と同様に一般的な設定として、Bashでも`Alt+P`と`Alt+N`にバインドしています。

## 終わりに

何とか少しでもClinkの魅力を伝えられるようにと、便利な機能を紹介させていただいたつもりですが、OSベンダーのサポートするPowerShellは優位性を保っているのが現状だとは思います。
LinuxでもPowerShellは使えるようになっていますが、私自身も過去にZSHやFish Shellに切り替えてみたことがありますが、結局Bashに戻してしまったという経験も持っているので、Bashの優位性も大きいものと思います。
この記事で、Windows環境でもBashライクな操作感覚を味わえるClinkを、一度体験してみようと思っていただくことが出来たら幸いです。