aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2004-04-27 13:12:07 +0000
committerEli Zaretskii2004-04-27 13:12:07 +0000
commit27cd478d97379dddb0c80d56cdcc5267dc710aca (patch)
treeca885cfca0afc496e7d69b94fcd23596f713030d
parent12092fb374d3958b6e3a240a18bedbb75f9b1280 (diff)
downloademacs-27cd478d97379dddb0c80d56cdcc5267dc710aca.tar.gz
emacs-27cd478d97379dddb0c80d56cdcc5267dc710aca.zip
Capitalise Emacs and Lisp.
(type-break-good-break-interval, type-break-demo-boring-stats) (type-break-terse-messages, type-break-file-name): New defcustoms. (type-break-post-command-hook) (type-break-warning-countdown-string): Quote variable names in doc. (type-break-interval-start, type-break-auto-save-file-name): New defvars. (type-break-mode): Document type-break-good-break-interval and the "session" file. Schedule break according to the session file. Kill session file buffer on exit. Organise for save-some-buffers to always save the session file. (type-break-mode-line-message-mode, type-break-query-mode): Uppercase arguments. (type-break-file-time, type-break-file-keystroke-count, timep) (type-break-choose-file, type-break-get-previous-time) (type-break-get-previous-count): New defuns. (type-break): Avoid break querying after a completed break in the case where the query was initiated during user invocation of the break. Optional terse messages. Use type-break-good-break-interval if type-break-good-rest-interval is nil. File the break time. (type-break-schedule): New optional args for overriding the use of the current time. (type-break-cancel-time-warning-schedule): Avoid leftover warnings after a break. (type-break-check): File the keystroke count. (type-break-do-query): Prevent a second query when the break is interrupted. Optional terse message. (type-break-keystroke-reset): Record the start of a typing interval. (type-break-demo-boring): Optional terse messages. Display word per minute and keystroke counts according to type-break-demo-boring-stats.
-rw-r--r--lisp/ChangeLog35
-rw-r--r--lisp/type-break.el372
2 files changed, 332 insertions, 75 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 5c01151c270..4b330727581 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -4,6 +4,41 @@
4 either a character representation of an event or an event 4 either a character representation of an event or an event
5 description list. 5 description list.
6 6
7 * type-break.el: Capitalise Emacs and Lisp.
8 (type-break-good-break-interval, type-break-demo-boring-stats)
9 (type-break-terse-messages, type-break-file-name): New defcustoms.
10 (type-break-post-command-hook)
11 (type-break-warning-countdown-string): Quote variable names in
12 doc.
13 (type-break-interval-start, type-break-auto-save-file-name): New
14 defvars.
15 (type-break-mode): Document type-break-good-break-interval and the
16 "session" file. Schedule break according to the session file.
17 Kill session file buffer on exit. Organise for save-some-buffers
18 to always save the session file.
19 (type-break-mode-line-message-mode, type-break-query-mode):
20 Uppercase arguments.
21 (type-break-file-time, type-break-file-keystroke-count, timep)
22 (type-break-choose-file, type-break-get-previous-time)
23 (type-break-get-previous-count): New defuns.
24 (type-break): Avoid break querying after a completed break in the
25 case where the query was initiated during user invocation of the
26 break. Optional terse messages. Use
27 type-break-good-break-interval if type-break-good-rest-interval is
28 nil. File the break time.
29 (type-break-schedule): New optional args for overriding the use of
30 the current time.
31 (type-break-cancel-time-warning-schedule): Avoid leftover warnings
32 after a break.
33 (type-break-check): File the keystroke count.
34 (type-break-do-query): Prevent a second query when the break is
35 interrupted. Optional terse message.
36 (type-break-keystroke-reset): Record the start of a typing
37 interval.
38 (type-break-demo-boring): Optional terse messages. Display word
39 per minute and keystroke counts according to
40 type-break-demo-boring-stats.
41
72004-04-27 Daniel M Coffman <coffmand@us.ibm.com> (tiny change) 422004-04-27 Daniel M Coffman <coffmand@us.ibm.com> (tiny change)
8 43
9 * arc-mode.el (archive-maybe-copy): If ARCHIVE includes leading 44 * arc-mode.el (archive-maybe-copy): If ARCHIVE includes leading
diff --git a/lisp/type-break.el b/lisp/type-break.el
index 26ac7f87ecb..253e1406f06 100644
--- a/lisp/type-break.el
+++ b/lisp/type-break.el
@@ -30,10 +30,10 @@
30;; The docstring for the function `type-break-mode' summarizes most of the 30;; The docstring for the function `type-break-mode' summarizes most of the
31;; details of the interface. 31;; details of the interface.
32 32
33;; This package relies on the assumption that you live entirely in emacs, 33;; This package relies on the assumption that you live entirely in Emacs,
34;; as the author does. If that's not the case for you (e.g. you often 34;; as the author does. If that's not the case for you (e.g. you often
35;; suspend emacs or work in other windows) then this won't help very much; 35;; suspend Emacs or work in other windows) then this won't help very much;
36;; it will depend on just how often you switch back to emacs. At the very 36;; it will depend on just how often you switch back to Emacs. At the very
37;; least, you will want to turn off the keystroke thresholds and rest 37;; least, you will want to turn off the keystroke thresholds and rest
38;; interval tracking. 38;; interval tracking.
39 39
@@ -95,7 +95,7 @@ use either \\[customize] or the function `type-break-mode'."
95(defcustom type-break-good-rest-interval (/ type-break-interval 6) 95(defcustom type-break-good-rest-interval (/ type-break-interval 6)
96 "*Number of seconds of idle time considered to be an adequate typing rest. 96 "*Number of seconds of idle time considered to be an adequate typing rest.
97 97
98When this variable is non-nil, emacs checks the idle time between 98When this variable is non-nil, Emacs checks the idle time between
99keystrokes. If this idle time is long enough to be considered a \"good\" 99keystrokes. If this idle time is long enough to be considered a \"good\"
100rest from typing, then the next typing break is simply rescheduled for later. 100rest from typing, then the next typing break is simply rescheduled for later.
101 101
@@ -105,6 +105,17 @@ asked whether or not really to interrupt the break."
105 :group 'type-break) 105 :group 'type-break)
106 106
107;;;###autoload 107;;;###autoload
108(defcustom type-break-good-break-interval nil
109 "*Number of seconds considered to be an adequate explicit typing rest.
110
111When this variable is non-nil, its value is considered to be a \"good\"
112length (in seconds) for a break initiated by the command `type-break',
113overriding `type-break-good-rest-interval'. This provides querying of
114break interruptions when `type-break-good-rest-interval' is nil."
115 :type 'integer
116 :group 'type-break)
117
118;;;###autoload
108(defcustom type-break-keystroke-threshold 119(defcustom type-break-keystroke-threshold
109 ;; Assuming typing speed is 35wpm (on the average, do you really 120 ;; Assuming typing speed is 35wpm (on the average, do you really
110 ;; type more than that in a minute? I spend a lot of time reading mail 121 ;; type more than that in a minute? I spend a lot of time reading mail
@@ -200,15 +211,30 @@ Format specifiers are as used by `format-time-string'."
200 '(type-break-demo-boring type-break-demo-life type-break-demo-hanoi) 211 '(type-break-demo-boring type-break-demo-life type-break-demo-hanoi)
201 "*List of functions to consider running as demos during typing breaks. 212 "*List of functions to consider running as demos during typing breaks.
202When a typing break begins, one of these functions is selected randomly 213When a typing break begins, one of these functions is selected randomly
203to have emacs do something interesting. 214to have Emacs do something interesting.
204 215
205Any function in this list should start a demo which ceases as soon as a 216Any function in this list should start a demo which ceases as soon as a
206key is pressed." 217key is pressed."
207 :type '(repeat function) 218 :type '(repeat function)
208 :group 'type-break) 219 :group 'type-break)
209 220
221(defcustom type-break-demo-boring-stats nil
222 "*Show word per minute and keystroke figures in the Boring demo."
223 :type 'boolean
224 :group 'type-break)
225
226(defcustom type-break-terse-messages nil
227 "*Use slightly terser messages."
228 :type 'boolean
229 :group 'type-break)
230
231(defcustom type-break-file-name (convert-standard-filename "~/.type-break")
232 "*Name of file used to save state across sessions."
233 :type 'file
234 :group 'type-break)
235
210(defvar type-break-post-command-hook '(type-break-check) 236(defvar type-break-post-command-hook '(type-break-check)
211 "Hook run indirectly by post-command-hook for typing break functions. 237 "Hook run indirectly by `post-command-hook' for typing break functions.
212This is not really intended to be set by the user, but it's probably 238This is not really intended to be set by the user, but it's probably
213harmless to do so. Mainly it is used by various parts of the typing break 239harmless to do so. Mainly it is used by various parts of the typing break
214program to delay actions until after the user has completed some command. 240program to delay actions until after the user has completed some command.
@@ -257,7 +283,7 @@ See also `type-break-mode-line-format' and its members."
257 283
258This variable, in conjunction with `type-break-warning-countdown-string-type' 284This variable, in conjunction with `type-break-warning-countdown-string-type'
259\(which indicates whether this value is a number of keystrokes or seconds) 285\(which indicates whether this value is a number of keystrokes or seconds)
260is installed in mode-line-format to notify of imminent typing breaks.") 286is installed in `mode-line-format' to notify of imminent typing breaks.")
261 287
262(defvar type-break-warning-countdown-string-type nil 288(defvar type-break-warning-countdown-string-type nil
263 "Indicates the unit type of `type-break-warning-countdown-string'. 289 "Indicates the unit type of `type-break-warning-countdown-string'.
@@ -275,6 +301,8 @@ It will be either \"seconds\" or \"keystrokes\".")
275(defvar type-break-current-keystroke-warning-interval nil) 301(defvar type-break-current-keystroke-warning-interval nil)
276(defvar type-break-time-warning-count 0) 302(defvar type-break-time-warning-count 0)
277(defvar type-break-keystroke-warning-count 0) 303(defvar type-break-keystroke-warning-count 0)
304(defvar type-break-interval-start nil)
305
278 306
279;;;###autoload 307;;;###autoload
280(defun type-break-mode (&optional prefix) 308(defun type-break-mode (&optional prefix)
@@ -284,7 +312,7 @@ This is a minor mode, but it is global to all buffers by default.
284When this mode is enabled, the user is encouraged to take typing breaks at 312When this mode is enabled, the user is encouraged to take typing breaks at
285appropriate intervals; either after a specified amount of time or when the 313appropriate intervals; either after a specified amount of time or when the
286user has exceeded a keystroke threshold. When the time arrives, the user 314user has exceeded a keystroke threshold. When the time arrives, the user
287is asked to take a break. If the user refuses at that time, emacs will ask 315is asked to take a break. If the user refuses at that time, Emacs will ask
288again in a short period of time. The idea is to give the user enough time 316again in a short period of time. The idea is to give the user enough time
289to find a good breaking point in his or her work, but be sufficiently 317to find a good breaking point in his or her work, but be sufficiently
290annoying to discourage putting typing breaks off indefinitely. 318annoying to discourage putting typing breaks off indefinitely.
@@ -309,9 +337,18 @@ affect the time schedule; it simply provides a default for the
309If set, the variable `type-break-good-rest-interval' specifies the minimum 337If set, the variable `type-break-good-rest-interval' specifies the minimum
310amount of time which is considered a reasonable typing break. Whenever 338amount of time which is considered a reasonable typing break. Whenever
311that time has elapsed, typing breaks are automatically rescheduled for 339that time has elapsed, typing breaks are automatically rescheduled for
312later even if emacs didn't prompt you to take one first. Also, if a break 340later even if Emacs didn't prompt you to take one first. Also, if a break
313is ended before this much time has elapsed, the user will be asked whether 341is ended before this much time has elapsed, the user will be asked whether
314or not to continue. 342or not to continue. A nil value for this variable prevents automatic
343break rescheduling, making `type-break-interval' an upper bound on the time
344between breaks. In this case breaks will be prompted for as usual before
345the upper bound if the keystroke threshold is reached.
346
347If `type-break-good-rest-interval' is nil and
348`type-break-good-break-interval' is set, then confirmation is required to
349interrupt a break before `type-break-good-break-interval' seconds
350have passed. This provides for an upper bound on the time between breaks
351together with confirmation of interruptions to these breaks.
315 352
316The variable `type-break-keystroke-threshold' is used to determine the 353The variable `type-break-keystroke-threshold' is used to determine the
317thresholds at which typing breaks should be considered. You can use 354thresholds at which typing breaks should be considered. You can use
@@ -335,7 +372,12 @@ a typing break occur. They include:
335 `type-break-query-function' 372 `type-break-query-function'
336 `type-break-query-interval' 373 `type-break-query-interval'
337 374
338Finally, the command `type-break-statistics' prints interesting things." 375The command `type-break-statistics' prints interesting things.
376
377Finally, a file (named `type-break-file-name') is used to store information
378across Emacs sessions. This provides recovery of the break status between
379sessions and after a crash. Manual changes to the file may result in
380problems."
339 (interactive "P") 381 (interactive "P")
340 (type-break-check-post-command-hook) 382 (type-break-check-post-command-hook)
341 383
@@ -356,13 +398,52 @@ Finally, the command `type-break-statistics' prints interesting things."
356 minor-mode-alist))) 398 minor-mode-alist)))
357 (type-break-keystroke-reset) 399 (type-break-keystroke-reset)
358 (type-break-mode-line-countdown-or-break nil) 400 (type-break-mode-line-countdown-or-break nil)
359 (type-break-schedule) 401
402 (if (boundp 'save-some-buffers-always)
403 (add-to-list 'save-some-buffers-always
404 (expand-file-name type-break-file-name)))
405
406 (setq type-break-time-last-break (type-break-get-previous-time))
407
408 ;; schedule according to break time from session file
409 (type-break-schedule
410 (let (diff)
411 (if (and type-break-time-last-break
412 (< (setq diff (type-break-time-difference
413 type-break-time-last-break
414 (current-time)))
415 type-break-interval))
416 ;; use the file's value
417 (progn
418 (setq type-break-keystroke-count
419 (type-break-get-previous-count))
420 ;; file the time, in case it was read from the auto-save file
421 (type-break-file-time type-break-interval-start)
422 (setq type-break-interval-start type-break-time-last-break)
423 (- type-break-interval diff))
424 ;; schedule from now
425 (setq type-break-interval-start (current-time))
426 (type-break-file-time type-break-interval-start)
427 type-break-interval))
428 type-break-interval-start
429 type-break-interval)
430
360 (and (interactive-p) 431 (and (interactive-p)
361 (message "Type Break mode is enabled and reset"))) 432 (message "Type Break mode is enabled and set")))
362 (t 433 (t
363 (type-break-keystroke-reset) 434 (type-break-keystroke-reset)
364 (type-break-mode-line-countdown-or-break nil) 435 (type-break-mode-line-countdown-or-break nil)
365 (type-break-cancel-schedule) 436 (type-break-cancel-schedule)
437 (do-auto-save)
438 (with-current-buffer (find-file-noselect type-break-file-name
439 'nowarn)
440 (set-buffer-modified-p nil)
441 (unlock-buffer)
442 (kill-this-buffer))
443 (if (boundp 'save-some-buffers-always)
444 (setq save-some-buffers-always
445 (remove (expand-file-name type-break-file-name)
446 save-some-buffers-always)))
366 (and (interactive-p) 447 (and (interactive-p)
367 (message "Type Break mode is disabled"))))) 448 (message "Type Break mode is disabled")))))
368 type-break-mode) 449 type-break-mode)
@@ -370,7 +451,7 @@ Finally, the command `type-break-statistics' prints interesting things."
370(defun type-break-mode-line-message-mode (&optional prefix) 451(defun type-break-mode-line-message-mode (&optional prefix)
371 "Enable or disable warnings in the mode line about typing breaks. 452 "Enable or disable warnings in the mode line about typing breaks.
372 453
373A negative prefix argument disables this mode. 454A negative PREFIX argument disables this mode.
374No argument or any non-negative argument enables it. 455No argument or any non-negative argument enables it.
375 456
376The user may also enable or disable this mode simply by setting the 457The user may also enable or disable this mode simply by setting the
@@ -398,7 +479,7 @@ When enabled, the user is periodically queried about whether to take a
398typing break at that moment. The function which does this query is 479typing break at that moment. The function which does this query is
399specified by the variable `type-break-query-function'. 480specified by the variable `type-break-query-function'.
400 481
401A negative prefix argument disables this mode. 482A negative PREFIX argument disables this mode.
402No argument or any non-negative argument enables it. 483No argument or any non-negative argument enables it.
403 484
404The user may also enable or disable this mode simply by setting the 485The user may also enable or disable this mode simply by setting the
@@ -413,6 +494,89 @@ variable of the same name."
413 type-break-query-mode) 494 type-break-query-mode)
414 495
415 496
497;;; session file functions
498
499(defvar type-break-auto-save-file-name
500 (let ((buffer-file-name type-break-file-name))
501 (make-auto-save-file-name))
502 "Auto-save name of `type-break-file-name'.")
503
504(defun type-break-file-time (&optional time)
505 "File break time in `type-break-file-name', unless the file is locked."
506 (if (not (stringp (file-locked-p type-break-file-name)))
507 (with-current-buffer (find-file-noselect type-break-file-name
508 'nowarn)
509 (let ((inhibit-read-only t))
510 (erase-buffer)
511 (insert (format "%s\n\n" (or time type-break-interval-start)))
512 ;; file saving is left to auto-save
513 ))))
514
515(defun type-break-file-keystroke-count ()
516 "File keystroke count in `type-break-file-name', unless the file is locked."
517 (if (not (stringp (file-locked-p type-break-file-name)))
518 (with-current-buffer (find-file-noselect type-break-file-name
519 'nowarn)
520 (save-excursion
521 (let ((inhibit-read-only t))
522 (goto-char (point-min))
523 (forward-line)
524 (delete-region (point) (save-excursion (end-of-line) (point)))
525 (insert (format "%s" type-break-keystroke-count))
526 ;; file saving is left to auto-save
527 )))))
528
529(defun timep (time)
530 "If TIME is in the format returned by `current-time' then
531return TIME, else return nil."
532 (and (listp time)
533 (eq (length time) 3)
534 (integerp (car time))
535 (integerp (nth 1 time))
536 (integerp (nth 2 time))
537 time))
538
539(defun type-break-choose-file ()
540 "Return file to read from."
541 (cond
542 ((and (file-exists-p type-break-auto-save-file-name)
543 (file-readable-p type-break-auto-save-file-name))
544 type-break-auto-save-file-name)
545 ((and (file-exists-p type-break-file-name)
546 (file-readable-p type-break-file-name))
547 type-break-file-name)
548 (t nil)))
549
550(defun type-break-get-previous-time ()
551 "Get previous break time from `type-break-file-name'.
552Returns nil if the file is missing or if the time breaks with the
553`current-time' format."
554 (let ((file (type-break-choose-file)))
555 (if file
556 (timep ;; returns expected format, else nil
557 (with-current-buffer (find-file-noselect file 'nowarn)
558 (save-excursion
559 (goto-char (point-min))
560 (read (current-buffer))))))))
561
562(defun type-break-get-previous-count ()
563 "Get previous keystroke count from `type-break-file-name'.
564Return 0 if the file is missing or if the form read is not an
565integer."
566 (let ((file (type-break-choose-file)))
567 (if (and file
568 (integerp
569 (setq file
570 (with-current-buffer
571 (find-file-noselect file 'nowarn)
572 (save-excursion
573 (goto-char (point-min))
574 (forward-line 1)
575 (read (current-buffer)))))))
576 file
577 0)))
578
579
416;;;###autoload 580;;;###autoload
417(defun type-break () 581(defun type-break ()
418 "Take a typing break. 582 "Take a typing break.
@@ -425,6 +589,8 @@ as per the function `type-break-schedule'."
425 (interactive) 589 (interactive)
426 (do-auto-save) 590 (do-auto-save)
427 (type-break-cancel-schedule) 591 (type-break-cancel-schedule)
592 ;; remove any query scheduled during interactive invocation
593 (remove-hook 'type-break-post-command-hook 'type-break-do-query)
428 (let ((continue t) 594 (let ((continue t)
429 (start-time (current-time))) 595 (start-time (current-time)))
430 (setq type-break-time-last-break start-time) 596 (setq type-break-time-last-break start-time)
@@ -435,7 +601,8 @@ as per the function `type-break-schedule'."
435 (other-window 1)) 601 (other-window 1))
436 (delete-other-windows) 602 (delete-other-windows)
437 (scroll-right (window-width)) 603 (scroll-right (window-width))
438 (message "Press any key to resume from typing break.") 604 (unless type-break-terse-messages
605 (message "Press any key to resume from typing break."))
439 606
440 (random t) 607 (random t)
441 (let* ((len (length type-break-demo-functions)) 608 (let* ((len (length type-break-demo-functions))
@@ -445,36 +612,45 @@ as per the function `type-break-schedule'."
445 (funcall fn) 612 (funcall fn)
446 (error nil)))) 613 (error nil))))
447 614
448 (cond 615 (let ((good-interval (or type-break-good-rest-interval
449 (type-break-good-rest-interval 616 type-break-good-break-interval)))
450 (let ((break-secs (type-break-time-difference 617 (cond
451 start-time (current-time)))) 618 (good-interval
452 (cond 619 (let ((break-secs (type-break-time-difference
453 ((>= break-secs type-break-good-rest-interval) 620 start-time (current-time))))
454 (setq continue nil)) 621 (cond
455 ;; 60 seconds may be too much leeway if the break is only 3 622 ((>= break-secs good-interval)
456 ;; minutes to begin with. You can just say "no" to the query 623 (setq continue nil))
457 ;; below if you're in that much of a hurry. 624 ;; 60 seconds may be too much leeway if the break is only 3
458 ;((> 60 (abs (- break-secs type-break-good-rest-interval))) 625 ;; minutes to begin with. You can just say "no" to the query
459 ; (setq continue nil)) 626 ;; below if you're in that much of a hurry.
460 ((funcall 627 ;;((> 60 (abs (- break-secs good-interval)))
461 type-break-query-function 628 ;; (setq continue nil))
462 (format "%sYou really ought to rest %s more. Continue break? " 629 ((funcall
463 (type-break-time-stamp) 630 type-break-query-function
464 (type-break-format-time (- type-break-good-rest-interval 631 (format
465 break-secs))))) 632 (if type-break-terse-messages
466 (t 633 "%s%s remaining. Continue break? "
467 (setq continue nil))))) 634 "%sYou really ought to rest %s more. Continue break? ")
468 (t (setq continue nil))))) 635 (type-break-time-stamp)
636 (type-break-format-time (- good-interval
637 break-secs)))))
638 (t
639 (setq continue nil)))))
640 (t (setq continue nil))))))
469 641
470 (type-break-keystroke-reset) 642 (type-break-keystroke-reset)
643 (type-break-file-time)
471 (type-break-mode-line-countdown-or-break nil) 644 (type-break-mode-line-countdown-or-break nil)
472 (type-break-schedule)) 645 (type-break-schedule))
473 646
474 647
475(defun type-break-schedule (&optional time) 648(defun type-break-schedule (&optional time start interval)
476 "Schedule a typing break for TIME seconds from now. 649 "Schedule a typing break for TIME seconds from now.
477If time is not specified, default to `type-break-interval'." 650If time is not specified it defaults to `type-break-interval'.
651START and INTERVAL are used when recovering a break.
652START is the start of the break (defaults to now).
653INTERVAL is the full length of an interval (defaults to TIME)."
478 (interactive (list (and current-prefix-arg 654 (interactive (list (and current-prefix-arg
479 (prefix-numeric-value current-prefix-arg)))) 655 (prefix-numeric-value current-prefix-arg))))
480 (or time (setq time type-break-interval)) 656 (or time (setq time type-break-interval))
@@ -483,7 +659,8 @@ If time is not specified, default to `type-break-interval'."
483 (type-break-time-warning-schedule time 'reset) 659 (type-break-time-warning-schedule time 'reset)
484 (type-break-run-at-time (max 1 time) nil 'type-break-alarm) 660 (type-break-run-at-time (max 1 time) nil 'type-break-alarm)
485 (setq type-break-time-next-break 661 (setq type-break-time-next-break
486 (type-break-time-sum (current-time) time))) 662 (type-break-time-sum (or start (current-time))
663 (or interval time))))
487 664
488(defun type-break-cancel-schedule () 665(defun type-break-cancel-schedule ()
489 (type-break-cancel-time-warning-schedule) 666 (type-break-cancel-time-warning-schedule)
@@ -532,6 +709,7 @@ If time is not specified, default to `type-break-interval'."
532 (remove-hook 'type-break-post-command-hook 'type-break-time-warning) 709 (remove-hook 'type-break-post-command-hook 'type-break-time-warning)
533 (setq type-break-current-time-warning-interval 710 (setq type-break-current-time-warning-interval
534 type-break-time-warning-intervals) 711 type-break-time-warning-intervals)
712 (setq type-break-time-warning-count 0) ; avoid warnings after break
535 (setq type-break-warning-countdown-string nil)) 713 (setq type-break-warning-countdown-string nil))
536 714
537(defun type-break-alarm () 715(defun type-break-alarm ()
@@ -556,6 +734,7 @@ If time is not specified, default to `type-break-interval'."
556This may be the case either because the scheduled time has come \(and the 734This may be the case either because the scheduled time has come \(and the
557minimum keystroke threshold has been reached\) or because the maximum 735minimum keystroke threshold has been reached\) or because the maximum
558keystroke threshold has been exceeded." 736keystroke threshold has been exceeded."
737 (type-break-file-keystroke-count)
559 (let* ((min-threshold (car type-break-keystroke-threshold)) 738 (let* ((min-threshold (car type-break-keystroke-threshold))
560 (max-threshold (cdr type-break-keystroke-threshold))) 739 (max-threshold (cdr type-break-keystroke-threshold)))
561 (and type-break-good-rest-interval 740 (and type-break-good-rest-interval
@@ -657,16 +836,19 @@ keystroke threshold has been exceeded."
657 ;; from taking place before this one has even returned. 836 ;; from taking place before this one has even returned.
658 ;; The condition-case wrapper will reschedule on quit. 837 ;; The condition-case wrapper will reschedule on quit.
659 (type-break-cancel-schedule) 838 (type-break-cancel-schedule)
839 ;; Also prevent a second query when the break is interrupted.
840 (remove-hook 'type-break-post-command-hook 'type-break-do-query)
660 (funcall type-break-query-function 841 (funcall type-break-query-function
661 (format "%s%s" 842 (format "%s%s"
662 (type-break-time-stamp) 843 (type-break-time-stamp)
663 "Take a break from typing now? "))) 844 (if type-break-terse-messages
845 "Break now? "
846 "Take a break from typing now? "))))
664 (type-break)) 847 (type-break))
665 (t 848 (t
666 (type-break-schedule type-break-query-interval))) 849 (type-break-schedule type-break-query-interval)))
667 (quit 850 (quit
668 (type-break-schedule type-break-query-interval))) 851 (type-break-schedule type-break-query-interval))))))
669 (remove-hook 'type-break-post-command-hook 'type-break-do-query))))
670 852
671(defun type-break-noninteractive-query (&optional ignored-args) 853(defun type-break-noninteractive-query (&optional ignored-args)
672 "Null query function which doesn't interrupt user and assumes `no'. 854 "Null query function which doesn't interrupt user and assumes `no'.
@@ -810,7 +992,7 @@ based on a fairly simple algorithm involving assumptions about the average
810length of words (5). For the minimum threshold, it uses about a fifth of 992length of words (5). For the minimum threshold, it uses about a fifth of
811the computed maximum threshold. 993the computed maximum threshold.
812 994
813When called from lisp programs, the optional args WORDLEN and FRAC can be 995When called from Lisp programs, the optional args WORDLEN and FRAC can be
814used to override the default assumption about average word length and the 996used to override the default assumption about average word length and the
815fraction of the maximum threshold to which to set the minimum threshold. 997fraction of the maximum threshold to which to set the minimum threshold.
816FRAC should be the inverse of the fractional value; for example, a value of 998FRAC should be the inverse of the fractional value; for example, a value of
@@ -891,6 +1073,7 @@ FRAC should be the inverse of the fractional value; for example, a value of
891 (t (format "%d seconds" secs))))) 1073 (t (format "%d seconds" secs)))))
892 1074
893(defun type-break-keystroke-reset () 1075(defun type-break-keystroke-reset ()
1076 (setq type-break-interval-start (current-time)) ; not a keystroke
894 (setq type-break-keystroke-count 0) 1077 (setq type-break-keystroke-count 0)
895 (setq type-break-keystroke-warning-count 0) 1078 (setq type-break-keystroke-warning-count 0)
896 (setq type-break-current-keystroke-warning-interval 1079 (setq type-break-current-keystroke-warning-interval
@@ -903,7 +1086,7 @@ With optional non-nil ALL, force redisplay of all mode-lines."
903 (and all (save-excursion (set-buffer (other-buffer)))) 1086 (and all (save-excursion (set-buffer (other-buffer))))
904 (set-buffer-modified-p (buffer-modified-p))) 1087 (set-buffer-modified-p (buffer-modified-p)))
905 1088
906;; If an exception occurs in emacs while running the post command hook, the 1089;; If an exception occurs in Emacs while running the post command hook, the
907;; value of that hook is clobbered. This is because the value of the 1090;; value of that hook is clobbered. This is because the value of the
908;; variable is temporarily set to nil while it's running to prevent 1091;; variable is temporarily set to nil while it's running to prevent
909;; recursive application, but it also means an exception aborts the routine 1092;; recursive application, but it also means an exception aborts the routine
@@ -916,7 +1099,7 @@ With optional non-nil ALL, force redisplay of all mode-lines."
916;;; Timer wrapper functions 1099;;; Timer wrapper functions
917;;; 1100;;;
918;;; These shield type-break from variations in the interval timer packages 1101;;; These shield type-break from variations in the interval timer packages
919;;; for different versions of emacs. 1102;;; for different versions of Emacs.
920 1103
921(defun type-break-run-at-time (time repeat function) 1104(defun type-break-run-at-time (time repeat function)
922 (condition-case nil (or (require 'timer) (require 'itimer)) (error nil)) 1105 (condition-case nil (or (require 'timer) (require 'itimer)) (error nil))
@@ -1002,44 +1185,83 @@ With optional non-nil ALL, force redisplay of all mode-lines."
1002;; Boring demo, but doesn't use many cycles 1185;; Boring demo, but doesn't use many cycles
1003(defun type-break-demo-boring () 1186(defun type-break-demo-boring ()
1004 "Boring typing break demo." 1187 "Boring typing break demo."
1005 (let ((rmsg "Press any key to resume from typing break") 1188 (let ((rmsg (if type-break-terse-messages
1189 ""
1190 "Press any key to resume from typing break"))
1006 (buffer-name "*Typing Break Buffer*") 1191 (buffer-name "*Typing Break Buffer*")
1007 line col pos 1192 lines elapsed timeleft tmsg)
1008 elapsed timeleft tmsg)
1009 (condition-case () 1193 (condition-case ()
1010 (progn 1194 (progn
1011 (switch-to-buffer (get-buffer-create buffer-name)) 1195 (switch-to-buffer (get-buffer-create buffer-name))
1012 (buffer-disable-undo (current-buffer)) 1196 (buffer-disable-undo (current-buffer))
1013 (erase-buffer) 1197 (setq lines (/ (window-body-height) 2))
1014 (setq line (1+ (/ (window-height) 2))) 1198 (unless type-break-terse-messages (setq lines (1- lines)))
1015 (setq col (/ (- (window-width) (length rmsg)) 2)) 1199 (if type-break-demo-boring-stats
1016 (insert (make-string line ?\C-j) 1200 (setq lines (- lines 2)))
1017 (make-string col ?\ ) 1201 (setq lines (make-string lines ?\C-j))
1018 rmsg)
1019 (forward-line -1)
1020 (beginning-of-line)
1021 (setq pos (point))
1022 (while (not (input-pending-p)) 1202 (while (not (input-pending-p))
1023 (delete-region pos (progn 1203 (erase-buffer)
1024 (goto-char pos)
1025 (end-of-line)
1026 (point)))
1027 (setq elapsed (type-break-time-difference 1204 (setq elapsed (type-break-time-difference
1028 type-break-time-last-break 1205 type-break-time-last-break
1029 (current-time))) 1206 (current-time)))
1030 (cond 1207 (let ((good-interval (or type-break-good-rest-interval
1031 (type-break-good-rest-interval 1208 type-break-good-break-interval)))
1032 (setq timeleft (- type-break-good-rest-interval elapsed)) 1209 (cond
1033 (if (> timeleft 0) 1210 (good-interval
1034 (setq tmsg (format "You should rest for %s more" 1211 (setq timeleft (- good-interval elapsed))
1035 (type-break-format-time timeleft))) 1212 (if (> timeleft 0)
1036 (setq tmsg (format "Typing break has lasted %s" 1213 (setq tmsg
1037 (type-break-format-time elapsed))))) 1214 (format (if type-break-terse-messages
1038 (t 1215 "Break remaining: %s"
1039 (setq tmsg (format "Typing break has lasted %s" 1216 "You should rest for %s more")
1040 (type-break-format-time elapsed))))) 1217 (type-break-format-time timeleft)))
1041 (setq col (/ (- (window-width) (length tmsg)) 2)) 1218 (setq tmsg
1042 (insert (make-string col ?\ ) tmsg) 1219 (format (if type-break-terse-messages
1220 "Break complete (%s elapsed in total)"
1221 "Typing break has lasted %s")
1222 (type-break-format-time elapsed)))))
1223 (t
1224 (setq tmsg
1225 (format (if type-break-terse-messages
1226 "Break has lasted %s"
1227 "Typing break has lasted %s")
1228 (type-break-format-time elapsed))))))
1229 (insert lines
1230 (make-string (/ (- (window-width) (length tmsg)) 2) ?\ )
1231 tmsg)
1232 (if (> (length rmsg) 0)
1233 (insert "\n"
1234 (make-string (/ (- (window-width) (length rmsg)) 2)
1235 ?\ )
1236 rmsg))
1237 (if type-break-demo-boring-stats
1238 (let*
1239 ((message
1240 (format
1241 (if type-break-terse-messages
1242 "Since last break: %s keystrokes\n"
1243 "Since your last break you've typed %s keystrokes\n")
1244 type-break-keystroke-count))
1245 (column-spaces
1246 (make-string (/ (- (window-width) (length message)) 2)
1247 ?\ ))
1248 (wpm (/ (/ (float type-break-keystroke-count) 5)
1249 (/ (type-break-time-difference
1250 type-break-interval-start
1251 type-break-time-last-break)
1252 60.0))))
1253 (insert "\n\n" column-spaces message)
1254 (if type-break-terse-messages
1255 (insert (format " %s%.2f wpm"
1256 column-spaces
1257 wpm))
1258 (setq message
1259 (format "at an average of %.2f words per minute"
1260 wpm))
1261 (insert
1262 (make-string (/ (- (window-width) (length message)) 2)
1263 ?\ )
1264 message))))
1043 (goto-char (point-min)) 1265 (goto-char (point-min))
1044 (sit-for 60)) 1266 (sit-for 60))
1045 (read-char) 1267 (read-char)