関数の実行中にユーザーがボタンを押したかどうかを確認するにはどうすればよいですか?


8

ユーザーが何らかのアクションを実行すると自動的に実行される機能があります。ただし、関数の完了には時間がかかります。これは、Emacsがすべての入力後に短時間応答しなくなることを意味します。これを修正するには、ユーザーが新しい入力を入力したかどうかを確認し、入力した場合は、この関数の実行をキャンセルしてユーザーの入力を続行します。

キューに入れられたキーボード入力を保持する変数はありますか?そうでない場合、関数の実行が開始されてからユーザーがボタンを押したかどうかを確認する別の方法はありますか?


2
あなたはwhile-no-inputマクロを見たいかもしれません。それはあなたが望むことをするようです:すなわち、それは新しい入力が現れたときにその本体の実行をキャンセルします。
wvxvw 2016年

@wvxvwあなたのコメントは私に良い答えのように見えます。そのように投稿する必要があります!
Phil Hudson

回答:


5

わかりました、私は拡張された答えを試します。実は、Emacs Lispはシングルスレッドです。さらに多くのプロセスをスピンできますが、Emacs Lispインタープリター内ではできません。ただし、関数を中断するためにユーザーから読み取る必要があるキーボード入力は、同じEmacs Lispインタープリターで処理する必要があります。これはあなたのインタプリタがいくつかのLispコードを解釈するのに行き詰まっている場合、あなたが内部からそれを中断する方法がないかもしれないことを意味します。この状況を説明するマニュアル内の場所は次のとおりです。

Cコードのレベルでは、終了はどこでも起こり得ません。終了フラグをチェックする特別な場所でのみ。これは、他の場所で終了するとEmacsの内部状態に矛盾が残る可能性があるためです。終了は安全な場所まで遅延されるため、終了してもEmacsがクラッシュすることはありません。

https://www.gnu.org/software/emacs/manual/html_node/elisp/Quitting.html

では、EmacsにはどのようにC-g/キャンセル機能がありますか?-I / O(コマンドループでイベントを待機)を行うタイマーと関数があります。タイマーは、計算がチャンクで実行されるように調整できます。これにより、計算のポイントを確認し、必要に応じて、それ以上の計算をすべて防ぐことができます。I / O関数はquit信号を送信できます。マクロwith-keyboard-quitはこのシグナルを待ち、受信されると正常に終了します。ただし、関数はこの信号を送信することを知っている必要があります。これは、関数がユーザーによるキーボード入力の送信を妨げている場合、キーボード割り込みの恩恵を受けることができないことを意味します。

結論:関数のコードをにラップしてみてくださいwhile-no-input。これが機能しない場合は、Emacsがキーボードイベントを処理できるように関数を書き直してみてください。


C-g常にlispコードを中断できwhile-no-inputます。これを他のキーボード入力に拡張するだけです。
npostavs 2016年

@npostavsはそうではありません。のようなものを中断してみてください(while t)。(ただし、行う前に、すべての変更を保存したことを確認してください)。
wvxvw 2016年

私は、型付き(while t)*scratch*とヒットC-x C-e、その後C-g、私が得たQuitメッセージを、Emacsは立ち往生しませんでした。
npostavs

@npostavsよく、私は中断することができない組み合わせを確かに見つけるでしょうが、今それを探す時間はありません。*scratch*あなたがそこで行うすべての評価はヘルパー関数にラップされているので、どれだけ信頼できるかはわかりません。
wvxvw 2016年

私はどうにか動けなくなっ(while t (condition-case _ (while t) (quit nil)))た。理論的にはC-g、適切なタイミングでヒットできれば割り込むことができると思うが、実際にはできない。
npostavs

3

私は一緒に行きinput-pending-tます。ドキュメントから:

(入力保留-p&オプションのCHECK-TIMERS)

コマンド入力が待機なしで現在利用可能な場合はtを返します。実際、値がnilになるのは、入力が利用できないことが確実な場合のみです。疑いがある場合、値はtです。

簡単な例:

(progn
  ;; I put this into a progn call so you can call it direcly from Emacs
  ;; if you are using the sx package
  (message "Try pressing a key in the next 2 seconds!")
  (sleep-for 2)
  (message (if (input-pending-p)
               "There is input waiting!"
             "No input, let’s move on!"))
  (sleep-for 2))

パーフェクト!どちらの回答も素晴らしいですが、残念ながら私は1つしか受け入れることができませんでした。ありがとう!
jcaw
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.