GNU Readline の使用;同じプログラムに ncurses を追加するにはどうすればよいですか?
質問
タイトルは私の実際の目標よりももう少し具体的です。
私は、主にコマンド履歴のために GNU Readline を使用するコマンドライン プログラムを持っています (すなわち、上矢印を使用して前のコマンドを取得するなど) などの便利な機能がいくつかあります。現時点では、プログラムの出力にはユーザーの入力が散在して表示されます。これは問題ない場合もありますが、出力は非同期であり (入力コマンドに応答してネットワーク接続を介して出力されます)、それが時々煩わしくなります (例:ユーザーが新しい入力を入力しているときに行が出力される場合)。
このプログラムに機能を追加したいと思います。出力用の別の「ウィンドウ」。これには ncurses を使用することを考えました。しかし、そこから見えるのは、 ncurses FAQ 2 つのライブラリを一緒に使用するのは簡単ではありません。
使用を検討してみようかな 編集ライン または テクラ Readline の代わりに使用しますが、どちらかが私の問題を解決するかどうかはわかりません。両方の種類の機能 (テキスト モード ウィンドウとコマンド履歴) を提供するライブラリなど、ncurses 以外のものを使用することも検討しますが、何が最適かわかりません。
ああ、色付きテキストのサポートにはボーナス ポイントが付与される可能性があります。Readline を使えばそれができるのではないかと思うので、それは別の問題かもしれませんが、私の問題の解決策によって、出力に少し色を追加することも簡単になるのであれば、それに越したことはありません。
Ubuntu Hardy (Linux 2.6) を使用しています。
解決
いくつか検索してみましたが、どうやら運が悪いようです。
ncurses の代替手段は次のとおりです スラング, イモリ そして ターボビジョン. 。スラングは、単なる画面処理以上のものであり、したがってより複雑ですが、あなたの目的のために使用できるかもしれません。ニュートは画面の処理を使用しており、はるかにシンプルですが、あなたの目的のために簡単すぎてシングルスレッドモードです。
Turbo Visionは、Borlandのテキストモードグラフィックライブラリであり、80年代後半/90年代前半にすべてのツールで使用されています。Borlandは、そのようなことの市場が減少したときにソースコードをリリースし、Linuxのポートがあります(サイドノート、 このプロジェクト 独自のターボビジョンの実装を書いたようです)。そのポートは死んでいません(今年は罰金を科せられたCVSアップデートがいくつかありました(古いリリースはそうではありませんでした))が、私が見つけたテレビの例は最新のものではなく、以前にコンパイルするいくつかのテレビしか持っていませんでした残りをあきらめる。テレビはとても使いやすい環境だったので、これは少し残念です。ちなみにTVはC++です(Cを使っていると思いますが?)。
readline の代替手段として、次のものがあります。 libkinput, 、おそらくncursesと一緒に機能するかもしれません(ncursesのterminfoを使用できると言います。しかし、それがncursesの使用と共存できることを意味するかどうかはわかりません)?
たぶん、1つのオプションは、ncursesプログラムに「外部から」readlineを実行することです rlラップ?
他のヒント
私は今GitHubの上で一緒に簡単なプログラム例を入れている: https://github.com / ulfalizer / readlineの-と-ncursesのでます。
これは、シームレスで効率的な端末サイズ変更およびマルチバイト/組み合わせ/ワイド文字をサポートしています。コードは有益なコメントを持っています。
以下のスクリーンショットます:
これで私は数時間頭を打ち続けたので、人々がグーグルで検索する手間を省くために:
ncurses の組み込みを使用している場合 SIGWINCH
ハンドラー付き KEY_RESIZE
, 、readline が設定することに注意してください。 LINES
そして COLUMNS
デフォルトでは環境変数。これらは、動的なサイズ計算をオーバーライドします (通常は ioctl()
TIOCGWINSZ
)それ以外の場合は ncurses が行うことになります。つまり、端末のサイズを変更した後でも、初期の端末サイズを取得し続けることになります。
設定で防ぐことができます rl_change_environment
に 0
readline を初期化する前に。
アップデート:
readline ソースから収集した追加情報を次に示します。
リードラインの SIGWINCH
処理コード (次の場合に使用されます) rl_catch_sigwinch
は 1) 更新します LINES
そして COLUMNS
, ncurses にはこれで十分だと思われます。ただし、代替の readline インターフェイス (readline と ncurses を組み合わせる場合に最も合理的です) を使用する場合、シグナル ハンドラー ( SIGWINCH
) は、それぞれの期間中にのみインストールされます。 rl_callback_read_char()
呼び出し。2 つの呼び出しの間で端末のサイズが変更されることを意味します。 rl_callback_read_char()
readline では表示されません。
だから、GDBはreadlineのとncursesの両方を使用していることが判明しました。あなたがこれを行うに興味があるなら、私はあなたが彼らの実装をチェックアウトすることをお勧めします:<のhref = "http://sourceware.org/git/?p=gdb.git;a=blob;f=gdb/tui/ TUI-io.c」のrel = "nofollowを"> http://sourceware.org/git/?p=gdb.git;a=blob;f=gdb/tui/tui-io.cする
私はあなたが試したどのバージョンかわかりません。それは非常に簡単です(2012年9月14日)今日の時点で、私達はちょうど関数ポインタを次のように私たちのカスタム関数をフックする必要があります。
rl_getch_function rl_redisplay_function rl_completion_display_matches_hook
私はここでの何か合理的なをしました。