ANSIエスケープシーケンスを使用して端末の内容を「所定の位置」に編集する正しい方法は何ですか?

ANSIエスケープシーケンスを使用して端末の内容を「所定の位置」に編集する正しい方法は何ですか?

そのため、次の動作を使用して単純な端末アプリケーションを作成しようとしました。

  1. 起動時に画面が消去され、空白の画面上部に一部の内容が記録されます。

  2. 「Enter」を押すたびに画面が消去され、その場に新しいコンテンツが表示されます。

ANSIエスケープコードを使用して画面を消去し、カーソルを移動してこれを達成しようとしています。私の現在のアプローチは次のとおりです(医師コード)

func clearAndPrintContent() {
    printf("\x[2J")    // clear the entire screen
    printf("\x[1;1f")  // move the cursor to the top left corner of the screen
    printContent() // print some lines of content to the screen
}

main {
    while true {
        clearAndPrintContent() // do the clear and print
        readLine() // wait for enter key
    }
}

私が期待するのは、ここにあるコンテンツが常にその場で作成されることです。つまり、新しいコンテンツが作成されると、既存のコンテンツが上書きされます。私が実際に得ることは、私のすべてのコンテンツが連続して書き込まれることです。つまり、後ろにスクロールすると、スペースや印刷内容を含むプログラムが印刷するすべての「ページ」が表示されます。

たとえば、何かを2回印刷する場合は、スクロールバックが次のように表示されます。

- previous scrollback -
$ run my-app

   [result of second printContent from my-app (first has been over-written)]



-end of terminal output -

しかし、私が実際に得るのはこれです:

- previous scrollback -
$ run my-app

   [result of first printContent from my-app]





   [result of second printContent from my-app]



-end of terminal output -

この結果をどのように取得できますか?

答え1

端末ごとに異なる動作をします\e[2J。 Xtermなどの一部は期待どおりに画面を消去します。 VTE(GNOME端末や他のフロントエンド)などの他のものは、ユーザーが経験するようにコンテンツをスクロールバックバッファにスクロールします。

最初のステップにあった位置にカーソルを移動してから\e[J(「消去」、つまりカーソルがある行の右側にあるすべての項目とその下の行にあるすべての項目)を使用して消去できます。これはどこでも同じです。

別の方法は、スクロールバック機能なしで代替画面バッファに切り替えることで、\e[2Jすべての端末で同じことを行います。アプリを終了すると通常画面に戻り、アプリの起動時にあった場所に移動します。

関連情報