web-dev-qa-db-ja.com

カーソル位置を保存してターミナルに復元します

bashに非同期プロンプト出力を作成するために、いくつかの端末機能を使用しています。次のようなものを取得したい:Prompt_COMMAND、端末カーソルの位置を保存、印刷...そして他のことをしに行く(例えば他の情報を印刷する);その後しばらくして戻る記憶された位置に戻り、何か新しいものを印刷します。 PS1は、コマンド自体が改行に配置されるように設計されているため、非同期出力は端末内のテキストにすぎません。

カーソルを指定された位置に移動するためのcup terminfoエントリを見つけました。現在の位置を取得するためのエスケープコードがあります(たとえば、 この質問 を参照してください)。しかし、私にとっては、それらはすべて、端末バッファーではなく、画面上のカーソル位置で機能するようです。つまり、改行を入れた後、覚えている位置が間違っているということです。

ターミナルカーソル位置を操作して、バッファ位置に基づいてカーソル位置を保存および復元する方法はありますか?記憶された位置はまだバッファの表示部分にあると想定できますが(実際にカーソルをそこに置くことができます)、数行上に移動する可能性があります。今のところ、競合状態については考慮しません。いいえの場合、私は他のトリックを見つけようとします。

実際に非同期プロンプトをサポートするzshシェルがありますが、出力ユーザーが押す前にそれが機能するかどうかは実際にはわかりません Enter 新しい行に移動します。

4
Lapshin Dmitry

使用する可能性のあるほとんどの端末は、カーソル位置を保存および復元するためのエスケープシーケンスを実装しています。これらは、端末の説明のsc(カーソルの保存)機能とrc(カーソルの復元)機能であり、tputを介して使用できます(cupと同様) )::

tput sc
tput cup 50 10
echo some stuff
echo more stuff
tput rc

ただし、プログラムがスクロールを強制するのに十分なテキストを書き込んだ場合、復元された位置は端末の画面上の同じ場所にあります。スクロールされたテキストと一緒に移動しません。

ちなみに、POSIXは、ツールが実際には別の標準であるX/Open Cursesの一部であるため、tputpartのみを文書化します。それはマニュアルページの portability セクションにまとめられています。

質問に戻ります。bufferの位置を追跡するエスケープシーケンスはありません(スクロールを考慮)。そのためには、アプリケーションが画面に送信されたものを追跡する必要があります。この種の問題を解決することが、cursesライブラリの目的です。単純なコマンドラインアプリケーションでは、できることはあまりありません。

9
Thomas Dickey