Mercurial > hg > xemacs-beta
comparison lisp/prim/itimer.el @ 108:360340f9fd5f r20-1b6
Import from CVS: tag r20-1b6
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:18:39 +0200 |
parents | a145efe76779 |
children | fe104dbd9147 |
comparison
equal
deleted
inserted
replaced
107:523141596bda | 108:360340f9fd5f |
---|---|
1 ;;; itimer.el -- Interval timers for XEmacs | 1 ;;; Interval timers for GNU Emacs |
2 | 2 ;;; Copyright (C) 1988, 1991, 1993, 1997 Kyle E. Jones |
3 ;; Copyright (C) 1988, 1991, 1993, 1997 Kyle E. Jones | 3 ;;; |
4 | 4 ;;; This program is free software; you can redistribute it and/or modify |
5 ;; Author: Kyle Jones <kyle_jones@wonderworks.com> | 5 ;;; it under the terms of the GNU General Public License as published by |
6 ;; Keywords: extensions | 6 ;;; the Free Software Foundation; either version 2, or (at your option) |
7 | 7 ;;; any later version. |
8 ;; This file is part of XEmacs | 8 ;;; |
9 | 9 ;;; This program is distributed in the hope that it will be useful, |
10 ;; XEmacs is free software; you can redistribute it and/or modify it | 10 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 ;; under the terms of the GNU General Public License as published by | 11 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 ;; the Free Software Foundation; either version 2, or (at your option) | 12 ;;; GNU General Public License for more details. |
13 ;; any later version. | 13 ;;; |
14 | 14 ;;; A copy of the GNU General Public License can be obtained from this |
15 ;; XEmacs is distributed in the hope that it will be useful, but | 15 ;;; program's author (send electronic mail to kyle@uunet.uu.net) or from |
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | 16 ;;; the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA |
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 17 ;;; 02139, USA. |
18 ;; General Public License for more details. | 18 ;;; |
19 | 19 ;;; Send bug reports to kyle_jones@wonderworks.com |
20 ;; A copy of the GNU General Public License can be obtained from this | |
21 ;; program's author (send electronic mail to kyle@uunet.uu.net) or | |
22 ;; from the Free Software Foundation, Inc., 59 Temple Place - Suite | |
23 ;; 330, Boston, MA 02111-1307, USA. | |
24 | |
25 ;;; Synched up with: Not in FSF | |
26 | |
27 ;;; Commentary: | |
28 | |
29 ;; Send bug reports to kyle_jones@wonderworks.com | |
30 | |
31 ;;; Code: | |
32 | 20 |
33 (provide 'itimer) | 21 (provide 'itimer) |
34 | 22 |
35 ;; `itimer' feature means Emacs-Lisp programmers get: | 23 ;; `itimer' feature means Emacs-Lisp programmers get: |
36 ;; itimerp | 24 ;; itimerp |
37 ;; itimer-value | 25 ;; itimer-value |
38 ;; itimer-restart | 26 ;; itimer-restart |
39 ;; itimer-function | 27 ;; itimer-function |
40 ;; itimer-function-argument | 28 ;; itimer-uses-arguments |
29 ;; itimer-function-arguments | |
41 ;; set-itimer-value | 30 ;; set-itimer-value |
42 ;; set-itimer-restart | 31 ;; set-itimer-restart |
43 ;; set-itimer-function | 32 ;; set-itimer-function |
44 ;; set-itimer-uses-argument | 33 ;; set-itimer-uses-arguments |
45 ;; set-itimer-function-argument | 34 ;; set-itimer-function-arguments |
46 ;; get-itimer | 35 ;; get-itimer |
47 ;; start-itimer | 36 ;; start-itimer |
48 ;; read-itimer | 37 ;; read-itimer |
49 ;; delete-itimer | 38 ;; delete-itimer |
39 ;; activate-itimer | |
50 ;; | 40 ;; |
51 ;; Interactive users get these commands: | 41 ;; Interactive users get these commands: |
52 ;; edit-itimers | 42 ;; edit-itimers |
53 ;; list-itimers | 43 ;; list-itimers |
54 ;; start-itimer | 44 ;; start-itimer |
55 ;; | 45 ;; |
56 ;; See the doc strings of these functions for more information. | 46 ;; See the doc strings of these functions for more information. |
57 | 47 |
58 (defvar itimer-version "1.02" | 48 (defvar itimer-version "1.03" |
59 "Version number of the itimer package.") | 49 "Version number of the itimer package.") |
60 | 50 |
61 (defvar itimer-list nil | 51 (defvar itimer-list nil |
62 "List of all active itimers.") | 52 "List of all active itimers.") |
63 | 53 |
165 | 155 |
166 ;; Functions to access and modify itimer attributes. | 156 ;; Functions to access and modify itimer attributes. |
167 | 157 |
168 (defun itimerp (obj) | 158 (defun itimerp (obj) |
169 "Returns non-nil iff OBJ is an itimer." | 159 "Returns non-nil iff OBJ is an itimer." |
170 (and (consp obj) (stringp (car obj)) (eq (length obj) 6))) | 160 (and (consp obj) (eq (length obj) 8))) |
171 | 161 |
172 (defun itimer-name (itimer) | 162 (defun itimer-name (itimer) |
173 "Returns the name of ITIMER." | 163 "Returns the name of ITIMER." |
174 (check-itimer itimer) | 164 (check-itimer itimer) |
175 (car itimer)) | 165 (car itimer)) |
189 "Returns the function of ITIMER. | 179 "Returns the function of ITIMER. |
190 This function is called each time ITIMER expires." | 180 This function is called each time ITIMER expires." |
191 (check-itimer itimer) | 181 (check-itimer itimer) |
192 (nth 3 itimer)) | 182 (nth 3 itimer)) |
193 | 183 |
194 (defun itimer-uses-argument (itimer) | 184 (defun itimer-is-idle (itimer) |
195 "Returns non-nil if the function of ITIMER will be called with an argment. | 185 "Returns non-nil if ITIMER is an idle timer. |
196 ITIMER's function is called with this argument each timer ITIMER expires." | 186 Normal timers eexpire after a set interval. Idle timers expire |
187 only after Emacs has been idle for a specific interval. ``Idle'' | |
188 means no command events within the interval." | |
197 (check-itimer itimer) | 189 (check-itimer itimer) |
198 (nth 4 itimer)) | 190 (nth 4 itimer)) |
199 | 191 |
200 (defun itimer-function-argument (itimer) | 192 (defun itimer-uses-arguments (itimer) |
201 "Returns the function argument of ITIMER. | 193 "Returns non-nil if the function of ITIMER will be called with arguments. |
202 ITIMER's function is called with this argument each timer ITIMER expires." | 194 ITIMER's function is called with the arguments each time ITIMER expires. |
195 The arguments themselves are retrievable with `itimer-function-arguments'." | |
203 (check-itimer itimer) | 196 (check-itimer itimer) |
204 (nth 5 itimer)) | 197 (nth 5 itimer)) |
198 | |
199 (defun itimer-function-arguments (itimer) | |
200 "Returns the function arguments of ITIMER as a list. | |
201 ITIMER's function is called with these argument each timer ITIMER expires." | |
202 (check-itimer itimer) | |
203 (nth 6 itimer)) | |
204 | |
205 (defun itimer-recorded-run-time (itimer) | |
206 (check-itimer itimer) | |
207 (nth 7 itimer)) | |
205 | 208 |
206 (defun set-itimer-value (itimer value) | 209 (defun set-itimer-value (itimer value) |
207 "Set the timeout value of ITIMER to be VALUE. | 210 "Set the timeout value of ITIMER to be VALUE. |
208 Itimer will expire is this many seconds. | 211 Itimer will expire is this many seconds. |
209 If your version of Emacs supports floating point numbers then | 212 If your version of Emacs supports floating point numbers then |
246 (defun set-itimer-function (itimer function) | 249 (defun set-itimer-function (itimer function) |
247 "Set the function of ITIMER to be FUNCTION. | 250 "Set the function of ITIMER to be FUNCTION. |
248 FUNCTION will be called when itimer expires. | 251 FUNCTION will be called when itimer expires. |
249 Returns FUNCTION." | 252 Returns FUNCTION." |
250 (check-itimer itimer) | 253 (check-itimer itimer) |
251 (setcar (cdr (cdr (cdr itimer))) function)) | 254 (setcar (nthcdr 3 itimer) function)) |
252 | 255 |
253 (defun set-itimer-uses-argument (itimer flag) | 256 (defun set-itimer-is-idle (itimer flag) |
254 "Sets when the function of ITIMER is called with an argument. | 257 "Sets flag that says whether ITIMER is an idle timer. |
258 If FLAG is non-nil, then ITIMER will eb considered an idle timer. | |
259 Returns FLAG." | |
260 (check-itimer itimer) | |
261 (setcar (nthcdr 4 itimer) flag)) | |
262 | |
263 (defun set-itimer-uses-arguments (itimer flag) | |
264 "Sets flag that says whether the function of ITIMER is called with arguments. | |
255 If FLAG is non-nil, then the function will be called with one argument, | 265 If FLAG is non-nil, then the function will be called with one argument, |
256 otherwise the function will be called with no arguments. | 266 otherwise the function will be called with no arguments. |
257 Returns FLAG." | 267 Returns FLAG." |
258 (check-itimer itimer) | 268 (check-itimer itimer) |
259 (setcar (nthcdr 4 itimer) flag)) | 269 (setcar (nthcdr 5 itimer) flag)) |
260 | 270 |
261 (defun set-itimer-function-argument (itimer argument) | 271 (defun set-itimer-function-arguments (itimer &rest arguments) |
262 "Set the function of ITIMER to be ARGUMENT. | 272 "Set the function arguments of ITIMER to be ARGUMENTS. |
263 The function of ITIMER will be called with ARGUMENT as its solt argument | 273 The function of ITIMER will be called with ARGUMENTS when itimer expires. |
264 when itimer expires. | 274 Returns ARGUMENTS." |
265 Returns ARGUMENT." | 275 (check-itimer itimer) |
266 (check-itimer itimer) | 276 (setcar (nthcdr 6 itimer) arguments)) |
267 (setcar (nthcdr 5 itimer) argument)) | 277 |
278 (defun set-itimer-recorded-run-time (itimer time) | |
279 (check-itimer itimer) | |
280 (setcar (nthcdr 7 itimer) time)) | |
268 | 281 |
269 (defun get-itimer (name) | 282 (defun get-itimer (name) |
270 "Return itimer named NAME, or nil if there is none." | 283 "Return itimer named NAME, or nil if there is none." |
271 (check-string name) | 284 (check-string name) |
272 (assoc name itimer-list)) | 285 (assoc name itimer-list)) |
282 "Deletes ITIMER. ITIMER may be an itimer or the name of one." | 295 "Deletes ITIMER. ITIMER may be an itimer or the name of one." |
283 (check-itimer-coerce-string itimer) | 296 (check-itimer-coerce-string itimer) |
284 (setq itimer-list (delq itimer itimer-list))) | 297 (setq itimer-list (delq itimer itimer-list))) |
285 | 298 |
286 (defun start-itimer (name function value &optional restart | 299 (defun start-itimer (name function value &optional restart |
287 with-arg function-argument) | 300 is-idle with-args &rest function-arguments) |
288 "Start an itimer. | 301 "Start an itimer. |
289 Args are NAME, FUNCTION, VALUE &optional RESTART, WITH-ARG, FUNCTION-ARGUMENT. | 302 Arguments are |
303 NAME, FUNCTION, VALUE &optional RESTART, IS-IDLE, WITH-ARGS, &rest FUNCTION-ARGUMENTS. | |
290 NAME is an identifier for the itimer. It must be a string. If an itimer | 304 NAME is an identifier for the itimer. It must be a string. If an itimer |
291 already exists with this name, NAME will be modified slightly to until | 305 already exists with this name, NAME will be modified slightly to until |
292 it is unique. | 306 it is unique. |
293 FUNCTION should be a function (or symbol naming one) of one argument. It | 307 FUNCTION should be a function (or symbol naming one). It |
294 will be called each time the itimer expires with an argument of | 308 will be called each time the itimer expires with arguments of |
295 FUNCTION-ARGUMENT. The function can access the itimer that | 309 FUNCTION-ARGUMENTS. The function can access the itimer that |
296 invoked it through the variable `current-itimer'. If WITH-ARG | 310 invoked it through the variable `current-itimer'. If WITH-ARGS |
297 is nil then FUNCTION is called with no arguments. This is for | 311 is nil then FUNCTION is called with no arguments. This is for |
298 backward compatibility with older versions of the itimer | 312 backward compatibility with older versions of the itimer |
299 package which always called FUNCTION with no arguments. | 313 package which always called FUNCTION with no arguments. |
300 VALUE is the number of seconds until this itimer expires. | 314 VALUE is the number of seconds until this itimer expires. |
301 If your version of Emacs supports floating point numbers then | 315 If your version of Emacs supports floating point numbers then |
304 Optional fourth arg RESTART non-nil means that this itimer should be | 318 Optional fourth arg RESTART non-nil means that this itimer should be |
305 restarted automatically after its function is called. Normally an itimer | 319 restarted automatically after its function is called. Normally an itimer |
306 is deleted at expiration after its function has returned. | 320 is deleted at expiration after its function has returned. |
307 If non-nil RESTART should be a number indicating the value at which the | 321 If non-nil RESTART should be a number indicating the value at which the |
308 itimer should be set at restart time. | 322 itimer should be set at restart time. |
323 Optional fifth arg IS-IDLE specified if this is an idle timer. | |
324 Normal timers eexpire after a set interval. Idle timers expire | |
325 only after Emacs has been idle for specific interval. ``Idle'' | |
326 means no command events within the interval. | |
309 Returns the newly created itimer." | 327 Returns the newly created itimer." |
310 (interactive | 328 (interactive |
311 (list (completing-read "Start itimer: " itimer-list) | 329 (list (completing-read "Start itimer: " itimer-list) |
312 (read (completing-read "Itimer function: " obarray 'fboundp)) | 330 (read (completing-read "Itimer function: " obarray 'fboundp)) |
313 (let (value) | 331 (let (value) |
329 (let ((oname name) | 347 (let ((oname name) |
330 (num 2)) | 348 (num 2)) |
331 (while (get-itimer name) | 349 (while (get-itimer name) |
332 (setq name (concat oname "<" num ">")) | 350 (setq name (concat oname "<" num ">")) |
333 (itimer-increment num))) | 351 (itimer-increment num))) |
334 ;; If there's no itimer process, start one now. | 352 (activate-itimer (list name value restart function is-idle |
335 ;; Otherwise wake up the itimer process so that seconds slept before | 353 with-args function-arguments (list 0 0 0))) |
354 (car itimer-list)) | |
355 | |
356 (defun make-itimer () | |
357 "Create an unactivated itimer. | |
358 The itimer will not begin running until activated with `activate-itimer'. | |
359 Set the itimer's expire interval with `set-itimer-value'. | |
360 Set the itimer's function interval with `set-itimer-function'. | |
361 Once this is done, the timer can be activated." | |
362 (list nil 0 nil 'ignore nil nil nil (list 0 0 0))) | |
363 | |
364 (defun activate-itimer (itimer) | |
365 "Activate ITIMER, which was previously created with `make-itimer'. | |
366 ITIMER will be added to the global list of running itimers, | |
367 its FUNCTION will be called when it expires, and so on." | |
368 (check-itimer itimer) | |
369 (if (memq itimer itimer-list) | |
370 (error "itimer already activated")) | |
371 (if (not (numberp (itimer-value itimer))) | |
372 (error "itimer timeout value not a number: %s" (itimer-value itimer))) | |
373 (if (<= (itimer-value itimer) 0) | |
374 (error "itimer timeout value not positive: %s" (itimer-value itimer))) | |
375 ;; If there's no itimer driver/process, start one now. | |
376 ;; Otherwise wake up the itimer driver so that seconds slept before | |
336 ;; the new itimer is created won't be counted against it. | 377 ;; the new itimer is created won't be counted against it. |
337 (if (or itimer-process itimer-timer) | 378 (if (or itimer-process itimer-timer) |
338 (itimer-driver-wakeup) | 379 (itimer-driver-wakeup) |
339 (itimer-driver-start)) | 380 (itimer-driver-start)) |
381 ;; Roll a unique name for the timer if it doesn't have a name | |
382 ;; already. | |
383 (if (not (stringp (car itimer))) | |
384 (let ((name "itimer-0") | |
385 (oname "itimer-") | |
386 (num 1)) | |
387 (while (get-itimer name) | |
388 (setq name (concat oname "<" num ">")) | |
389 (itimer-increment num)) | |
390 (setcar itimer name)) | |
391 ;; signal an error if the timer's name matches an already | |
392 ;; activated timer. | |
393 (if (get-itimer (itimer-name itimer)) | |
394 (error "itimer named \"%s\" already existing and activated" | |
395 (itimer-name itimer)))) | |
340 (let ((inhibit-quit t)) | 396 (let ((inhibit-quit t)) |
341 ;; add the itimer to the global list | 397 ;; add the itimer to the global list |
342 (setq itimer-list | 398 (setq itimer-list (cons itimer itimer-list)) |
343 (cons (list name value restart function with-arg function-argument) | 399 ;; If the itimer process is scheduled to wake up too late for |
344 itimer-list)) | 400 ;; the itimer we wake it up to calculate a correct wakeup |
345 ;; If the itimer process is scheduled to wake up too late for the itimer | 401 ;; value giving consideration to the newly added itimer. |
346 ;; we wake it up to calculate a correct wakeup value giving consideration | 402 (if (< (itimer-value itimer) itimer-next-wakeup) |
347 ;; to the newly added itimer. | 403 (itimer-driver-wakeup)))) |
348 (if (< value itimer-next-wakeup) | |
349 (itimer-driver-wakeup))) | |
350 (car itimer-list)) | |
351 | 404 |
352 ;; User level functions to list and modify existing itimers. | 405 ;; User level functions to list and modify existing itimers. |
353 ;; Itimer Edit major mode, and the editing commands thereof. | 406 ;; Itimer Edit major mode, and the editing commands thereof. |
354 | 407 |
355 (defun list-itimers () | 408 (defun list-itimers () |
365 (set-buffer buf) | 418 (set-buffer buf) |
366 (itimer-edit-mode) | 419 (itimer-edit-mode) |
367 (setq buffer-read-only nil) | 420 (setq buffer-read-only nil) |
368 (erase-buffer) | 421 (erase-buffer) |
369 (insert | 422 (insert |
370 "Name Value Restart Function Argument\n" | 423 "Name Value Restart Function Idle Arguments" |
371 "---- ----- ------- -------- --------") | 424 "\n" |
425 "---- ----- ------- -------- ---- --------") | |
372 (if (null itimer-edit-start-marker) | 426 (if (null itimer-edit-start-marker) |
373 (setq itimer-edit-start-marker (point))) | 427 (setq itimer-edit-start-marker (point))) |
374 (while itimers | 428 (while itimers |
375 (newline 1) | 429 (newline 1) |
376 (prin1 (itimer-name (car itimers))) | 430 (prin1 (itimer-name (car itimers))) |
380 (tab-to-tab-stop) | 434 (tab-to-tab-stop) |
381 (insert (itimer-truncate-string | 435 (insert (itimer-truncate-string |
382 (format "%5.5s" (itimer-restart (car itimers))) 5)) | 436 (format "%5.5s" (itimer-restart (car itimers))) 5)) |
383 (tab-to-tab-stop) | 437 (tab-to-tab-stop) |
384 (insert (itimer-truncate-string | 438 (insert (itimer-truncate-string |
385 (format "%.26s" (itimer-function (car itimers))) 26)) | 439 (format "%.19s" (itimer-function (car itimers))) 19)) |
386 (tab-to-tab-stop) | 440 (tab-to-tab-stop) |
387 (if (itimer-uses-argument (car itimers)) | 441 (if (itimer-is-idle (car itimers)) |
388 (prin1 (itimer-function-argument (car itimers))) | 442 (insert "yes") |
443 (insert "no")) | |
444 (tab-to-tab-stop) | |
445 (if (itimer-uses-arguments (car itimers)) | |
446 (prin1 (itimer-function-arguments (car itimers))) | |
389 (prin1 'NONE)) | 447 (prin1 'NONE)) |
390 (setq itimers (cdr itimers))) | 448 (setq itimers (cdr itimers))) |
391 ;; restore point | 449 ;; restore point |
392 (goto-char opoint) | 450 (goto-char opoint) |
393 (if (< (point) itimer-edit-start-marker) | 451 (if (< (point) itimer-edit-start-marker) |
414 (message "type q to quit, ? for help")) | 472 (message "type q to quit, ? for help")) |
415 | 473 |
416 ;; no point in making this interactive. | 474 ;; no point in making this interactive. |
417 (defun itimer-edit-mode () | 475 (defun itimer-edit-mode () |
418 "Major mode for manipulating itimers. | 476 "Major mode for manipulating itimers. |
419 Atrributes of running itimers are changed by moving the cursor to the | 477 Attributes of running itimers are changed by moving the cursor to the |
420 desired field and typing `s' to set that field. The field will then be | 478 desired field and typing `s' to set that field. The field will then be |
421 set to the value read from the minibuffer. | 479 set to the value read from the minibuffer. |
422 | 480 |
423 Commands: | 481 Commands: |
424 TAB move forward a field | 482 TAB move forward a field |
430 (kill-all-local-variables) | 488 (kill-all-local-variables) |
431 (make-local-variable 'tab-stop-list) | 489 (make-local-variable 'tab-stop-list) |
432 (setq major-mode 'itimer-edit-mode | 490 (setq major-mode 'itimer-edit-mode |
433 mode-name "Itimer Edit" | 491 mode-name "Itimer Edit" |
434 truncate-lines t | 492 truncate-lines t |
435 tab-stop-list '(22 32 40 67)) | 493 tab-stop-list '(22 32 40 60 67)) |
436 (abbrev-mode 0) | 494 (abbrev-mode 0) |
437 (auto-fill-mode 0) | 495 (auto-fill-mode 0) |
438 (buffer-flush-undo (current-buffer)) | 496 (buffer-flush-undo (current-buffer)) |
439 (use-local-map itimer-edit-map) | 497 (use-local-map itimer-edit-map) |
440 (set-syntax-table emacs-lisp-mode-syntax-table)) | 498 (set-syntax-table emacs-lisp-mode-syntax-table)) |
476 (n 0)) | 534 (n 0)) |
477 ;; count the number of sexprs until we reach the cursor | 535 ;; count the number of sexprs until we reach the cursor |
478 ;; and use this info to determine which field the user | 536 ;; and use this info to determine which field the user |
479 ;; wants to modify. | 537 ;; wants to modify. |
480 (beginning-of-line) | 538 (beginning-of-line) |
481 (while (and (>= opoint (point)) (< n 5)) | 539 (while (and (>= opoint (point)) (< n 6)) |
482 (forward-sexp 2) | 540 (forward-sexp 2) |
483 (backward-sexp) | 541 (backward-sexp) |
484 (itimer-increment n)) | 542 (itimer-increment n)) |
485 (cond ((eq n 1) (error "Cannot change itimer name.")) | 543 (cond ((eq n 1) (error "Cannot change itimer name.")) |
486 ((eq n 2) 'value) | 544 ((eq n 2) 'value) |
487 ((eq n 3) 'restart) | 545 ((eq n 3) 'restart) |
488 ((eq n 4) 'function) | 546 ((eq n 4) 'function) |
547 ((eq n 5) 'is-idle) | |
489 (t 'function-argument))))) | 548 (t 'function-argument))))) |
490 (cond ((eq field 'value) | 549 (cond ((eq field 'value) |
491 (let ((prompt "Set itimer value: ")) | 550 (let ((prompt "Set itimer value: ")) |
492 (while (not (natnump field-value)) | 551 (while (not (natnump field-value)) |
493 (setq field-value (read-from-minibuffer prompt nil nil t))))) | 552 (setq field-value (read-from-minibuffer prompt nil nil t))))) |
500 (while (not (or (and (symbolp field-value) (fboundp field-value)) | 559 (while (not (or (and (symbolp field-value) (fboundp field-value)) |
501 (and (consp field-value) | 560 (and (consp field-value) |
502 (memq (car field-value) '(lambda macro))))) | 561 (memq (car field-value) '(lambda macro))))) |
503 (setq field-value | 562 (setq field-value |
504 (read (completing-read prompt obarray 'fboundp nil)))))) | 563 (read (completing-read prompt obarray 'fboundp nil)))))) |
564 ((eq field 'is-idle) | |
565 (setq field-value (not (itimer-is-idle itimer)))) | |
505 ((eq field 'function-argument) | 566 ((eq field 'function-argument) |
506 (let ((prompt "Set itimer function argument: ")) | 567 (let ((prompt "Set itimer function argument: ")) |
507 (setq field-value (read-expression prompt)) | 568 (setq field-value (read-expression prompt)) |
508 (set-itimer-uses-argument itimer t)))) | 569 (cond ((not (listp field-value)) |
570 (setq field-value (list field-value)))) | |
571 (if (null field-value) | |
572 (set-itimer-uses-arguments itimer nil) | |
573 (set-itimer-uses-arguments itimer t))))) | |
509 ;; set the itimer field | 574 ;; set the itimer field |
510 (funcall (intern (concat "set-itimer-" (symbol-name field))) | 575 (funcall (intern (concat "set-itimer-" (symbol-name field))) |
511 itimer field-value) | 576 itimer field-value) |
512 ;; move to beginning of field to be changed | 577 ;; move to beginning of field to be changed |
513 (itimer-edit-beginning-of-field) | 578 (itimer-edit-beginning-of-field) |
584 | 649 |
585 (defun itimer-run-expired-timers (time-elapsed) | 650 (defun itimer-run-expired-timers (time-elapsed) |
586 (let ((itimers (copy-sequence itimer-list)) | 651 (let ((itimers (copy-sequence itimer-list)) |
587 (itimer) | 652 (itimer) |
588 (next-wakeup 600) | 653 (next-wakeup 600) |
654 (idle-time) | |
655 (last-event-time) | |
656 (recorded-run-time) | |
589 ;; process filters can be hit by stray C-g's from the user, | 657 ;; process filters can be hit by stray C-g's from the user, |
590 ;; so we must protect this stuff appropriately. | 658 ;; so we must protect this stuff appropriately. |
591 ;; Quit's are allowed from within itimer functions, but we | 659 ;; Quit's are allowed from within itimer functions, but we |
592 ;; catch them and print a message. | 660 ;; catch them and print a message. |
593 (inhibit-quit t)) | 661 (inhibit-quit t)) |
594 (setq next-wakeup 600) | 662 (setq next-wakeup 600) |
663 (if (and (boundp 'last-input-time) (consp last-input-time)) | |
664 (setq last-event-time (list (car last-input-time) | |
665 (cdr last-input-time) | |
666 0) | |
667 idle-time (itimer-time-difference (current-time) | |
668 last-event-time)) | |
669 ;; no way to do this under FSF Emacs yet. | |
670 (setq last-event-time '(0 0 0) | |
671 idle-time 0)) | |
595 (while itimers | 672 (while itimers |
596 (setq itimer (car itimers)) | 673 (setq itimer (car itimers)) |
597 (set-itimer-value-internal itimer (max 0 (- (itimer-value itimer) | 674 (if (itimer-is-idle itimer) |
598 time-elapsed))) | 675 (setq recorded-run-time (itimer-recorded-run-time itimer)) |
599 (if (> (itimer-value itimer) 0) | 676 (set-itimer-value-internal itimer (max 0 (- (itimer-value itimer) |
677 time-elapsed)))) | |
678 (if (if (itimer-is-idle itimer) | |
679 (or (> (itimer-time-difference recorded-run-time | |
680 last-event-time) | |
681 0) | |
682 (< idle-time (itimer-value itimer))) | |
683 (> (itimer-value itimer) 0)) | |
600 (setq next-wakeup | 684 (setq next-wakeup |
601 (min next-wakeup (itimer-value itimer))) | 685 (if (itimer-is-idle itimer) |
686 (if (< idle-time (itimer-value itimer)) | |
687 (min next-wakeup (- (itimer-value itimer) idle-time)) | |
688 (min next-wakeup (itimer-value itimer))) | |
689 (min next-wakeup (itimer-value itimer)))) | |
690 (and (itimer-is-idle itimer) | |
691 (set-itimer-recorded-run-time itimer (current-time))) | |
602 ;; itimer has expired, we must call its function. | 692 ;; itimer has expired, we must call its function. |
603 ;; protect our local vars from the itimer function. | 693 ;; protect our local vars from the itimer function. |
604 ;; allow keyboard quit to occur, but catch and report it. | 694 ;; allow keyboard quit to occur, but catch and report it. |
605 ;; provide the variable `current-itimer' in case the function | 695 ;; provide the variable `current-itimer' in case the function |
606 ;; is interested. | 696 ;; is interested. |
608 (save-match-data | 698 (save-match-data |
609 (let* ((current-itimer itimer) | 699 (let* ((current-itimer itimer) |
610 (quit-flag nil) | 700 (quit-flag nil) |
611 (inhibit-quit nil) | 701 (inhibit-quit nil) |
612 itimer itimers time-elapsed) | 702 itimer itimers time-elapsed) |
613 (if (itimer-uses-argument current-itimer) | 703 (if (itimer-uses-arguments current-itimer) |
614 (funcall (itimer-function current-itimer) | 704 (apply (itimer-function current-itimer) |
615 (itimer-function-argument current-itimer)) | 705 (itimer-function-arguments current-itimer)) |
616 (funcall (itimer-function current-itimer))))) | 706 (funcall (itimer-function current-itimer))))) |
617 (error (message "itimer \"%s\" signaled: %s" (itimer-name itimer) | 707 (error (message "itimer \"%s\" signaled: %s" (itimer-name itimer) |
618 (prin1-to-string condition-data))) | 708 (prin1-to-string condition-data))) |
619 (quit (message "itimer \"%s\" quit" (itimer-name itimer)))) | 709 (quit (message "itimer \"%s\" quit" (itimer-name itimer)))) |
620 ;; restart the itimer if we should, otherwise delete it. | 710 ;; restart the itimer if we should, otherwise delete it. |
699 (disable-timeout itimer-timer))) | 789 (disable-timeout itimer-timer))) |
700 (setq itimer-timer (add-timeout itimer-short-interval | 790 (setq itimer-timer (add-timeout itimer-short-interval |
701 'itimer-timer-driver nil nil)))) | 791 'itimer-timer-driver nil nil)))) |
702 | 792 |
703 (defun itimer-time-difference (t1 t2) | 793 (defun itimer-time-difference (t1 t2) |
704 (let (usecs secs 65536-secs) | 794 (let (usecs secs 65536-secs carry) |
705 (setq usecs (- (nth 2 t1) (nth 2 t2))) | 795 (setq usecs (- (nth 2 t1) (nth 2 t2))) |
706 (if (< usecs 0) | 796 (if (< usecs 0) |
707 (setq carry 1 | 797 (setq carry 1 |
708 usecs (+ usecs 1000000)) | 798 usecs (+ usecs 1000000)) |
709 (setq carry 0)) | 799 (setq carry 0)) |
710 (setq secs (- (nth 1 t1) (nth 1 t2) carry)) | 800 (setq secs (- (nth 1 t1) (nth 1 t2) carry)) |
711 (if (< secs 0) | 801 (if (< secs 0) |
712 (setq carry 1 | 802 (setq carry 1 |
713 secs (+ secs 65536)) | 803 secs (+ secs 65536)) |
714 (setq carry 0)) | 804 (setq carry 0)) |
715 (setq 65536-secs (- (nth 0 t1) (nth 0 t2) carry)) | 805 (setq 65536-secs (- (nth 0 t1) (nth 0 t2) carry)) |
716 ;; loses for interval larger than the maximum signed Lisp integer. | 806 ;; loses for interval larger than the maximum signed Lisp integer. |
717 ;; can't really be helped. | 807 ;; can't really be helped. |
718 (+ (* 65536-secs 65536) | 808 (+ (* 65536-secs 65536) |
741 | 831 |
742 (defun itimer-driver-wakeup () | 832 (defun itimer-driver-wakeup () |
743 (if (fboundp 'add-timeout) | 833 (if (fboundp 'add-timeout) |
744 (itimer-timer-wakeup) | 834 (itimer-timer-wakeup) |
745 (itimer-process-wakeup))) | 835 (itimer-process-wakeup))) |
746 | |
747 ;;; itimer.el ends here |