read-key-sequence-vector で timeout

Emacs でキー入力を待ち, なおかつ, 一定時間入力がなければタイムアウトする方法.
これどうやんだろーと悩んでた.

read-char, read-event


まず, 方法1.

  • read-char, read-event 等を使う

これを使えば, 第3引数にsecondというものがありその時間を過ぎるとタイムアウトし, nilを返させることができる.
でも, この関数自体, 自分の欲しい方法とはちょっち違う.

  • C-gでQuitしてしまう.
  • C-x a gなど複数のキー入力が取れない.

つまりは, 本当に1つのキーしかとれない上, C-gでC-gのキーが取れるのではなくQuitしてしまう.
これは自分の目的とは似わないので却下.

read-key-sequence-vector, read-key-sequence

んで, もう1つの方法.
たぶんキー入力を取るならこっちの方が嬉しい思う.
read-key-sequence, もしくは, read-key-sequence-vectorを使う.
嬉しい点.

  • C-g でもちゃんとキーが取れる
  • 複数のキー入力(C-xaeとかC-xC-fとか)でもちゃんと大丈夫

ちなみに使うなら, read-key-sequence-vectorの方が良いと思う.
理由としては, 以下のような感じ

  • read-key-sequenceは, 返す値が文字列だったり, ベクトルだったりする.
    # Hyperキーとか混ぜるとread-key-sequenceはベクトルになる.
  • 文字列でC-xaeを示す値「"^Xae"」を返されるより, ベクトル「[24 97 101]」を返してくれた方が処理しやすい(と思う).

まあケースバイケースだろうけどね.
で, こいつらの問題点.
タイムアウトを設定する引数がない. 実行したらずーっと待っちょる.

read-key-sequence-vectorタイムアウト


解決編.
ELisp infoのReading Inputとかを読んでみたけどわかんなくてググってみたら簡単に見付かった.

すんばらしい.
with-timeout マクロを使えばいいみたい.

(with-timeout (3 nil)
  (read-key-sequence-vector "hoge"))

これで, 3秒間, なんもせんかったらnilが返戻されるようになる.
ちなみにこのwith-timeoutマクロは, catchフォーム内でrun-with-timerを指定した秒数何もせんかったらタグを飛ばすように設定してるっぽい.
んで, 何もせんかったら, run-with-timerが実行されてタグが飛ぶ.
それをcatchが取って, タイムアウトーみたいなことを実現してるっぽ.
すげえ.
これでやりたいことがでけましたよ, と. 便利なマクロがあるもんだ.

追記ー

読み返してて気付いた.
apropos使ってれば一発で見付かったようなw

まとめ

キー入力が欲しくて, かつ, タイムアウトを設定したかったら,
with-timeoutマクロとread-key-sequence-vectorかread-key-sequenceを使えばおk.
# つか, with-timeoutマクロはかなーり便利やと思う. これは色々な所で使える思う.
少しすすんだ.

更新時刻

  • 1かいめ 2008年, 2月18日, 23:43
  • 2かいめ 2008年, 2月18日, 23:51