diff options
| -rw-r--r-- | lisp/ChangeLog | 35 | ||||
| -rw-r--r-- | lisp/type-break.el | 372 |
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 | |||
| 7 | 2004-04-27 Daniel M Coffman <coffmand@us.ibm.com> (tiny change) | 42 | 2004-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 | ||
| 98 | When this variable is non-nil, emacs checks the idle time between | 98 | When this variable is non-nil, Emacs checks the idle time between |
| 99 | keystrokes. If this idle time is long enough to be considered a \"good\" | 99 | keystrokes. If this idle time is long enough to be considered a \"good\" |
| 100 | rest from typing, then the next typing break is simply rescheduled for later. | 100 | rest 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 | |||
| 111 | When this variable is non-nil, its value is considered to be a \"good\" | ||
| 112 | length (in seconds) for a break initiated by the command `type-break', | ||
| 113 | overriding `type-break-good-rest-interval'. This provides querying of | ||
| 114 | break 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. |
| 202 | When a typing break begins, one of these functions is selected randomly | 213 | When a typing break begins, one of these functions is selected randomly |
| 203 | to have emacs do something interesting. | 214 | to have Emacs do something interesting. |
| 204 | 215 | ||
| 205 | Any function in this list should start a demo which ceases as soon as a | 216 | Any function in this list should start a demo which ceases as soon as a |
| 206 | key is pressed." | 217 | key 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. |
| 212 | This is not really intended to be set by the user, but it's probably | 238 | This is not really intended to be set by the user, but it's probably |
| 213 | harmless to do so. Mainly it is used by various parts of the typing break | 239 | harmless to do so. Mainly it is used by various parts of the typing break |
| 214 | program to delay actions until after the user has completed some command. | 240 | program 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 | ||
| 258 | This variable, in conjunction with `type-break-warning-countdown-string-type' | 284 | This 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) |
| 260 | is installed in mode-line-format to notify of imminent typing breaks.") | 286 | is 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. | |||
| 284 | When this mode is enabled, the user is encouraged to take typing breaks at | 312 | When this mode is enabled, the user is encouraged to take typing breaks at |
| 285 | appropriate intervals; either after a specified amount of time or when the | 313 | appropriate intervals; either after a specified amount of time or when the |
| 286 | user has exceeded a keystroke threshold. When the time arrives, the user | 314 | user has exceeded a keystroke threshold. When the time arrives, the user |
| 287 | is asked to take a break. If the user refuses at that time, emacs will ask | 315 | is asked to take a break. If the user refuses at that time, Emacs will ask |
| 288 | again in a short period of time. The idea is to give the user enough time | 316 | again in a short period of time. The idea is to give the user enough time |
| 289 | to find a good breaking point in his or her work, but be sufficiently | 317 | to find a good breaking point in his or her work, but be sufficiently |
| 290 | annoying to discourage putting typing breaks off indefinitely. | 318 | annoying to discourage putting typing breaks off indefinitely. |
| @@ -309,9 +337,18 @@ affect the time schedule; it simply provides a default for the | |||
| 309 | If set, the variable `type-break-good-rest-interval' specifies the minimum | 337 | If set, the variable `type-break-good-rest-interval' specifies the minimum |
| 310 | amount of time which is considered a reasonable typing break. Whenever | 338 | amount of time which is considered a reasonable typing break. Whenever |
| 311 | that time has elapsed, typing breaks are automatically rescheduled for | 339 | that time has elapsed, typing breaks are automatically rescheduled for |
| 312 | later even if emacs didn't prompt you to take one first. Also, if a break | 340 | later even if Emacs didn't prompt you to take one first. Also, if a break |
| 313 | is ended before this much time has elapsed, the user will be asked whether | 341 | is ended before this much time has elapsed, the user will be asked whether |
| 314 | or not to continue. | 342 | or not to continue. A nil value for this variable prevents automatic |
| 343 | break rescheduling, making `type-break-interval' an upper bound on the time | ||
| 344 | between breaks. In this case breaks will be prompted for as usual before | ||
| 345 | the upper bound if the keystroke threshold is reached. | ||
| 346 | |||
| 347 | If `type-break-good-rest-interval' is nil and | ||
| 348 | `type-break-good-break-interval' is set, then confirmation is required to | ||
| 349 | interrupt a break before `type-break-good-break-interval' seconds | ||
| 350 | have passed. This provides for an upper bound on the time between breaks | ||
| 351 | together with confirmation of interruptions to these breaks. | ||
| 315 | 352 | ||
| 316 | The variable `type-break-keystroke-threshold' is used to determine the | 353 | The variable `type-break-keystroke-threshold' is used to determine the |
| 317 | thresholds at which typing breaks should be considered. You can use | 354 | thresholds 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 | ||
| 338 | Finally, the command `type-break-statistics' prints interesting things." | 375 | The command `type-break-statistics' prints interesting things. |
| 376 | |||
| 377 | Finally, a file (named `type-break-file-name') is used to store information | ||
| 378 | across Emacs sessions. This provides recovery of the break status between | ||
| 379 | sessions and after a crash. Manual changes to the file may result in | ||
| 380 | problems." | ||
| 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 | ||
| 373 | A negative prefix argument disables this mode. | 454 | A negative PREFIX argument disables this mode. |
| 374 | No argument or any non-negative argument enables it. | 455 | No argument or any non-negative argument enables it. |
| 375 | 456 | ||
| 376 | The user may also enable or disable this mode simply by setting the | 457 | The 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 | |||
| 398 | typing break at that moment. The function which does this query is | 479 | typing break at that moment. The function which does this query is |
| 399 | specified by the variable `type-break-query-function'. | 480 | specified by the variable `type-break-query-function'. |
| 400 | 481 | ||
| 401 | A negative prefix argument disables this mode. | 482 | A negative PREFIX argument disables this mode. |
| 402 | No argument or any non-negative argument enables it. | 483 | No argument or any non-negative argument enables it. |
| 403 | 484 | ||
| 404 | The user may also enable or disable this mode simply by setting the | 485 | The 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 | ||
| 531 | return 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'. | ||
| 552 | Returns 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'. | ||
| 564 | Return 0 if the file is missing or if the form read is not an | ||
| 565 | integer." | ||
| 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. |
| 477 | If time is not specified, default to `type-break-interval'." | 650 | If time is not specified it defaults to `type-break-interval'. |
| 651 | START and INTERVAL are used when recovering a break. | ||
| 652 | START is the start of the break (defaults to now). | ||
| 653 | INTERVAL 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'." | |||
| 556 | This may be the case either because the scheduled time has come \(and the | 734 | This may be the case either because the scheduled time has come \(and the |
| 557 | minimum keystroke threshold has been reached\) or because the maximum | 735 | minimum keystroke threshold has been reached\) or because the maximum |
| 558 | keystroke threshold has been exceeded." | 736 | keystroke 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 | |||
| 810 | length of words (5). For the minimum threshold, it uses about a fifth of | 992 | length of words (5). For the minimum threshold, it uses about a fifth of |
| 811 | the computed maximum threshold. | 993 | the computed maximum threshold. |
| 812 | 994 | ||
| 813 | When called from lisp programs, the optional args WORDLEN and FRAC can be | 995 | When called from Lisp programs, the optional args WORDLEN and FRAC can be |
| 814 | used to override the default assumption about average word length and the | 996 | used to override the default assumption about average word length and the |
| 815 | fraction of the maximum threshold to which to set the minimum threshold. | 997 | fraction of the maximum threshold to which to set the minimum threshold. |
| 816 | FRAC should be the inverse of the fractional value; for example, a value of | 998 | FRAC 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) |