長いコマンドライン(> $ COLUMNS)を自動的にラップする方法は?

長いコマンドライン(> $ COLUMNS)を自動的にラップする方法は?

I / O転送にはいくつかのポイントがあり、そのいくつかは(私が知っている限り)シェル、pty、tty、termios、およびターミナルエミュレータアプリケーションです。ほとんどの端末エミュレータでは、ユーザーがEnterキーを押してコマンドを送信する前に、長いコマンドライン(現在の$ COLUMNSを超えている行)が折り返されます。また、期待どおりにコマンドラインから適切な数の文字が削除された場合、行は上の行に逆に折り返されます。

私の質問は:この魔法は通常どこで処理されますか?シェルの一部であるtermiosの設定ですか、それともそれを担当する端末エミュレータアプリケーションですか?

より詳細な説明のために、UbuntuはTerminator端末エミュレータアプリケーションを使用しています。ここで改行文字はうまく動作します(したがって$ PS1プロンプトも問題ありません)。しかし、go pty generateer(github.com/jp/pty)で動作する独自の端末エミュレータアプリケーションを開発していますが、改行はありませんが、行の先頭に同じ行がある長い行に問題があります。ワイヤー。

ベストアンサー1

ほとんどの端末エミュレータでは、ユーザーがEnterキーを押してコマンドを送信する前に、長いコマンドライン[...]が折り返されます。

これ端末エミュレータ機能ではありません。

これはシェルの機能です。あなたのシェルはフルスクリーンアプリケーションではありませんが、次のことを行っています。カーソルのアドレス指定

シェルでコマンドラインを編集すると、シェルの行編集ライブラリは編集中の行の表示方法を完全に担当します。 Bourne Again シェルでは、これは GNU readline ライブラリです。 Almquistシェルはlibeditを使用します。他のシェル(Zシェルなど)には独自のライブラリがあります。

これらのライブラリは、ターミナルエミュレータのターミナル機能を文書化するtermcap / terminfoライブラリの上にあります。これには、カーソルを相対位置または絶対位置に配置する制御シーケンス、行末と画面終了を消去するシーケンス、端末に自動マージン

これと端末の幅に関する情報TIOCGWINSZ ioctl(他のライブラリの場合はtermcap / terminfoデータベースに置き換えますCOLUMNS)を使用して、シェルの行編集ライブラリはコマンドラインの長さと行数を追跡できます。ターミナルラインに表示されます。入力ラインの編集中にカーソルをインテリジェントに移動して入力ラインを再描画します。時には自動マージンに依存することがあります(端末にある場合)。時には制御シーケンスを使用してカーソルの位置を明示的に変更することもできます。

そうなると、次のような問題が発生します。https://superuser.com/questions/695338/。プロンプト文字列の制御シーケンスが正しく分離されていない場合、人々はカーソルがどこにあるのか、画面上の特定の位置に書き込むためにどのカーソルの動きをエクスポートする必要があるのか​​についての混乱を招く可能性があります。

ターミナルエミュレータはコマンドラインまたは行編集の概念を処理しません。このレイヤーの一部ではありません。単純な文字ストリームと制御シーケンスを確認してレンダリングする必要があります。ターミナルエミュレータは、termcap / terminfoエントリに宣伝された制御シーケンスを実装する役割を果たします。 GNU readline、libedit、ZLEvimなどscreenは、自分が見つけた広告コンテンツを使用します。たとえば、端末に自動マージンがあるとtermcap / terminfoで宣言した場合、エミュレータは文字が右マージンに印刷されるときに改行する必要があります。端末がカーソルを上下に動かすことができると指定した場合、適切な制御シーケンスを受け取ったら実際にそうする必要があります。

注:GNU readlineがtermcap / terminfoエントリにそれを行う方法がないため、カーソルを上に移動できないことがわかった場合、実際には改行文字はまったく表示されません。 readline は、入力行をすべて 1 行に水平にスクロールするモードに戻ります。

おすすめ記事