4

コンソールへのキーボード文字エコーを無効にしたい Rebol2 コンソール アプリ (Rebol Core) があります。アプリは最小限の Linux カーネル/initramfs から実行され、busybox inittab によって (ターミナルからではなく) 開始されます。色などの ANSI コードを使用する最小限のコンソール ユーザー インターフェイスを備えており、キーを 1 回押すだけでメニュー選択に応答します。コンソールを「静かにする」ために、カーソルをオフにして、キーを押しても出力が表示されないようにしました (最近まで)。

以前は、Rebol 内で 'stty -echo' を呼び出すことで問題が解決したと思っていましたが、実際には機能せず、5 ~ 10 秒かかる関数が 1 つあります。完了する関数。

この 1 つの関数の実行中にエコーされた文字しか表示されない理由はよくわかりませんが、時間がかかる唯一の関数です。キーボードは、console:// をバイナリ モードで開くことによってポーリングされ、キーが押されるのを待ってから、switch ステートメントで機能を選択します。バイナリ/コンソールでのキーの読み取りは、キー エコーを「消費」しているようです。

minimal example, pressing 'a'-

    cons: open/binary console://
    first cons
    == 97

(値は希望どおりに返され、文字はエコーされません。これは良いことです。ほとんどの関数では、キーは get-key ループで「消費」されると思いますが、より長い関数では「消費」する機会がありません' それらをコンソールにエコーすることになります)

Rebol2 内のコンソール文字エコーを無効にする方法はありますか? system/console と system/ports/input,output を調べましたが、明らかなものは何もありません。私の現在の回避策は、テキストの色を背景に合わせて変更するだけで、特定の機能の実行中にキーを押しても見えないようにすることです。

ここに私がやっていることの最小限の例があります-

get-key: func [ /local cons ch ][
    cons: open/binary console://
    ch: lowercase to-string to-char first cons
    all [ equal? ch "^["   append ch copy/part cons 2 ]
    close cons
    ch
]

forever [
    switch get-key [
        ;up arrow
        "^[[A" [ some-function1 ]
        ;down arrow
        "^[[B" [ some-function2 ]
        ;enter
        "^M" [ some-function3 ]
        ;quit
        "q" [ break ]
    ]
]

永久ループはキーボード入力を「消費」しているように見えますが (何もエコーされません)、関数の 1 つに時間がかかると、キーボード入力はカーソルがどこにあっても画面にエコーされます。ほとんどの場合、get-key を呼び出す間の時間が最小限であるため、エコーされた文字は表示されません。また、エコーされた文字は、その後の get-key の呼び出しにも表示されないことに注意してください。

アップデート-

これは、問題を確認するためのより良いコードのサンプルです-

get-key: has [ cons ch ][
  cons: open/binary console://
  ch: lowercase to-string to-char first cons
  prin rejoin [ "<" ch ">" ] ;show get-key chars
  ch
]
long-func: does [ call/wait {sleep 10} ]
reb-func: does [ wait 10 ]

forever [
  switch get-key [
   "f" [ long-func ]
   "r" [ reb-func ]
   "q" [ break ]
  ]
]

私の「長い」関数は、数秒かかる可能性のある呼び出しを使用しているため、呼び出しを使用すると問題が発生することがわかりました。

上記のコードを実行すると、キーが get-key 関数 (括弧) で出力されるためだけにエコーされることが示されます。long-func が実行されている場合、キーは get-key の外側 (括弧なし) でエコーされます。完了すると、get-key はそれらのキーも処理します。または単に「call/wait {sleep 10}」を実行すると、待機中にエコーされたキーが取得され、コールが返されたときに Rebol によってエコーされた同じキーも取得されます。reb-func の実行時にキーはエコーされません。reb-func が完了すると、get-key はすべてのバッファリングされたキーを処理します。call を使用すると、キーボード入力が 2 回処理されます。

call コマンド (bash プロンプトなどの call string コマンド) で stdin/stdout をリダイレクトしようとしましたが、機能するコンボが見つかりませんでした。(私の実際のコードは /output/error で呼び出しを実行して、すべての出力をキャプチャします)。

4

2 に答える 2