# HG changeset patch # User Karl Heuer # Date 824938137 0 # Node ID f50f87fae91425fce6645a0b54cc08cdb9319b24 # Parent 25ecb6e5fffca744f6382259016e3a3397900b7d (run-with-idle-timer): New function. (timer-create, timerp): Leave a slot for idle-delay. (timer-activate-when-idle): New function. (timer-event-handler): Handle idle-delay timers specially. (cancel-timer, cancel-function-timers): Handle idle-delay timers. diff -r 25ecb6e5fffc -r f50f87fae914 lisp/timer.el --- a/lisp/timer.el Wed Feb 21 21:28:23 1996 +0000 +++ b/lisp/timer.el Wed Feb 21 21:28:57 1996 +0000 @@ -29,17 +29,18 @@ ;;; Code: ;; Layout of a timer vector: -;; [triggered-p high-seconds low-seconds usecs delta-secs function args] +;; [triggered-p high-seconds low-seconds usecs repeat-delay +;; function args idle-delay] (defun timer-create () "Create a timer object." - (let ((timer (make-vector 7 nil))) + (let ((timer (make-vector 8 nil))) (aset timer 0 t) timer)) (defun timerp (object) "Return t if OBJECT is a timer." - (and (vectorp object) (= (length object) 7))) + (and (vectorp object) (= (length object) 8))) (defun timer-set-time (timer time &optional delta) "Set the trigger time of TIMER to TIME. @@ -132,6 +133,35 @@ (setcdr last (cons timer timers)) (setq timer-list (cons timer timers))) (aset timer 0 nil) + (aset timer 7 nil) + nil) + (error "Invalid or uninitialized timer"))) + +(defun timer-activate-when-idle (timer) + "Arrange to activate TIMER whenever Emacs is next idle." + (if (and (timerp timer) + (integerp (aref timer 1)) + (integerp (aref timer 2)) + (integerp (aref timer 3)) + (aref timer 5)) + (let ((timers timer-idle-list) + last) + ;; Skip all timers to trigger before the new one. + (while (and timers + (or (> (aref timer 1) (aref (car timers) 1)) + (and (= (aref timer 1) (aref (car timers) 1)) + (> (aref timer 2) (aref (car timers) 2))) + (and (= (aref timer 1) (aref (car timers) 1)) + (= (aref timer 2) (aref (car timers) 2)) + (> (aref timer 3) (aref (car timers) 3))))) + (setq last timers + timers (cdr timers))) + ;; Insert new timer after last which possibly means in front of queue. + (if last + (setcdr last (cons timer timers)) + (setq timer-idle-list (cons timer timers))) + (aset timer 0 t) + (aset timer 7 t) nil) (error "Invalid or uninitialized timer"))) @@ -141,6 +171,7 @@ (or (timerp timer) (error "Invalid timer")) (setq timer-list (delq timer timer-list)) + (setq timer-idle-list (delq timer timer-idle-list)) nil) (defun cancel-function-timers (function) @@ -150,6 +181,11 @@ (while tail (if (eq (aref (car tail) 5) function) (setq timer-list (delq (car tail) timer-list))) + (setq tail (cdr tail)))) + (let ((tail timer-idle-list)) + (while tail + (if (eq (aref (car tail) 5) function) + (setq timer-idle-list (delq (car tail) timer-idle-list))) (setq tail (cdr tail))))) ;; Set up the common handler for all timer events. Since the event has @@ -169,7 +205,8 @@ (apply (aref timer 5) (aref timer 6)) ;; Re-schedule if requested. (if (aref timer 4) - (progn + (if (aref timer 7) + (timer-activate-when-idle timer) (timer-inc-time timer (aref timer 4) 0) (timer-activate timer)))) (error "Bogus timer event")))) @@ -246,6 +283,27 @@ (timer-set-function timer function args) (timer-activate timer) timer)) + +;;;###autoload +(defun run-with-idle-timer (secs repeat function &rest args) + "Perform an action the next time Emacs is idle for SECS seconds. +The action is to call FUNCTION with arguments ARGS. +If REPEAT is non-nil, do this each time Emacs is idle for SECS seconds. +SECS may be an integer or a floating point number. + +This function returns a timer object which you can use in `cancel-timer'." + (interactive "sRun after delay (seconds): \nNRepeat interval: \naFunction: ") + + (let ((timer (timer-create))) + (timer-set-function timer function args) + ;; Store 0 into the time fields, then add in SECS. + (aset timer 1 0) + (aset timer 2 0) + (aset timer 3 0) + (timer-inc-time timer secs) + (aset timer 4 repeat) + (timer-activate-when-idle timer) + timer)) ;;;###autoload (defun add-timeout (secs function object &optional repeat)