macos - escape - ターミナル ansiカラー



Terminal.appはANSIエスケープコードを尊重することができますか? (1)

ANSIコードは使用しないでください。 適切なterminfoベースのテクニックを使用してください。 Xtermベースの端末は、すべてのANSIコードをサポートするように指定されていません。 いくつかは互換性のために、あるものは互換性のためにありません

セーブカーソル位置シーケンスはtput scコマンドで与えられ、リストアカーソル位置はtput rcです。

echo -e "$(tput sc)Hello world$(tput rc)G'day"

これらのシーケンスをサポートするすべての端末で動作するはずです。

サポートされているシーケンスの読み取り可能な表現を表示するには、 infocmpコマンドを使用します。 出力はかなり長いかもしれません。 scrc興味があるなら:

infocmp | grep --color ' [sr]c='

免責事項:私のLinuxマシンでテストしましたが、近くにMacを置いてはいけません。

更新

Terminal.appはxtermの後にモデル化され、xtermはVT100端末の後にモデル化されます。 VT100はCSI uおよびCSI sシーケンスを実装しませんでしたが、DECプライベートESC 7およびESC 8シーケンス(ソース)を使用しました 。 後のVTモデルは、 CSI s/uESC 7/8 CSI s/u両方を、異なる名前で、わずかに異なる機能(ソース)でサポートしていました。

ECMA 48は、カーソル位置の保存/復元カーソル(ソース(PDF))を指定していないようですが、見つけられませんでした。 CSU s/uどこから来たCSU s/uか分かりません。 VT510のドキュメンテーションの名前は、SCOと何とかつながっていることを示しています。 この情報源は、実際には標準的な意味のない私的な配列であることを示唆しています。 SUN端末はSCI s使用してリセットを行います。 これらの2つのシーケンスANSIをブランド化することはおそらくエラーです。

現代版のxtermやその他のX11端末プログラム(konsole、rxvt ...)は、 ESC 7/8CSI s/u両方をサポートしていますが、terminfoデータベースはESC 7/8のみをアドバタイズします。 Terminal.appは明らかにESC 7/8のみをサポートしています。

私は、 TERM環境変数をxtermまたはxterm-256color設定すると、Mac OS XのTerminal.appユーティリティがほとんどのANSIエスケープコードを尊重していることにxterm-256colorた。

例えば:

echo -e "\033[0;31mERROR:\033[0m It worked"

プロデュース:

しかし、私はANSIエスケープコードによって得られるカーソル位置操作機能にもっと興味があります。 残念ながら、 このタイプのコードはTerminal.appではあまりうまく機能していないようです。 たとえば、私がしたいことは次のようなものです:

echo -e "\033[sHello world\033[uG'day"

ESC[s現在のカーソル位置を保存しますが、 ESC[uは最後に保存した位置を復元します。 上のスクリプトを実行した結果、 "G'day"の5文字が、カーソルが再配置された後の "Hello"の5文字を​​上書きして、次のようになることが予想されます。

G'day world

確かに、これはまさに私がiTerm2.app、ConEmu for Windows(MinGWまたはMSYS Gitのbash.exeのコピーを実行している)などで得られるものです。しかし、Terminal.appで見ているのはこれです:

Hello worldG'day

Terminal.appにこれらのコードのサポートが欠けているのを除いて、これは理由がありますか? この機能を有効にする方法はありますか? 私は何かが誤って設定されている可能性はありますか? 私のTERMの設定? 他に何か?

私はどこからでも検索してきましたが、Terminal.appに関連するものは特に見つけられませんでした。 ANSIのエスケープコードを使って色付きのテキストをサポートするのは間違いないが、まったく同じ技術でカーソルの位置を変えることはできない。 これは、かなり明確な標準のかなり任意のサブセットのようです。 Terminal.appが責任を負うのではなくむしろ何かが誤って設定されていると思うのですが、単純に実行できない可能性があります。 (おそらくiTerm2が最初に存在する理由の1つでしょうか?)

このような状況で誰かが何らかの光を当てることができれば、大いに感謝しています!

更新

だから私はもう少し読んで実験を行い、次の不思議さを発見しました:

以下のnmの答えを調べた後、 tputによって返されたバイトをファイルに書き出し、通常のANSI命令とどのように違うのかを調べることにしました。

$ echo "$(tput sc)Hello world$(tput rc)G'day" > out.bin
$ cat -e out.bin
^[7Hello world^[8G'day$

ESC 7ESC 8シーケンスを送ると、すべてが正常に動作するように見えますが、 ESC [sESC [u 、ANSI SCPとRCPコードのより典型的な表現です(それぞれカーソル位置を保存し、カーソル位置を復元する)。 エスケープされた8進バイト表現の隣にASCII小数点文字7または8を置くことは不可能なので( \0337 != ESC )、代わりに環境変数を使用してtput依存することを避けることができます。

$ esc=$'\033'
$ csi="${esc}["
$ echo "${csi}0;31mERROR:${csi}0m It worked."
ERROR: It worked.  # Color works, as before
$ echo "${csi}sHello world${csi}uG'day"
Hello worldG'day   # No dice
$ echo "${esc}7Hello world${esc}8G'day"
G'day world        # Success

なぜこのことが分かりませんか? ESC 7ESC 8が、端末の実装から端末の実装までに変化する可能性のあるANSI SCPとRCPの独自のコードまたはカスタムコードである場合、最初にtputが作成された理由を説明します。

残念ながら、私が現在取り組んでいることはtputを使うことができません。 tput私はbash環境で独占的に働いているわけではないからです。 私はrawバイトがターミナルからターミナルにどのように解釈される 、もっと具体的には、 Terminal.appに、同じANSIエスケープコードを尊重する方法があるかどうか、私が試した他のすべてのターミナルエミュレータ何の問題もないようです。 それは可能ですか? この時点で、私はそれが単純ではないかもしれないと思うようになっています。これはうまくいきますが、確かに知っているといいでしょう。





ansi-escape