cmd.exeの見た目をがんばっていい感じにする

cmd.exe（コマンドプロンプト）、起動速度だけでいえば最速ではあるものの見た目はそこまでなぁ...って感じだと思います（少なくともデフォルトでは）
私もそういう印象があったので、細かいカスタマイズが可能で起動も早いAlacrittyに移行するまではCLIツールとは無縁だったのですが、ふとcmdでCLIツールを使ってみたらどうなるんだろう？と思ったのが始まりです
どうせカスタマイズ性も低いんだろうと長いこと思い込んでいましたが、それも今は昔で最近(Windows10)ではわりとカスタマイズできるっぽいな貴様？となったのでちょっと試してみました

## なんかTrueColorが使えるらしい
以前cmdから[bat]（Rust製のコマンドのほう）を使った際にはフルカラー表示されなかったので「あぁ、cmd.exeはTrueColorとやらに対応していないんだなー」となっていましたが、[Helix]をコマンドプロンプトで動かしてみて衝撃が走ります

なんとフルカラー（この語が正しいかはわからない、正確にはTrueColor/24bitカラー？）表示されているではありませんか！

調べてみると、プログラム側から使う場合にはAPIを通してちょろっとフラグを立てる(?)ことによりANSIエスケープシーケンスとやらが使えるらしいです（[参考](https://qiita.com/zetamatta/items/0c6130bd631491b97844)）
プログラム側が対応してくれてさえいればユーザー側は何もせずとも表示してくれるっぽい

Windows10の最新版なら、コマンドプロンプトで以下のようなコマンドを打てば色付きの文字が表示されるはずです（`^[`のところはコピペではなくCtrl+[を打つ必要がある[^2]）
```bat
echo ^[[33m aaa^[[m
```
Truecolor出力も試してみます（RGBで指定します）
```bat
echo ^[[38;2;85;197;m Qiitaっぽい^[[m
rem 背景色もつけてみる、見た目を揃えるため後ろにスペースを付けてる
echo ^[[38;2;85;197;m^[[48;2;255;255;255m Qiitaっぽい ^[[m
```
このようになります
![実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2327338/2a443888-0de0-eb49-013c-c0c468cb57f0.png)
下記ページを参考にしました

https://tsuu32.hatenablog.com/entry/2019/08/04/135347

で、なぜ[bat]だとtruecolorで出力されなかったのかという話ですが、恐らくは`COLORTERM`環境変数を`truecolor`(or`24bit`)に設定していなかったためだと思われます（Alacrittyだと自動で`COLORTERM=truecolor`という環境変数が設定されている）
Readmeに「COLORTERM変数がtruecolorか24bitに設定されてないと24bitエスケープシーケンスがサポートされてるかどうか判断できないよ、その場合8bitカラーで表示されるよ」というふうなことが書いてある（[参考](https://github.com/sharkdp/bat#terminals--colors)）

んで、Helixの場合は[ドキュメント](https://docs.helix-editor.com/configuration.html#editor-section)の`true-color`のところを見るにtruecolorが有効かどうかを自動で検出するシステムがあるっぽいです（英語弱者すぎてよくわからんけどたぶんそんな感じ）
今見ると、batから参照のある[TrueColor準拠のターミナルのリスト](https://gist.github.com/XVilka/8346728)にガッツリ載ってますね...どうせ対応してないんだろうと思っちゃってた

### いつから対応してたん？
ANSIエスケープシーエンスは[2015年11月の"Threshold 2(10.0.1058)"というアップデートで追加（復活？）](https://srad.jp/story/16/02/09/0639223/)されていたらしい
24bitTruecolorに関しては[2017年のアップデート](https://forest.watch.impress.co.jp/docs/news/1074095.html)で追加されていたっぽいです

## なぜかインストールしたフォントが使えた
どういう理屈かは知りませんが、インストールして使っていたフォント（Firge[^1]）がプロパティ（タイトルバー右クリから開けます）から選択できました
なんで？？？
以前は「プロパティ」のところにはなくて「既定値」のところにのみなぜか出てきたのを覚えているので、以前はできなかったと思うんですがなぜか一覧に表示ました（その時既定値側で選択したから？）
普通はレジストリをいじらないといけないものだと思っていましたし実際そうだと思うのですが、自分としては「レジストリいじるのは面倒だしなぁ...」って感じだったのでラッキーでした

どういう仕組みなんだろうか...インストールされたものの中から等幅フォントを自動認識してレジストリに登録しているのかな？
`HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts`にFirgeがインストールされてるよーってデータがあって、HKLM側の同位置や本来手動で追加する位置と思われる`HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont`にはFirgeのデータはなかったので、インストールしたときorなにかしらのソフトで使用する設定にした際にユーザー設定側にこのデータが追加されたとかになるんだろうか...?...うーんわからん！
まぁ好きなフォントが使えるようになるってのは大きいよねとだけ...

## コマンドプロンプト自体の色設定を変更する

先ほどのスクショもコマンドプロンプト自体の色がデフォルトのままだとこうなります
![画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2327338/c402cba6-960f-d18d-4e6b-7b53a3dba01b.png)
なんかあんまりそれっぽくないですよね？
なので、お好みの配色に変更してしまいましょう（[ここ][sgry.jp]が全体的に参考になります）

私は普段Alacrittyではgruvbox(dark)テーマやeverforest(dark)テーマ等を使用していますが、cmdではちょっと趣向を変えてNordっぽい色を使ってみようかとなりました

ちまちまと既定値から変更していきます（タスクバーにピン留めしている場合、タスクバーアイコンの実体はショートカットファイルなので先述の記事にあるようにそこから起動した際は以前の設定が使われてしまうため、ピン留めは一度外しておくのが無難[^3]）
画面の色→黒を46, 52, 64に変更、真ん中の灰色を236, 239, 244にすると、こうなります
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2327338/70eee89d-2205-451c-3f9c-69c2b0177f2e.png)
本当なら他の色もNordのやつに定義しといたほうがいいんでしょうが（赤とか青とかの色指定時に使用される）、手動で設定するのはさすがに骨が折れるのでそのままにしてあります

~~先述のページの[この項](https://blog.sgry.jp/entry/2017/08/11/183229#%E3%82%AB%E3%83%A9%E3%83%BC%E3%83%86%E3%83%BC%E3%83%9E%E3%82%92%E8%A6%8F%E5%AE%9A%E5%80%A4%E3%81%AB%E9%81%A9%E7%94%A8%E3%81%99%E3%82%8B)にあるレジストリファイルをうまいこと改変してやればいい感じに設定できそうではありますが、自分で試してはないので確証はありません
頭に固定で00がついている16進色表記かと思いきや、軽く見比べてみた限り`rrggbb`ではなく`bbggrr`の値のようです~~

~~[サクラエディタで使われてるやつ](https://gist.github.com/tsuyoshicho/a06b315e8ee952929763)とかと同じっぽいけど、どこ発祥なんだろう？レジストリ含むWindows関連の技術で使われてる感じっぽいけど（変換するの面倒くさい）
→リトルエンディアンでDelphiが残した云々って出てきたけど、詳しいことはよくわからなかった...~~

### [ColorTool]がよさそう
[ColorTool]のことを思い出しました
どうやら主にiTermカラースキームからインポートすることを想定されているようですが、なんだか手書きするにはつらそうなフォーマットなので（Readmeにあるように[ mbadolato/iTerm2-Color-Schemes](https://github.com/mbadolato/iTerm2-Color-Schemes)から引っ張ってきてもいいですが）デフォルトのファイルがそうされているようにiniファイルから定義できれば楽そうです（マイナーテーマ使用者並の感想）

iniファイルはターミナルとかの色設定にありがちな[^4]ANSIカラー16色（通常8色、明るめの8色）とプライマリの背景色と文字色とかのちょろっとしたのをRGBで定義するだけのシンプルな形式っぽいので（[参考](https://github.com/microsoft/terminal/blob/main/src/tools/ColorTool/schemes/campbell.ini)）、自分で手書きするにしてもお手軽にできそう（Readme見るになんかjsonフォーマットも読めるらしい、恐らくWindows Terminalのやつ用だと思われ）
可読性も高いし（~~`.itermcolors`は見ればわかるようにヒューマンフレンドリーじゃない~~）

なお、ColorToolの使用方法については[こちら](https://qiita.com/ysk_n/items/21d9e3fb8b8f22ab3476)等が参考になりそうです
あとは[Readme][ColorTool]を見ましょう
2022年3月時点での最新リリースは[ここ](https://github.com/microsoft/terminal/releases/tag/1904.29002)らしい

→使ってみたけどなかなかいい感じ。注意点としては、
- `colortool -o hoge.ini`で現在の設定を`hoge.ini`としてカレントディレクトリに出力できる（ini形式）
	- もちろん`colortool -o schemes\hogehoge.ini`のようにすれば出力ディレクトリを指定できる
- カラースキームの配置先はカレントディレクトリに関係なく`ColorTool.exe\schemes\`ディレクトリになるらしい
- インポートする際には拡張子までつける必要がある、例: `colortool onehalfdark.itermcolors`

## ただ、ここまで頑張っても（多分）完璧ではない
具体的には
- [bat]の使用時に罫線が途切れる
	- Alacritty使用時には正常に表示される、デモを見ても明らかに不具合

- 適用されないANSIエスケープシーケンスの効果がある（それも一般的なものと思われるやつ）
	- [ansi-color.cmd](https://github.com/microsoft/terminal/tree/main/src/tools/ansi-color)でテスト、事前に要`chcp 65001`実行＆フルスク化
	- 具体的にはBold（太字）、Faint（薄字？）、Italic（斜体）、Conceal（「包み隠す」、文字色と背景色が同じになる）、Crossed-out（打消し線）、Double Underline（二重打消し線、Alacrittyでも動作せず）
	- 逆に動作するのはUnderline（下線）、Reverse video（文字色と背景色を反転）のみだった
	- Alacrittyでも適用されない効果はあるし、（主に点滅(Blink)関連、Faintはテーマが対応していないだけで動作するかも）ここで試していないもの含む[その全て](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters)に対応すべきとは思わないけど、にしても動作しないのが多い気がする。まぁしょうがないけど

- Powershellも同じ見た目に変わってしまう（conhost.exe側で設定しているため？）
	- やり方がありそうな気はするけど、ぱっと見見分けづらい。そんなにPowershell使わないしいいけど

## 参考になるかもしれないリンクの羅列（主にtruecolor関連）
[Windows Consoleでも256color、さらにtrue colorなEmacsする - つーさにブログ](https://tsuu32.hatenablog.com/entry/2019/08/04/135347)
[20年越しの悲願、コンソールが24bitカラーに対応 ～「Windows 10 Insider Preview」Build 16257 - 窓の杜](https://forest.watch.impress.co.jp/docs/news/1074095.html)

[本当に Windows10 のコマンドプロンプトはエスケープシーケンスをサポートしたのか？ - Qiita](https://qiita.com/zetamatta/items/0c6130bd631491b97844)
[第３章５ エスケープシーケンスで文字の色、背景の色を変更 - Nodachisoft](https://nodachisoft.com/common/jp/article/jp000152/)
[コンソールの仮想ターミナル シーケンス - Windows Console | Microsoft Docs](https://docs.microsoft.com/ja-jp/windows/console/console-virtual-terminal-sequences?redirectedfrom=MSDN)
[ANSI escape code - Wikipedia](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters) - ANSIエスケープシーケンスに関する包括的な内容、よく使うであろうSGR(?)のとこにヘッダ指定してる

[古いWindows 10でコマンドプロンプトのカラーテーマをアップグレードする - sgryjp.log](https://blog.sgry.jp/entry/2017/08/11/183229)
[ColorTool を使ってコンソールを見やすくする - Qiita](https://qiita.com/ysk_n/items/21d9e3fb8b8f22ab3476)
[terminal/src/tools/ColorTool at main · microsoft/terminal · GitHub](https://github.com/microsoft/terminal/tree/main/src/tools/ColorTool)

[24-bit Color in the Windows Console! - Windows Command Line](https://devblogs.microsoft.com/commandline/24-bit-color-in-the-windows-console/) - TrueColorサポートのアナウンス
[Understanding Windows Console Host Settings - Windows Command Line](https://devblogs.microsoft.com/commandline/understanding-windows-console-host-settings/) - MS開発者ブログによるconhost.exeの設定の解説
[Updating the Windows Console Colors - Windows Command Line](https://devblogs.microsoft.com/commandline/updating-the-windows-console-colors/) - デフォルトのコンソール色設定更新のアナウンス
[Introducing the Windows Console Colortool - Windows Command Line](https://devblogs.microsoft.com/commandline/introducing-the-windows-console-colortool/) - MS開発者ブログによるColorToolの紹介


[bat]: https://github.com/sharkdp/bat
[Helix]: https://github.com/helix-editor/helix
[sgry.jp]: https://blog.sgry.jp/entry/2017/08/11/183229 "古いWindows 10でコマンドプロンプトのカラーテーマをアップグレードする - sgryjp.log"
[ColorTool]: https://github.com/microsoft/terminal/tree/main/src/tools/ColorTool

[^1]: 実は元になったフォントFira monoではスラッシュゼロではないらしいので、私はFira monoではなくFirgeしか使えない（FiraCodeをリガチャ解除して使えばいけそうではある）
[^2]: Alacrittyでもできないかといろいろと試しては見たんですが、`- { key: LBracket, mods: Control, chars: "\x1b" }`という風に設定しても現時点ではできませんでした...（なぜかReceiveCharのような挙動になる。Altキーでも不可）まぁターミナルから入力できなくともプログラムからなら対応してるのは明らかなのでヨシ！
ちなみに、Back（BackSpaceのことらしい）に`action: ReceiveChar`を割り振っても実行されないが、`chars: "\x1b"`を割り振るとなぜか望ましき挙動になるというバッドノウハウを確認した（追記：素のcmdでEscキーを押すとReceiveCharの挙動になるのでそれが関係してるのかも）
[^3]: ショートカットファイルの実体は 起動していない状態でピン留めされたアイコンをShift+右クリック→プロパティからいじれます
[^4]: まぁ細かいところはエディタやらのプログラム側が自分でよしなにやってくれるでしょうしね