指定した将来の時刻、または一定時間のアイドル状態の後に関数を呼び出すタイマーを設定できます。タイマーとは、次回の呼び出し時刻と呼び出す関数に関する情報を保持する特殊なオブジェクトです。
この述語関数は、object がタイマーである場合に non-nil を返します。
Emacsは、Lispプログラム内の任意のタイミングでタイマーを実行することはできません。タイマーを実行できるのは、Emacsがサブプロセスからの出力を受け取れる場合、すなわち待機中であるか、あるいはsit-forやread-eventのように待機可能な特定のプリミティブ関数内である場合に限られます。したがって、Emacsがビジー状態にある場合、タイマーの実行が遅延することがあります。ただし、Emacsがアイドル状態であれば、実行時刻は非常に正確になります。
Emacsでは、多くのタイマー関数から終了すると状態が不整合になる可能性があるため、タイマー関数を呼び出す前に inhibit-quit を t
にバインドします。ほとんどのタイマー関数は処理量が多くないため、通常は問題になりません。実際、実行に相当な時間を要する関数をタイマーが呼び出すのは、煩わしいことでしょう。タイマー関数で終了を許可する必要がある場合は、with-local-quit を使用してください(終了を参照)。例えば、タイマー関数が外部プロセスから出力を受け取るために accept-process-output を呼び出す場合、外部プロセスがハングしても C-g が確実に動作するように、その呼び出しを with-local-quit で囲む必要があります。
タイマー関数がバッファの内容を変更するのは、通常好ましくありません。変更を行う際は、通常、バッファ変更の前後でそれぞれundo-boundaryを呼び出し、タイマーによる変更とユーザーコマンドによる変更を分離し、単一のアンドゥエントリが著しく肥大化するのを防ぐべきです。
タイマー関数では、sit-for のように Emacs
を待機させる関数の呼び出しも避けるべきです(経過時間または入力の待機を参照)。待機中に他のタイマー(あるいは同一のタイマー)が動作する可能性があるため、予期せぬ挙動を招く恐れがあります。タイマー関数で一定時間が経過した後に処理を実行する必要がある場合は、新しいタイマーをスケジュールすることで実現できます。
タイマー関数がリモートファイル操作を行う場合、同一接続で既に実行中のリモートファイル操作と競合することがあります。このような競合は検出され、remote-file-error エラーが発生します(標準エラーを参照)。これは、タイマー関数の本体を以下でラップすることで防ぐ必要があります。
(ignore-error remote-file-error ...)
タイマー関数がマッチデータを変更しうる関数を呼び出す場合は、マッチデータを保存および復元する必要があります。マッチデータの保存と復元を参照してください。
これにより、時刻 time に引数 args を指定して関数
function を呼び出すタイマーが設定されます。repeat が数値(整数または浮動小数点数)の場合、タイマーは time 以降、repeat
秒ごとに再度実行されるようスケジュールされます。repeat が nil の場合、タイマーは1回のみ実行されます。
time では、絶対時刻または相対時刻を指定できます。
絶対時刻は、形式が限定された文字列を用いて指定でき、たとえ既に過去の時刻であっても、今日の時刻とみなされます。認められている形式は、‘xxxx’、‘x:xx’、または‘xx:xx’(軍用時刻)、および‘xxam’、‘xxAM’、‘xxpm’、‘xxPM’、‘xx:xxam’、‘xx:xxAM’、‘xx:xxpm’、または‘xx:xxPM’です。時と分の部分を区切るには、コロンの代わりにピリオドを使用することもできますが、これは‘am’または‘pm’という接尾辞(大文字・小文字を問わない)が指定されている場合に限られます。そうでない場合、文字列は単位のない秒数と区別がつかなくなり、相対時刻として解釈されるためです(後述)。
相対時間を文字列で指定するには、数値の後に単位を記述します。例えば:
今から1分後を表します。
今から65秒後を表します。
今からちょうど103か月123日10862秒後を表します。
‘12.34’のように、単位のない数値を指定する文字列は、秒単位の相対時刻として扱われます。
相対的な時間値について、Emacsでは1か月をちょうど30日、1年をちょうど365.25日として扱います。
便利なフォーマットがすべて文字列であるとは限りません。time
が数値(整数または浮動小数点数)の場合、それは秒単位で計測された相対時間を表します。encode-time の結果は、time
の絶対値を指定するためにも使用できます。
ほとんどの場合、repeat は 初回
呼び出しのタイミングに影響を与えません—それを指定するのは time
のみです。ただし、1つだけ例外があります。time が t である場合、エポックから repeat
秒の倍数となるタイミングでタイマーが動作します。これは display-time
のような関数に有用です。例えば、以下のように記述すると、function
が「整数分」ごと(例:「11:03:00」、「11:04:00」など)に動作します:
(run-at-time t 60 function)
タイマーが作動するはずのタイミングでEmacsにCPU時間が割り当てられていなかった場合(例えば、システムが別のプロセスの実行でビジー状態であったり、コンピュータがスリープ中またはサスペンド状態であったりした場合)、Emacsが復帰してアイドル状態になるとすぐにタイマーが作動します。
関数 run-at-time
は、予定されている特定の将来のアクションを識別するタイマー値を返します。この値を使用して cancel-timer を呼び出すことができます(後述)。
これは run-at-time
と全く同じです(パラメータの説明についてはその定義を参照してください。secs はその関数に time として渡されます)。ただし、遅延を秒単位で指定する場合に使用することを想定しています。
繰り返しタイマーは、名目上はrepeat秒ごとに動作するはずですが、タイマーの呼び出しはいつでも遅延する可能性があることに注意してください。1回の繰り返しが遅延しても、次の繰り返しの予定時刻に影響はありません。例えば、Emacsがタイマーの予定された3回分の繰り返しをカバーするほどの長時間計算に従事し、その後待機し始めた場合、直ちにタイマー関数を3回連続して呼び出します(その間やその前に他のタイマーが作動しないと想定した場合)。前回の呼び出しから少なくともn秒後にタイマーを再度動作させたい場合は、repeat引数を使用しないでください。代わりに、タイマー関数側で明示的にタイマーを再スケジュールする必要があります。
この変数の値は、事前にスケジュールされていた多くの呼び出しがやむを得ず遅延した場合に、タイマー関数を連続して呼び出す最大回数を指定します。
bodyを実行し、seconds秒後に終了する。タイムアップ前にbodyが終了した場合、with-timeoutはbody内の最後のフォームの値を返す。ただし、タイムアウトによってbodyの実行が途中で打ち切られた場合は、with-timeoutはすべてのtimeout-formsを実行し、そのうち最後のものの値を返す。
このマクロは、seconds秒後に実行されるようタイマーを設定することで動作します。もしbodyがその時刻より前に終了した場合、タイマーをキャンセルします。実際にタイマーが作動すると、bodyの実行を終了し、続いてtimeout-formsを実行します。
タイマーがLispプログラム内で動作できるのは、プログラムが待機可能なプリミティブを呼び出した場合に限られるため、with-timeoutは計算の途中でbodyの実行を停止させることはできず—それらのプリミティブのいずれかを呼び出したときにのみ停止します。したがって、with-timeoutは長時間の計算を行うものではなく、入力を待機するbodyと組み合わせてのみ使用してください。入力を待機するプリミティブには、sit-for、sleep-for、accept-process-outputなどが含まれます。
y-or-n-p-with-timeout
関数を使用すると、タイマーを簡単に利用して、回答を長時間待ちすぎるのを避けることができます。Yes-or-No クエリを参照してください。
これにより、タイマー(通常は以前に run-at-time または run-with-idle-timer によって返されたもの)であるはずの timer
に対するリクエスト済みのアクションがキャンセルされます。これにより、これらの関数のいずれかへの呼び出しによる効果が打ち消され、指定された時刻になっても特に何も起こりません。
list-timers コマンドは、現在有効なすべてのタイマーを一覧表示します。c (timer-list-cancel)
コマンドは、ポイントの下にある行のタイマーを解除します。S (tabulated-list-sort) コマンドを使用すると、列ごとにリストをソートできます。