Emacs が一定時間アイドル状態になったときに動作するタイマーの設定方法を紹介します。設定方法を除けば、アイドルタイマーは通常のタイマーと同様に動作します。
Emacsが次にアイドル状態になった際にsecs秒間動作するタイマーを設定します。secsの値には、数値またはcurrent-idle-timeが返す型の値を指定できます。
repeat が nil
の場合、タイマーは一度だけ動作します。これは、Emacs が十分に長い時間アイドル状態になった最初のタイミングです。多くの場合、repeat は nil ではなく、これは Emacs が
secs 秒間アイドル状態になるたびにタイマーが動作することを意味します。
関数 run-with-idle-timer は、cancel-timer の呼び出しに使用できるタイマー値を返します(遅延実行用タイマーを参照)。
Emacsは、ユーザー入力の待機を開始するとアイドル状態になります(タイムアウトを設けて入力を待機する場合は除きます。Reading One
Eventを参照してください)。そして、ユーザーが何らかの入力を行うまでアイドル状態のままとなります。5秒間のアイドル状態にタイマーが設定されている場合、Emacsが最初にアイドル状態になってから約5秒後にタイマーが作動します。たとえrepeatがnilでない場合でも、Emacsがアイドル状態である限り、このタイマーは再度作動しません。これは、アイドル状態の継続時間が増え続け、再び5秒まで短縮されることがないためです。
Emacsはアイドル状態で、ガベージコレクションやオートセーブ、サブプロセスからのデータ処理など、さまざまな処理を行うことができます。しかし、こうしたアイドル中の合間の処理は、アイドルタイマーをゼロにリセットしないため、アイドルタイマーに影響を与えることはありません。600秒に設定されたアイドルタイマーは、最後のユーザーコマンドが完了してから10分が経過した時点で作動します。その10分の間にサブプロセスの出力が数千回受け付けられていたとしても、あるいはガベージコレクションやオートセーブが行われていたとしても同様です。
ユーザーが入力を行うと、Emacsはその入力処理の間、非アイドル状態になります。その後、再びアイドル状態に戻り、繰り返し実行されるよう設定されていたすべてのアイドルタイマーが、順次もう一度作動します。
ループを含み、回ごとに一定の処理を行い、(input-pending-p)がnilでないときに抜けるような空のタイマー関数を記述しないでください。この手法は非常に自然に思えますが、2つの問題があります:
同様に、現在のアイドル時間以下の secs 引数を用いて別のアイドルタイマー(同一のアイドルタイマーを含む)を設定するような、無意味なタイマー関数を記述しないでください。このようなタイマーはほぼ即座に動作し、Emacs が次にアイドル状態になるのを待たずに、繰り返し動作し続けます。正しい方法は、以下に説明するように、現在のアイドル時間の値に適切な増分を加えて再スケジューリングすることです。
Emacs がアイドル状態の場合、この関数は current-time と同じ形式で、Emacs
がアイドル状態であった時間を返します(Time of Day
を参照)。
Emacs がアイドル状態でないとき、current-idle-time は nil を返します。これは、Emacs がアイドル状態かどうかを判定する便利な方法です。
current-idle-timeの主な用途は、アイドルタイマー関数がしばらくの間「休憩」したい場合です。これにより、さらに数秒のアイドル状態が続いた後、同じ関数を再度呼び出す別のアイドルタイマーを設定できます。以下に例を示します。
(defvar my-resume-timer nil "Timer for `my-timer-function' to reschedule itself, or nil.") (defun my-timer-function () ;; If the user types a command whilemy-resume-timer;; is active, the next time this function is called from ;; its main idle timer, deactivatemy-resume-timer. (when my-resume-timer (cancel-timer my-resume-timer)) ...do the work for a while... (when taking-a-break (setq my-resume-timer (run-with-idle-timer ;; Compute an idle time break-length ;; more than the current value. (time-add (current-idle-time) break-length) nil 'my-timer-function))))