* emacs-lisp/timer.el (timer-until): Use time-subtract and float-time.
[bpt/emacs.git] / lisp / emacs-lisp / timer.el
CommitLineData
5e046f6d
JB
1;;; timer.el --- run a function with args at some time in future
2
73b0cd50 3;; Copyright (C) 1996, 2001-2011 Free Software Foundation, Inc.
5e046f6d
JB
4
5;; Maintainer: FSF
bd78fa1d 6;; Package: emacs
5e046f6d
JB
7
8;; This file is part of GNU Emacs.
9
d6cba7ae 10;; GNU Emacs is free software: you can redistribute it and/or modify
5e046f6d 11;; it under the terms of the GNU General Public License as published by
d6cba7ae
GM
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
5e046f6d
JB
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
d6cba7ae 21;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
5e046f6d
JB
22
23;;; Commentary:
24
25;; This package gives you the capability to run Emacs Lisp commands at
26;; specified times in the future, either as one-shots or periodically.
27
28;;; Code:
29
30;; Layout of a timer vector:
31;; [triggered-p high-seconds low-seconds usecs repeat-delay
32;; function args idle-delay]
b8bd37f2
RS
33;; triggered-p is nil if the timer is active (waiting to be triggered),
34;; t if it is inactive ("already triggered", in theory)
5e046f6d 35
e0f0f3ef
SM
36(eval-when-compile (require 'cl))
37
38(defstruct (timer
39 (:constructor nil)
40 (:copier nil)
41 (:constructor timer-create ())
42 (:type vector)
43 (:conc-name timer--))
44 (triggered t)
45 high-seconds low-seconds usecs repeat-delay function args idle-delay)
5e046f6d
JB
46
47(defun timerp (object)
48 "Return t if OBJECT is a timer."
49 (and (vectorp object) (= (length object) 8)))
50
e0f0f3ef
SM
51;; Pseudo field `time'.
52(defun timer--time (timer)
53 (list (timer--high-seconds timer)
54 (timer--low-seconds timer)
55 (timer--usecs timer)))
56
57(defsetf timer--time
58 (lambda (timer time)
59 (or (timerp timer) (error "Invalid timer"))
60 (setf (timer--high-seconds timer) (pop time))
61 (setf (timer--low-seconds timer)
62 (if (consp time) (car time) time))
63 (setf (timer--usecs timer) (or (and (consp time) (consp (cdr time))
64 (cadr time))
65 0))))
66
67
5e046f6d
JB
68(defun timer-set-time (timer time &optional delta)
69 "Set the trigger time of TIMER to TIME.
70TIME must be in the internal format returned by, e.g., `current-time'.
71If optional third argument DELTA is a positive number, make the timer
72fire repeatedly that many seconds apart."
e0f0f3ef
SM
73 (setf (timer--time timer) time)
74 (setf (timer--repeat-delay timer) (and (numberp delta) (> delta 0) delta))
5e046f6d
JB
75 timer)
76
77(defun timer-set-idle-time (timer secs &optional repeat)
78 "Set the trigger idle time of TIMER to SECS.
1063efe8
CY
79SECS may be an integer, floating point number, or the internal
80time format (HIGH LOW USECS) returned by, e.g., `current-idle-time'.
5e046f6d
JB
81If optional third argument REPEAT is non-nil, make the timer
82fire each time Emacs is idle for that many seconds."
1063efe8 83 (if (consp secs)
e0f0f3ef
SM
84 (setf (timer--time timer) secs)
85 (setf (timer--time timer) '(0 0 0))
1063efe8 86 (timer-inc-time timer secs))
e0f0f3ef 87 (setf (timer--repeat-delay timer) repeat)
5e046f6d
JB
88 timer)
89
90(defun timer-next-integral-multiple-of-time (time secs)
91 "Yield the next value after TIME that is an integral multiple of SECS.
92More precisely, the next value, after TIME, that is an integral multiple
93of SECS seconds since the epoch. SECS may be a fraction."
94 (let ((time-base (ash 1 16)))
9a0dd02d
GM
95 ;; Use floating point, taking care to not lose precision.
96 (let* ((float-time-base (float time-base))
97 (million 1000000.0)
98 (time-usec (+ (* million
99 (+ (* float-time-base (nth 0 time))
100 (nth 1 time)))
101 (nth 2 time)))
102 (secs-usec (* million secs))
103 (mod-usec (mod time-usec secs-usec))
104 (next-usec (+ (- time-usec mod-usec) secs-usec))
105 (time-base-million (* float-time-base million)))
106 (list (floor next-usec time-base-million)
107 (floor (mod next-usec time-base-million) million)
108 (floor (mod next-usec million))))))
5e046f6d
JB
109
110(defun timer-relative-time (time secs &optional usecs)
111 "Advance TIME by SECS seconds and optionally USECS microseconds.
1063efe8 112SECS may be either an integer or a floating point number."
fe955043
PE
113 (let ((delta (if (floatp secs)
114 (seconds-to-time secs)
115 (list (floor secs 65536) (mod secs 65536)))))
116 (if usecs
117 (setq delta (time-add delta (list 0 0 usecs))))
118 (time-add time delta)))
5e046f6d 119
e0f0f3ef
SM
120(defun timer--time-less-p (t1 t2)
121 "Say whether time value T1 is less than time value T2."
122 ;; FIXME just use time-less-p.
123 (destructuring-bind (high1 low1 micro1) (timer--time t1)
124 (destructuring-bind (high2 low2 micro2) (timer--time t2)
125 (or (< high1 high2)
126 (and (= high1 high2)
127 (or (< low1 low2)
128 (and (= low1 low2)
129 (< micro1 micro2))))))))
130
5e046f6d
JB
131(defun timer-inc-time (timer secs &optional usecs)
132 "Increment the time set in TIMER by SECS seconds and USECS microseconds.
133SECS may be a fraction. If USECS is omitted, that means it is zero."
e0f0f3ef
SM
134 (setf (timer--time timer)
135 (timer-relative-time (timer--time timer) secs usecs)))
5e046f6d
JB
136
137(defun timer-set-time-with-usecs (timer time usecs &optional delta)
138 "Set the trigger time of TIMER to TIME plus USECS.
139TIME must be in the internal format returned by, e.g., `current-time'.
140The microsecond count from TIME is ignored, and USECS is used instead.
141If optional fourth argument DELTA is a positive number, make the timer
142fire repeatedly that many seconds apart."
e0f0f3ef
SM
143 (setf (timer--time timer) time)
144 (setf (timer--usecs timer) usecs)
145 (setf (timer--repeat-delay timer) (and (numberp delta) (> delta 0) delta))
5e046f6d
JB
146 timer)
147(make-obsolete 'timer-set-time-with-usecs
148 "use `timer-set-time' and `timer-inc-time' instead."
bf247b6e 149 "22.1")
5e046f6d
JB
150
151(defun timer-set-function (timer function &optional args)
152 "Make TIMER call FUNCTION with optional ARGS when triggering."
153 (or (timerp timer)
154 (error "Invalid timer"))
e0f0f3ef
SM
155 (setf (timer--function timer) function)
156 (setf (timer--args timer) args)
5e046f6d
JB
157 timer)
158\f
e0f0f3ef 159(defun timer--activate (timer &optional triggered-p reuse-cell idle)
5e046f6d 160 (if (and (timerp timer)
e0f0f3ef
SM
161 (integerp (timer--high-seconds timer))
162 (integerp (timer--low-seconds timer))
163 (integerp (timer--usecs timer))
164 (timer--function timer))
165 (let ((timers (if idle timer-idle-list timer-list))
5e046f6d
JB
166 last)
167 ;; Skip all timers to trigger before the new one.
e0f0f3ef 168 (while (and timers (timer--time-less-p (car timers) timer))
5e046f6d
JB
169 (setq last timers
170 timers (cdr timers)))
dbbee529
RS
171 (if reuse-cell
172 (progn
173 (setcar reuse-cell timer)
174 (setcdr reuse-cell timers))
175 (setq reuse-cell (cons timer timers)))
5e046f6d 176 ;; Insert new timer after last which possibly means in front of queue.
7dbe3dbc
CY
177 (cond (last (setcdr last reuse-cell))
178 (idle (setq timer-idle-list reuse-cell))
179 (t (setq timer-list reuse-cell)))
e0f0f3ef
SM
180 (setf (timer--triggered timer) triggered-p)
181 (setf (timer--idle-delay timer) idle)
5e046f6d
JB
182 nil)
183 (error "Invalid or uninitialized timer")))
184
7dbe3dbc
CY
185(defun timer-activate (timer &optional triggered-p reuse-cell)
186 "Insert TIMER into `timer-list'.
187If TRIGGERED-P is t, make TIMER inactive (put it on the list, but
188mark it as already triggered). To remove it, use `cancel-timer'.
e0f0f3ef 189
7dbe3dbc
CY
190REUSE-CELL, if non-nil, is a cons cell to reuse when inserting
191TIMER into `timer-list' (usually a cell removed from that list by
192`cancel-timer-internal'; using this reduces consing for repeat
193timers). If nil, allocate a new cell."
e0f0f3ef
SM
194 (timer--activate timer triggered-p reuse-cell nil))
195
dbbee529 196(defun timer-activate-when-idle (timer &optional dont-wait reuse-cell)
7dbe3dbc
CY
197 "Insert TIMER into `timer-idle-list'.
198This arranges to activate TIMER whenever Emacs is next idle.
199If optional argument DONT-WAIT is non-nil, set TIMER to activate
200immediately, or at the right time, if Emacs is already idle.
201
202REUSE-CELL, if non-nil, is a cons cell to reuse when inserting
203TIMER into `timer-idle-list' (usually a cell removed from that
204list by `cancel-timer-internal'; using this reduces consing for
205repeat timers). If nil, allocate a new cell."
e0f0f3ef 206 (timer--activate timer (not dont-wait) reuse-cell 'idle))
5e046f6d 207
5e046f6d 208(defalias 'disable-timeout 'cancel-timer)
f31b1257 209
5e046f6d
JB
210(defun cancel-timer (timer)
211 "Remove TIMER from the list of active timers."
212 (or (timerp timer)
213 (error "Invalid timer"))
214 (setq timer-list (delq timer timer-list))
215 (setq timer-idle-list (delq timer timer-idle-list))
216 nil)
217
dbbee529 218(defun cancel-timer-internal (timer)
b8bd37f2
RS
219 "Remove TIMER from the list of active timers or idle timers.
220Only to be used in this file. It returns the cons cell
221that was removed from the timer list."
dbbee529
RS
222 (let ((cell1 (memq timer timer-list))
223 (cell2 (memq timer timer-idle-list)))
224 (if cell1
225 (setq timer-list (delq timer timer-list)))
226 (if cell2
227 (setq timer-idle-list (delq timer timer-idle-list)))
228 (or cell1 cell2)))
229
5e046f6d 230(defun cancel-function-timers (function)
b8bd37f2
RS
231 "Cancel all timers which would run FUNCTION.
232This affects ordinary timers such as are scheduled by `run-at-time',
233and idle timers such as are scheduled by `run-with-idle-timer'."
5e046f6d 234 (interactive "aCancel timers of function: ")
e0f0f3ef
SM
235 (dolist (timer timer-list)
236 (if (eq (timer--function timer) function)
237 (setq timer-list (delq timer timer-list))))
238 (dolist (timer timer-idle-list)
239 (if (eq (timer--function timer) function)
240 (setq timer-idle-list (delq timer timer-idle-list)))))
5e046f6d
JB
241\f
242;; Record the last few events, for debugging.
b8bd37f2
RS
243(defvar timer-event-last nil
244 "Last timer that was run.")
245(defvar timer-event-last-1 nil
246 "Next-to-last timer that was run.")
247(defvar timer-event-last-2 nil
248 "Third-to-last timer that was run.")
5e046f6d
JB
249
250(defvar timer-max-repeats 10
e00c3f6f
RS
251 "*Maximum number of times to repeat a timer, if many repeats are delayed.
252Timer invocations can be delayed because Emacs is suspended or busy,
253or because the system's time changes. If such an occurrence makes it
254appear that many invocations are overdue, this variable controls
255how many will really happen.")
5e046f6d
JB
256
257(defun timer-until (timer time)
258 "Calculate number of seconds from when TIMER will run, until TIME.
259TIMER is a timer, and stands for the time when its next repeat is scheduled.
260TIME is a time-list."
f34755dc 261 (float-time (time-subtract time (timer--time timer))))
5e046f6d
JB
262
263(defun timer-event-handler (timer)
264 "Call the handler for the timer TIMER.
265This function is called, by name, directly by the C code."
266 (setq timer-event-last-2 timer-event-last-1)
267 (setq timer-event-last-1 timer-event-last)
268 (setq timer-event-last timer)
269 (let ((inhibit-quit t))
270 (if (timerp timer)
dbbee529
RS
271 (let (retrigger cell)
272 ;; Delete from queue. Record the cons cell that was used.
273 (setq cell (cancel-timer-internal timer))
5e046f6d 274 ;; Re-schedule if requested.
e0f0f3ef
SM
275 (if (timer--repeat-delay timer)
276 (if (timer--idle-delay timer)
dbbee529 277 (timer-activate-when-idle timer nil cell)
e0f0f3ef 278 (timer-inc-time timer (timer--repeat-delay timer) 0)
5e046f6d
JB
279 ;; If real time has jumped forward,
280 ;; perhaps because Emacs was suspended for a long time,
281 ;; limit how many times things get repeated.
282 (if (and (numberp timer-max-repeats)
283 (< 0 (timer-until timer (current-time))))
284 (let ((repeats (/ (timer-until timer (current-time))
e0f0f3ef 285 (timer--repeat-delay timer))))
5e046f6d 286 (if (> repeats timer-max-repeats)
e0f0f3ef
SM
287 (timer-inc-time timer (* (timer--repeat-delay timer)
288 repeats)))))
dbbee529 289 (timer-activate timer t cell)
6160f933 290 (setq retrigger t)))
5e046f6d
JB
291 ;; Run handler.
292 ;; We do this after rescheduling so that the handler function
293 ;; can cancel its own timer successfully with cancel-timer.
294 (condition-case nil
0798a8d8
SM
295 ;; Timer functions should not change the current buffer.
296 ;; If they do, all kinds of nasty surprises can happen,
297 ;; and it can be hellish to track down their source.
298 (save-current-buffer
299 (apply (timer--function timer) (timer--args timer)))
6160f933
KS
300 (error nil))
301 (if retrigger
e0f0f3ef 302 (setf (timer--triggered timer) nil)))
5e046f6d
JB
303 (error "Bogus timer event"))))
304
305;; This function is incompatible with the one in levents.el.
306(defun timeout-event-p (event)
307 "Non-nil if EVENT is a timeout event."
308 (and (listp event) (eq (car event) 'timer-event)))
309\f
153ef845 310
5cec3056 311(declare-function diary-entry-time "diary-lib" (s))
153ef845 312
5e046f6d
JB
313(defun run-at-time (time repeat function &rest args)
314 "Perform an action at time TIME.
315Repeat the action every REPEAT seconds, if REPEAT is non-nil.
b9be25fd
GM
316TIME should be one of: a string giving an absolute time like
317\"11:23pm\" (the acceptable formats are those recognized by
318`diary-entry-time'; note that such times are interpreted as times
319today, even if in the past); a string giving a relative time like
320\"2 hours 35 minutes\" (the acceptable formats are those
321recognized by `timer-duration'); nil meaning now; a number of
322seconds from now; a value from `encode-time'; or t (with non-nil
323REPEAT) meaning the next integral multiple of REPEAT. REPEAT may
324be an integer or floating point number. The action is to call
325FUNCTION with arguments ARGS.
5e046f6d
JB
326
327This function returns a timer object which you can use in `cancel-timer'."
328 (interactive "sRun at time: \nNRepeat interval: \naFunction: ")
329
330 (or (null repeat)
331 (and (numberp repeat) (< 0 repeat))
332 (error "Invalid repetition interval"))
333
334 ;; Special case: nil means "now" and is useful when repeating.
335 (if (null time)
336 (setq time (current-time)))
337
338 ;; Special case: t means the next integral multiple of REPEAT.
339 (if (and (eq time t) repeat)
340 (setq time (timer-next-integral-multiple-of-time (current-time) repeat)))
341
342 ;; Handle numbers as relative times in seconds.
343 (if (numberp time)
344 (setq time (timer-relative-time (current-time) time)))
345
b9be25fd 346 ;; Handle relative times like "2 hours 35 minutes"
5e046f6d
JB
347 (if (stringp time)
348 (let ((secs (timer-duration time)))
349 (if secs
350 (setq time (timer-relative-time (current-time) secs)))))
351
352 ;; Handle "11:23pm" and the like. Interpret it as meaning today
353 ;; which admittedly is rather stupid if we have passed that time
354 ;; already. (Though only Emacs hackers hack Emacs at that time.)
355 (if (stringp time)
356 (progn
357 (require 'diary-lib)
358 (let ((hhmm (diary-entry-time time))
359 (now (decode-time)))
360 (if (>= hhmm 0)
361 (setq time
362 (encode-time 0 (% hhmm 100) (/ hhmm 100) (nth 3 now)
363 (nth 4 now) (nth 5 now) (nth 8 now)))))))
364
365 (or (consp time)
366 (error "Invalid time format"))
367
368 (let ((timer (timer-create)))
369 (timer-set-time timer time repeat)
370 (timer-set-function timer function args)
371 (timer-activate timer)
372 timer))
373
5e046f6d
JB
374(defun run-with-timer (secs repeat function &rest args)
375 "Perform an action after a delay of SECS seconds.
376Repeat the action every REPEAT seconds, if REPEAT is non-nil.
377SECS and REPEAT may be integers or floating point numbers.
378The action is to call FUNCTION with arguments ARGS.
379
380This function returns a timer object which you can use in `cancel-timer'."
381 (interactive "sRun after delay (seconds): \nNRepeat interval: \naFunction: ")
382 (apply 'run-at-time secs repeat function args))
383
5e046f6d
JB
384(defun add-timeout (secs function object &optional repeat)
385 "Add a timer to run SECS seconds from now, to call FUNCTION on OBJECT.
386If REPEAT is non-nil, repeat the timer every REPEAT seconds.
387This function is for compatibility; see also `run-with-timer'."
388 (run-with-timer secs repeat function object))
389
5e046f6d
JB
390(defun run-with-idle-timer (secs repeat function &rest args)
391 "Perform an action the next time Emacs is idle for SECS seconds.
392The action is to call FUNCTION with arguments ARGS.
1063efe8
CY
393SECS may be an integer, a floating point number, or the internal
394time format (HIGH LOW USECS) returned by, e.g., `current-idle-time'.
171d328e
RS
395If Emacs is currently idle, and has been idle for N seconds (N < SECS),
396then it will call FUNCTION in SECS - N seconds from now.
5e046f6d
JB
397
398If REPEAT is non-nil, do the action each time Emacs has been idle for
399exactly SECS seconds (that is, only once for each time Emacs becomes idle).
400
401This function returns a timer object which you can use in `cancel-timer'."
402 (interactive
403 (list (read-from-minibuffer "Run after idle (seconds): " nil nil t)
404 (y-or-n-p "Repeat each time Emacs is idle? ")
405 (intern (completing-read "Function: " obarray 'fboundp t))))
406 (let ((timer (timer-create)))
407 (timer-set-function timer function args)
408 (timer-set-idle-time timer secs repeat)
171d328e 409 (timer-activate-when-idle timer t)
5e046f6d
JB
410 timer))
411\f
412(defun with-timeout-handler (tag)
b8bd37f2 413 "This is the timer function used for the timer made by `with-timeout'."
5e046f6d
JB
414 (throw tag 'timeout))
415
89c020e8
RS
416(defvar with-timeout-timers nil
417 "List of all timers used by currently pending `with-timeout' calls.")
418
5e046f6d
JB
419(defmacro with-timeout (list &rest body)
420 "Run BODY, but if it doesn't finish in SECONDS seconds, give up.
421If we give up, we run the TIMEOUT-FORMS and return the value of the last one.
5e046f6d 422The timeout is checked whenever Emacs waits for some kind of external
7452fadc 423event (such as keyboard input, input from subprocesses, or a certain time);
5e046f6d 424if the program loops without waiting in any way, the timeout will not
7452fadc
JB
425be detected.
426\n(fn (SECONDS TIMEOUT-FORMS...) BODY)"
f291fe60 427 (declare (indent 1))
5e046f6d
JB
428 (let ((seconds (car list))
429 (timeout-forms (cdr list)))
430 `(let ((with-timeout-tag (cons nil nil))
89c020e8
RS
431 with-timeout-value with-timeout-timer
432 (with-timeout-timers with-timeout-timers))
5e046f6d
JB
433 (if (catch with-timeout-tag
434 (progn
435 (setq with-timeout-timer
436 (run-with-timer ,seconds nil
437 'with-timeout-handler
438 with-timeout-tag))
89c020e8 439 (push with-timeout-timer with-timeout-timers)
5e046f6d
JB
440 (setq with-timeout-value (progn . ,body))
441 nil))
442 (progn . ,timeout-forms)
443 (cancel-timer with-timeout-timer)
444 with-timeout-value))))
445
89c020e8
RS
446(defun with-timeout-suspend ()
447 "Stop the clock for `with-timeout'. Used by debuggers.
448The idea is that the time you spend in the debugger should not
449count against these timeouts.
450
451The value is a list that the debugger can pass to `with-timeout-unsuspend'
452when it exits, to make these timers start counting again."
453 (mapcar (lambda (timer)
454 (cancel-timer timer)
e0f0f3ef 455 (list timer (time-subtract (timer--time timer) (current-time))))
89c020e8
RS
456 with-timeout-timers))
457
458(defun with-timeout-unsuspend (timer-spec-list)
459 "Restart the clock for `with-timeout'.
460The argument should be a value previously returned by `with-timeout-suspend'."
461 (dolist (elt timer-spec-list)
462 (let ((timer (car elt))
463 (delay (cadr elt)))
64ba814f 464 (timer-set-time timer (time-add (current-time) delay))
89c020e8
RS
465 (timer-activate timer))))
466
5e046f6d
JB
467(defun y-or-n-p-with-timeout (prompt seconds default-value)
468 "Like (y-or-n-p PROMPT), with a timeout.
469If the user does not answer after SECONDS seconds, return DEFAULT-VALUE."
470 (with-timeout (seconds default-value)
471 (y-or-n-p prompt)))
472\f
2f7f4bee 473(defconst timer-duration-words
5e046f6d
JB
474 (list (cons "microsec" 0.000001)
475 (cons "microsecond" 0.000001)
476 (cons "millisec" 0.001)
477 (cons "millisecond" 0.001)
478 (cons "sec" 1)
479 (cons "second" 1)
480 (cons "min" 60)
481 (cons "minute" 60)
482 (cons "hour" (* 60 60))
483 (cons "day" (* 24 60 60))
484 (cons "week" (* 7 24 60 60))
485 (cons "fortnight" (* 14 24 60 60))
486 (cons "month" (* 30 24 60 60)) ; Approximation
487 (cons "year" (* 365.25 24 60 60)) ; Approximation
488 )
64ba814f 489 "Alist mapping temporal words to durations in seconds.")
5e046f6d
JB
490
491(defun timer-duration (string)
492 "Return number of seconds specified by STRING, or nil if parsing fails."
493 (let ((secs 0)
494 (start 0)
495 (case-fold-search t))
496 (while (string-match
497 "[ \t]*\\([0-9.]+\\)?[ \t]*\\([a-z]+[a-rt-z]\\)s?[ \t]*"
498 string start)
499 (let ((count (if (match-beginning 1)
500 (string-to-number (match-string 1 string))
501 1))
502 (itemsize (cdr (assoc (match-string 2 string)
503 timer-duration-words))))
504 (if itemsize
505 (setq start (match-end 0)
506 secs (+ secs (* count itemsize)))
507 (setq secs nil
508 start (length string)))))
509 (if (= start (length string))
510 secs
64ba814f 511 (if (string-match-p "\\`[0-9.]+\\'" string)
5e046f6d
JB
512 (string-to-number string)))))
513\f
514(provide 'timer)
515
516;;; timer.el ends here