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


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

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

なんかTrueColorが使えるらしい

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

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

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

Windows10の最新版なら、コマンドプロンプトで以下のようなコマンドを打てば色付きの文字が表示されるはずです(^[のところはコピペではなくCtrl+[を打つ必要がある1

echo ^[[33m aaa^[[m

Truecolor出力も試してみます(RGBで指定します)

echo ^[[38;2;85;197;m Qiitaっぽい^[[m
rem 背景色もつけてみる、見た目を揃えるため後ろにスペースを付けてる
echo ^[[38;2;85;197;m^[[48;2;255;255;255m Qiitaっぽい ^[[m

このようになります

下記ページを参考にしました

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

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

いつから対応してたん?

ANSIエスケープシーエンスは2015年11月の"Threshold 2(10.0.1058)"というアップデートで追加(復活?)されていたらしい
24bitTruecolorに関しては2017年のアップデートで追加されていたっぽいです

なぜかインストールしたフォントが使えた

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

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

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

先ほどのスクショもコマンドプロンプト自体の色がデフォルトのままだとこうなります

なんかあんまりそれっぽくないですよね?
なので、お好みの配色に変更してしまいましょう(ここが全体的に参考になります)

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

ちまちまと既定値から変更していきます(タスクバーにピン留めしている場合、タスクバーアイコンの実体はショートカットファイルなので先述の記事にあるようにそこから起動した際は以前の設定が使われてしまうため、ピン留めは一度外しておくのが無難3
画面の色→黒を46, 52, 64に変更、真ん中の灰色を236, 239, 244にすると、こうなります

本当なら他の色もNordのやつに定義しといたほうがいいんでしょうが(赤とか青とかの色指定時に使用される)、手動で設定するのはさすがに骨が折れるのでそのままにしてあります

先述のページのこの項にあるレジストリファイルをうまいこと改変してやればいい感じに設定できそうではありますが、自分で試してはないので確証はありません
頭に固定で00がついている16進色表記かと思いきや、軽く見比べてみた限りrrggbbではなくbbggrrの値のようです

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

ColorToolがよさそう

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

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

なお、ColorToolの使用方法についてはこちら等が参考になりそうです
あとはReadmeを見ましょう
2022年3月時点での最新リリースはここらしい

→使ってみたけどなかなかいい感じ。注意点としては、

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

ただ、ここまで頑張っても(多分)完璧ではない

具体的には

  • batの使用時に罫線が途切れる

    • Alacritty使用時には正常に表示される、デモを見ても明らかに不具合
  • 適用されないANSIエスケープシーケンスの効果がある(それも一般的なものと思われるやつ)

    • ansi-color.cmdでテスト、事前に要chcp 65001実行&フルスク化
    • 具体的にはBold(太字)、Faint(薄字?)、Conceal(「包み隠す」、文字色と背景色が同じになる)、Crossed-out(打消し線)、Double Underline(二重打消し線、Alacrittyでも動作せず)
    • 逆に動作するのはUnderline(下線)、Reverse video(文字色と背景色を反転)のみだった
    • Alacrittyでも適用されない効果はあるし、(主に点滅(Blink)関連、Faintはテーマが対応していないだけで動作するかも)ここで試していないもの含むその全てに対応すべきとは思わないけど、にしても動作しないのが多い気がする。まぁしょうがないけど
  • Powershellも同じ見た目に変わってしまう(conhost.exe側で設定しているため?)

    • やり方がありそうな気はするけど、ぱっと見見分けづらい。そんなにPowershell使わないしいいけど

参考になるかもしれないリンクの羅列(主にtruecolor関連)

Windows Consoleでも256color、さらにtrue colorなEmacsする - つーさにブログ
20年越しの悲願、コンソールが24bitカラーに対応 ~「Windows 10 Insider Preview」Build 16257 - 窓の杜

本当に Windows10 のコマンドプロンプトはエスケープシーケンスをサポートしたのか? - Qiita
第3章5 エスケープシーケンスで文字の色、背景の色を変更 - Nodachisoft
コンソールの仮想ターミナル シーケンス - Windows Console | Microsoft Docs
ANSI escape code - Wikipedia - ANSIエスケープシーケンスに関する包括的な内容、よく使うであろうSGR(?)のとこにヘッダ指定してる

古いWindows 10でコマンドプロンプトのカラーテーマをアップグレードする - sgryjp.log
ColorTool を使ってコンソールを見やすくする - Qiita
terminal/src/tools/ColorTool at main · microsoft/terminal · GitHub

24-bit Color in the Windows Console! - Windows Command Line - TrueColorサポートのアナウンス
Understanding Windows Console Host Settings - Windows Command Line - MS開発者ブログによるconhost.exeの設定の解説
Updating the Windows Console Colors - Windows Command Line - デフォルトのコンソール色設定更新のアナウンス
Introducing the Windows Console Colortool - Windows Command Line - MS開発者ブログによるColorToolの紹介

  1. Alacrittyでもできないかといろいろと試しては見たんですが、- { key: LBracket, mods: Control, chars: "\x1b" }という風に設定しても現時点ではできませんでした...(なぜかReceiveCharのような挙動になる。Altキーでも不可)まぁターミナルから入力できなくともプログラムからなら対応してるのは明らかなのでヨシ!
    ちなみに、Back(BackSpaceのことらしい)にaction: ReceiveCharを割り振っても実行されないが、chars: "\x1b"を割り振るとなぜか望ましき挙動になるというバッドノウハウを確認した(追記:素のcmdでEscキーを押すとReceiveCharの挙動になるのでそれが関係してるのかも)

  2. 実は元になったフォントFira monoではスラッシュゼロではないらしいので、私はFira monoではなくFirgeしか使えない(FiraCodeをリガチャ解除して使えばいけそうではある)

  3. ショートカットファイルの実体は 起動していない状態でピン留めされたアイコンをShift+右クリック→プロパティからいじれます

  4. まぁ細かいところはエディタやらのプログラム側が自分でよしなにやってくれるでしょうしね