仮想端末にCTOを表示する

経緯

前職ではチームの先輩や隣のチームのリーダーのアイコンを色つきAAにして.bashrcで表示するようにしていたが、はてな入社後は特にそういったことをしておらず、まずいと思ったため勢いで実装した。

必要なもの

  • 色つきAAにして可視性が高いアイコンをしている同僚
    • 偶然にもCTOのアイコンがtodefyされていたので助かった
    • todefyされていると非常に楽だが、されてなくてもうまくやれば良い感じのAAにはできる
    • 最惡は自分で人のアイコンをtodefyしてください
  • ANSI escape code/SGR(Select Graphic Rendition) parameterの知識

スクリプト

motemenさんを表示したい人はこれでできます。たぶん。

echo -e '\x1b[48;2;195;213;227m \x1b[m\x1b[48;2;195;213;227m \x1b[m\x1b[48;2;252;255;246m \x1b[m\x1b[48;2;252;255;246m \x1b[m\x1b[48;2;19;58;137m \x1b[m\x1b[48;2;19;58;137m \x1b[m\x1b[48;2;157;167;185m \x1b[m\x1b[48;2;157;167;185m \x1b[m\n\x1b[48;2;129;82;38m \x1b[m\x1b[48;2;129;82;38m \x1b[m\x1b[48;2;255;224;211m \x1b[m\x1b[48;2;255;224;211m \x1b[m\x1b[48;2;248;199;182m \x1b[m\x1b[48;2;248;199;182m \x1b[m\x1b[48;2;218;46;32m \x1b[m\x1b[48;2;218;46;32m \x1b[m\n\x1b[48;2;164;172;193m \x1b[m\x1b[48;2;164;172;193m \x1b[m\x1b[48;2;254;196;184m \x1b[m\x1b[48;2;254;196;184m \x1b[m\x1b[48;2;255;179;162m \x1b[m\x1b[48;2;255;179;162m \x1b[m\x1b[48;2;225;107;93m \x1b[m\x1b[48;2;225;107;93m \x1b[m\n\x1b[48;2;174;179;183m \x1b[m\x1b[48;2;174;179;183m \x1b[m\x1b[48;2;55;62;68m \x1b[m\x1b[48;2;55;62;68m \x1b[m\x1b[48;2;83;32;13m \x1b[m\x1b[48;2;83;32;13m \x1b[m\x1b[48;2;89;90;95m \x1b[m\x1b[48;2;89;90;95m \x1b[m'

良く見ると SGRの指定 (空白1つ) デフォルトに戻すSGR としているが、SGRの指定 (空白2つ) デフォルトに戻すSGR とした方が短くて済む。このあたり片手間でやってたのでそんなに頭が働いていない

ANSI escape code/SGR

平たく言えば、仮想端末上でカラーリングや動的に変化する情報の表示(htopとかみたいな)などに使われている仕組み。

今回使うSGRの機能としては文字の背景色の切り替えとなる。

これは、\x1b[48;2;<r>;<g>;<b>m を仮想端末上でエンコードして出力すると、その後の文字の出力時に文字背景色が指定した r g b の値に対応する色となる。という機能である。

背景色の指定の例

これはもう1度SGRの機能で表示設定を変更しない限り続く、これを解除するには \x1b[m を仮想端末上でエンコードして出力する必要がある。*1

表示設定をデフォルトに戻す例

今回の場合偶然にも以下のリポジトリにCTOのアイコンの各色のカラーコードが記載されていたのでNode.jsで雑に生成することができた。改行と幅の調整だけ手作業で入力した。 github.com

const m  = [
   "c3d5e3", "fcfff6", "133a89", "9da7b9",
   "815226", "ffe0d3", "f8c7b6", "da2e20",
   "a4acc1", "fec4b8", "ffb3a2", "e16b5d",
   "aeb3b7", "373e44", "53200d", "595a5f"
 ];
 m.map(c => c.match(/\w{2}/g).map(c => Number.parseInt(c, 16))).map(([r,g,b]) => `\x1b[48;2;${r};${g};${b}m \x1b[m`).map(c => `${c}${c}`).join('');

簡単なやり方

画像をカラーつきAAに変換するツールでHTMLを生成→CLIブラウザ等で表示→その出力をリダイレクトしてテキストファイルに保存。

そうするとSGRも含めて良い感じのテキストが得られるので、後は頑張れば良い感じになる。この場合 \x1b[38;2;<r>;<g>;<b>m での文字色の変更も含まれていたりするので先ほどの手作業よりも表現力の高いAAが仮想端末上で表示できる。

さすがにtodefyアイコンよりは手間がかかるが…

前職ではそういう感じで頑張っていた。

まとめ

現職同僚各位で「俺のアイコンを仮想端末に表示してくれ」という人がいたら連絡ください。

現在の様子(PS1で表示するようにした)

追記: PS1で表示したい人向け(大きいサイズ)

export PS1="\\n\\e[48;2;195;213;227m        \\e[m\\e[48;2;252;255;246m        \\e[m\\e[48;2;19;58;137m        \\e[m\\e[48;2;157;167;185m        \\e[m\\n\\e[48;2;195;213;227m        \\e[m\\e[48;2;252;255;246m        \\e[m\\e[48;2;19;58;137m        \\e[m\\e[48;2;157;167;185m        \\e[m\\n\\e[48;2;195;213;227m        \\e[m\\e[48;2;252;255;246m        \\e[m\\e[48;2;19;58;137m        \\e[m\\e[48;2;157;167;185m        \\e[m\\n\\e[48;2;195;213;227m        \\e[m\\e[48;2;252;255;246m        \\e[m\\e[48;2;19;58;137m        \\e[m\\e[48;2;157;167;185m        \\e[m\\n\\e[48;2;129;82;38m        \\e[m\\e[48;2;255;224;211m        \\e[m\\e[48;2;248;199;182m        \\e[m\\e[48;2;218;46;32m        \\e[m\\n\\e[48;2;129;82;38m        \\e[m\\e[48;2;255;224;211m        \\e[m\\e[48;2;248;199;182m        \\e[m\\e[48;2;218;46;32m        \\e[m\\n\\e[48;2;129;82;38m        \\e[m\\e[48;2;255;224;211m        \\e[m\\e[48;2;248;199;182m        \\e[m\\e[48;2;218;46;32m        \\e[m\\n\\e[48;2;129;82;38m        \\e[m\\e[48;2;255;224;211m        \\e[m\\e[48;2;248;199;182m        \\e[m\\e[48;2;218;46;32m        \\e[m\\n\\e[48;2;164;172;193m        \\e[m\\e[48;2;254;196;184m        \\e[m\\e[48;2;255;179;162m        \\e[m\\e[48;2;225;107;93m        \\e[m\\n\\e[48;2;164;172;193m        \\e[m\\e[48;2;254;196;184m        \\e[m\\e[48;2;255;179;162m        \\e[m\\e[48;2;225;107;93m        \\e[m\\n\\e[48;2;164;172;193m        \\e[m\\e[48;2;254;196;184m        \\e[m\\e[48;2;255;179;162m        \\e[m\\e[48;2;225;107;93m        \\e[m\\n\\e[48;2;164;172;193m        \\e[m\\e[48;2;254;196;184m        \\e[m\\e[48;2;255;179;162m        \\e[m\\e[48;2;225;107;93m        \\e[m\\n\\e[48;2;174;179;183m        \\e[m\\e[48;2;55;62;68m        \\e[m\\e[48;2;83;32;13m        \\e[m\\e[48;2;89;90;95m        \\e[m\\n\\e[48;2;174;179;183m        \\e[m\\e[48;2;55;62;68m        \\e[m\\e[48;2;83;32;13m        \\e[m\\e[48;2;89;90;95m        \\e[m\\n\\e[48;2;174;179;183m        \\e[m\\e[48;2;55;62;68m        \\e[m\\e[48;2;83;32;13m        \\e[m\\e[48;2;89;90;95m        \\e[m\\n\\e[48;2;174;179;183m        \\e[m\\e[48;2;55;62;68m        \\e[m\\e[48;2;83;32;13m        \\e[m\\e[48;2;89;90;95m        \\e[m \\n\\n:\\w \\$ "

*1:これは文字表示の設定をデフォルトに戻すSGRの指定