diff options
| author | Noah Friedman | 1994-07-21 10:11:59 +0000 |
|---|---|---|
| committer | Noah Friedman | 1994-07-21 10:11:59 +0000 |
| commit | cc669dd81045a9fdc4aa566140f750918ec39600 (patch) | |
| tree | 45ae55995d5e58509a159230cd404239a4bc7be6 | |
| parent | fcbadd58adee0da90604c659e8609eaa605c4aa5 (diff) | |
| download | emacs-cc669dd81045a9fdc4aa566140f750918ec39600.tar.gz emacs-cc669dd81045a9fdc4aa566140f750918ec39600.zip | |
type-break-good-rest-interval: Doc fix.
type-break-keystroke-threshold: Calcuate based on 35wpm, not 30.
type-break-demo-function-vector: Variable deleted.
type-break-demo-functions: New variable.
type-break: Use new variable.
type-break-time-difference: Return absolute value.
type-break-format-time: New inline function (defsubst).
type-break-statistics, type-break: Use it.
type-break-mode: Just test prefix-numeric-value >= 0 to to enable mode.
The only visible difference is that invocation with no prefix arg the same
as if given positive numeric prefix arg now.
Do not document type-break-query-interval or type-break-query-function
here; make fritterware-happy users read the source.
type-break: If type break is much less (at least 2 minutes) than a "good
rest interval", ask user whether or not to continue with the break.
type-break-check: Do nothing if user is in the minibuffer.
When alarm is signaled but min threshold isn't reached, reschedule break.
type-break-demo-life: Eat char entered to end life demo.
| -rw-r--r-- | lisp/type-break.el | 152 |
1 files changed, 81 insertions, 71 deletions
diff --git a/lisp/type-break.el b/lisp/type-break.el index 84e1dab026e..341895415b0 100644 --- a/lisp/type-break.el +++ b/lisp/type-break.el | |||
| @@ -51,6 +51,7 @@ | |||
| 51 | ;;; repetitive strain injury? | 51 | ;;; repetitive strain injury? |
| 52 | 52 | ||
| 53 | ;;; This package was inspired by Roland McGrath's hanoi-break.el. | 53 | ;;; This package was inspired by Roland McGrath's hanoi-break.el. |
| 54 | ;;; Thanks to Mark Ashton <mpashton@gnu.ai.mit.edu> for feedback and ideas. | ||
| 54 | 55 | ||
| 55 | ;;; Code: | 56 | ;;; Code: |
| 56 | 57 | ||
| @@ -73,11 +74,11 @@ See the docstring for the `type-break-mode' command for more information.") | |||
| 73 | "*Number of seconds of idle time considered to be an adequate typing rest. | 74 | "*Number of seconds of idle time considered to be an adequate typing rest. |
| 74 | 75 | ||
| 75 | When this variable is non-`nil', emacs checks the idle time between | 76 | When this variable is non-`nil', emacs checks the idle time between |
| 76 | keystrokes. If this idle time is long enough to be considered a "good" | 77 | keystrokes. If this idle time is long enough to be considered a \"good\" |
| 77 | rest from typing, then the next typing break is simply rescheduled for later. | 78 | rest from typing, then the next typing break is simply rescheduled for later. |
| 78 | 79 | ||
| 79 | The user will also be admonished if a forced break isn't at least as long | 80 | If a break is interrupted before this much time elapses, the user will be |
| 80 | as this time, to remind them to rest longer next time.") | 81 | asked whether or not really to interrupt the break.") |
| 81 | 82 | ||
| 82 | ;;;###autoload | 83 | ;;;###autoload |
| 83 | (defvar type-break-query-interval 60 | 84 | (defvar type-break-query-interval 60 |
| @@ -87,7 +88,7 @@ finally submits to taking a typing break.") | |||
| 87 | 88 | ||
| 88 | ;;;###autoload | 89 | ;;;###autoload |
| 89 | (defvar type-break-keystroke-threshold | 90 | (defvar type-break-keystroke-threshold |
| 90 | ;; Assuming typing speed is 30wpm (on the average, do you really | 91 | ;; Assuming typing speed is 35wpm (on the average, do you really |
| 91 | ;; type more than that in a minute? I spend a lot of time reading mail | 92 | ;; type more than that in a minute? I spend a lot of time reading mail |
| 92 | ;; and simply studying code in buffers) and average word length is | 93 | ;; and simply studying code in buffers) and average word length is |
| 93 | ;; about 5 letters, default upper threshold to the average number of | 94 | ;; about 5 letters, default upper threshold to the average number of |
| @@ -95,7 +96,7 @@ finally submits to taking a typing break.") | |||
| 95 | ;; user goes through a furious burst of typing activity, cause a typing | 96 | ;; user goes through a furious burst of typing activity, cause a typing |
| 96 | ;; break to be required sooner than originally scheduled. | 97 | ;; break to be required sooner than originally scheduled. |
| 97 | ;; Conversely, the minimum threshold should be about a fifth of this. | 98 | ;; Conversely, the minimum threshold should be about a fifth of this. |
| 98 | (let* ((wpm 30) | 99 | (let* ((wpm 35) |
| 99 | (avg-word-length 5) | 100 | (avg-word-length 5) |
| 100 | (upper (* wpm avg-word-length (/ type-break-interval 60))) | 101 | (upper (* wpm avg-word-length (/ type-break-interval 60))) |
| 101 | (lower (/ upper 5))) | 102 | (lower (/ upper 5))) |
| @@ -124,22 +125,19 @@ keystroke even though they really require multiple keys to generate them.") | |||
| 124 | It should take a string as an argument, the prompt. | 125 | It should take a string as an argument, the prompt. |
| 125 | Usually this should be set to `yes-or-no-p' or `y-or-n-p'.") | 126 | Usually this should be set to `yes-or-no-p' or `y-or-n-p'.") |
| 126 | 127 | ||
| 127 | (defvar type-break-demo-function-vector | 128 | (defvar type-break-demo-functions |
| 128 | [type-break-demo-life type-break-demo-hanoi] | 129 | '(type-break-demo-life type-break-demo-hanoi) |
| 129 | "*Vector consisting of functions to run as demos during typing breaks. | 130 | "*List of functions to consider running as demos during typing breaks. |
| 130 | When a typing break begins, one of these functions is selected randomly | 131 | When a typing break begins, one of these functions is selected randomly |
| 131 | to have emacs do something interesting. | 132 | to have emacs do something interesting. |
| 132 | 133 | ||
| 133 | Any function in this vector should start a demo which ceases as soon as a | 134 | Any function in this list should start a demo which ceases as soon as a |
| 134 | key is pressed.") | 135 | key is pressed.") |
| 135 | 136 | ||
| 136 | ;; These are internal variables. Do not set them yourself. | 137 | ;; These are internal variables. Do not set them yourself. |
| 137 | 138 | ||
| 138 | ;; Non-nil when a scheduled typing break is due. | 139 | (defvar type-break-alarm-p nil) ; Non-nil when a scheduled typing break is due. |
| 139 | (defvar type-break-alarm-p nil) | ||
| 140 | |||
| 141 | (defvar type-break-keystroke-count 0) | 140 | (defvar type-break-keystroke-count 0) |
| 142 | |||
| 143 | (defvar type-break-time-last-break nil) | 141 | (defvar type-break-time-last-break nil) |
| 144 | (defvar type-break-time-next-break nil) | 142 | (defvar type-break-time-next-break nil) |
| 145 | (defvar type-break-time-last-command (current-time)) | 143 | (defvar type-break-time-last-command (current-time)) |
| @@ -151,9 +149,18 @@ key is pressed.") | |||
| 151 | ;; seconds to the cdr of some of my stored time values, which may throw off | 149 | ;; seconds to the cdr of some of my stored time values, which may throw off |
| 152 | ;; the number of bits in the cdr. | 150 | ;; the number of bits in the cdr. |
| 153 | (defsubst type-break-time-difference (a b) | 151 | (defsubst type-break-time-difference (a b) |
| 154 | (+ (lsh (- (car b) (car a)) 16) | 152 | (abs (+ (lsh (- (car b) (car a)) 16) |
| 155 | (- (car (cdr b)) (car (cdr a))))) | 153 | (- (car (cdr b)) (car (cdr a)))))) |
| 156 | 154 | ||
| 155 | (defsubst type-break-format-time (secs) | ||
| 156 | (let ((mins (/ secs 60))) | ||
| 157 | (cond | ||
| 158 | ((> mins 0) | ||
| 159 | (format "%d minutes" mins)) | ||
| 160 | (t | ||
| 161 | (format "%d seconds" secs))))) | ||
| 162 | |||
| 163 | |||
| 157 | ;;;###autoload | 164 | ;;;###autoload |
| 158 | (defun type-break-mode (&optional prefix) | 165 | (defun type-break-mode (&optional prefix) |
| 159 | "Enable or disable typing-break mode. | 166 | "Enable or disable typing-break mode. |
| @@ -167,9 +174,8 @@ again in a short period of time. The idea is to give the user enough time | |||
| 167 | to find a good breaking point in his or her work, but be sufficiently | 174 | to find a good breaking point in his or her work, but be sufficiently |
| 168 | annoying to discourage putting typing breaks off indefinitely. | 175 | annoying to discourage putting typing breaks off indefinitely. |
| 169 | 176 | ||
| 170 | Calling this command with no prefix argument toggles this mode. | ||
| 171 | A negative prefix argument disables this mode. | 177 | A negative prefix argument disables this mode. |
| 172 | A non-negative prefix argument or any other non-`nil' argument enables it. | 178 | No argument or any non-negative argument enables it. |
| 173 | 179 | ||
| 174 | The user may enable or disable this mode by setting the variable of the | 180 | The user may enable or disable this mode by setting the variable of the |
| 175 | same name, though setting it in that way doesn't reschedule a break or | 181 | same name, though setting it in that way doesn't reschedule a break or |
| @@ -185,44 +191,30 @@ schedule between regular typing breaks. This variable doesn't directly | |||
| 185 | affect the time schedule; it simply provides a default for the | 191 | affect the time schedule; it simply provides a default for the |
| 186 | `type-break-schedule' command. | 192 | `type-break-schedule' command. |
| 187 | 193 | ||
| 188 | The variable `type-break-query-interval' specifies the number of seconds to | 194 | If set, the variable `type-break-good-rest-interval' specifies the minimum |
| 189 | schedule between repeated queries for breaks when the user answers \"no\" | 195 | amount of time which is considered a reasonable typing break. Whenever |
| 190 | to the previous query. | 196 | that time has elapsed, typing breaks are automatically rescheduled for |
| 191 | 197 | later even if emacs didn't prompt you to take one first. Also, if a break | |
| 192 | The variable `type-break-good-rest-interval' specifies the minimum amount | 198 | is ended before this much time has elapsed, the user will be asked whether |
| 193 | of time which is considered a reasonable typing break. Whenever that time | 199 | or not to continue. |
| 194 | has elapsed, typing breaks are automatically rescheduled for later even if | ||
| 195 | emacs didn't prompt you to take one first. You can disable this behavior. | ||
| 196 | 200 | ||
| 197 | The variable `type-break-keystroke-threshold' is used to determine the | 201 | The variable `type-break-keystroke-threshold' is used to determine the |
| 198 | thresholds at which typing breaks should be considered. You can use | 202 | thresholds at which typing breaks should be considered. You can use |
| 199 | the command `type-break-guestimate-keystroke-threshold' to try to | 203 | the command `type-break-guestimate-keystroke-threshold' to try to |
| 200 | approximate good values for this. | 204 | approximate good values for this. |
| 201 | 205 | ||
| 202 | The variable `type-break-query-function' should contain a function (or the | ||
| 203 | symbolic name of a function) to be used to query the user for typing | ||
| 204 | breaks. | ||
| 205 | |||
| 206 | Finally, the command `type-break-statistics' prints interesting things." | 206 | Finally, the command `type-break-statistics' prints interesting things." |
| 207 | (interactive "P") | 207 | (interactive "P") |
| 208 | ;; make sure it's there. | 208 | ;; make sure it's there. |
| 209 | (add-hook 'post-command-hook 'type-break-check 'append) | 209 | (add-hook 'post-command-hook 'type-break-check 'append) |
| 210 | 210 | ||
| 211 | (let ((already-enabled type-break-mode)) | 211 | (let ((already-enabled type-break-mode)) |
| 212 | (cond | 212 | (setq type-break-mode (>= (prefix-numeric-value prefix) 0)) |
| 213 | ((null prefix) | ||
| 214 | (setq type-break-mode (not type-break-mode))) | ||
| 215 | ((numberp (prefix-numeric-value prefix)) | ||
| 216 | (setq type-break-mode (>= (prefix-numeric-value prefix) 0))) | ||
| 217 | (prefix | ||
| 218 | (setq type-break-mode t)) | ||
| 219 | (t | ||
| 220 | (setq type-break-mode nil))) | ||
| 221 | 213 | ||
| 222 | (cond | 214 | (cond |
| 223 | ((and already-enabled type-break-mode) | 215 | ((and already-enabled type-break-mode) |
| 224 | (and (interactive-p) | 216 | (and (interactive-p) |
| 225 | (message "type-break-mode was already enabled"))) | 217 | (message "type-break-mode is enabled"))) |
| 226 | (type-break-mode | 218 | (type-break-mode |
| 227 | (setq type-break-keystroke-count 0) | 219 | (setq type-break-keystroke-count 0) |
| 228 | (type-break-schedule) | 220 | (type-break-schedule) |
| @@ -237,34 +229,50 @@ Finally, the command `type-break-statistics' prints interesting things." | |||
| 237 | "Take a typing break. | 229 | "Take a typing break. |
| 238 | 230 | ||
| 239 | During the break, a demo selected from the functions listed in | 231 | During the break, a demo selected from the functions listed in |
| 240 | `type-break-demo-function-vector' is run. | 232 | `type-break-demo-functions' is run. |
| 241 | 233 | ||
| 242 | After the typing break is finished, the next break is scheduled | 234 | After the typing break is finished, the next break is scheduled |
| 243 | as per the function `type-break-schedule', and the keystroke counter is | 235 | as per the function `type-break-schedule'." |
| 244 | reset." | ||
| 245 | (interactive) | 236 | (interactive) |
| 246 | (setq type-break-time-last-break (current-time)) | 237 | (let ((continue t) |
| 247 | (save-window-excursion | 238 | (start-time (current-time))) |
| 248 | ;; Eat the screen. | 239 | (setq type-break-time-last-break start-time) |
| 249 | (and (eq (selected-window) (minibuffer-window)) | 240 | (while continue |
| 250 | (other-window 1)) | 241 | (save-window-excursion |
| 251 | (delete-other-windows) | 242 | ;; Eat the screen. |
| 252 | (scroll-right (window-width)) | 243 | (and (eq (selected-window) (minibuffer-window)) |
| 253 | (message "Press any key to resume from typing break.") | 244 | (other-window 1)) |
| 254 | 245 | (delete-other-windows) | |
| 255 | (random t) | 246 | (scroll-right (window-width)) |
| 256 | (let* ((len (length type-break-demo-function-vector)) | 247 | (message "Press any key to resume from typing break.") |
| 257 | (idx (random len)) | 248 | |
| 258 | (fn (aref type-break-demo-function-vector idx))) | 249 | (random t) |
| 259 | (condition-case () | 250 | (let* ((len (length type-break-demo-functions)) |
| 260 | (funcall fn) | 251 | (idx (random len)) |
| 261 | (error nil)))) | 252 | (fn (nth idx type-break-demo-functions))) |
| 253 | (condition-case () | ||
| 254 | (funcall fn) | ||
| 255 | (error nil)))) | ||
| 262 | 256 | ||
| 263 | (and type-break-good-rest-interval | 257 | (cond |
| 264 | (< (type-break-time-difference type-break-time-last-command | 258 | (type-break-good-rest-interval |
| 265 | (current-time)) | 259 | (let ((break-secs (type-break-time-difference |
| 266 | type-break-good-rest-interval) | 260 | start-time (current-time)))) |
| 267 | (message "That typing break wasn't really long enough. Rest more next time.")) | 261 | (cond |
| 262 | ((>= break-secs type-break-good-rest-interval) | ||
| 263 | (setq continue nil)) | ||
| 264 | ;; Don't be pedantic; if user's rest was only a minute or two | ||
| 265 | ;; short, why bother? | ||
| 266 | ((> 120 (abs (- break-secs type-break-good-rest-interval))) | ||
| 267 | (setq continue nil)) | ||
| 268 | ((funcall | ||
| 269 | type-break-query-function | ||
| 270 | (format "You really ought to rest %s more. Continue break? " | ||
| 271 | (type-break-format-time (- type-break-good-rest-interval | ||
| 272 | break-secs))))) | ||
| 273 | (t | ||
| 274 | (setq continue nil))))) | ||
| 275 | (t (setq continue nil))))) | ||
| 268 | 276 | ||
| 269 | (setq type-break-keystroke-count 0) | 277 | (setq type-break-keystroke-count 0) |
| 270 | (type-break-schedule)) | 278 | (type-break-schedule)) |
| @@ -321,6 +329,7 @@ keystroke threshold has been exceeded." | |||
| 321 | type-break-good-rest-interval) | 329 | type-break-good-rest-interval) |
| 322 | (progn | 330 | (progn |
| 323 | (setq type-break-keystroke-count 0) | 331 | (setq type-break-keystroke-count 0) |
| 332 | (setq type-break-time-last-break (current-time)) | ||
| 324 | (type-break-schedule))) | 333 | (type-break-schedule))) |
| 325 | (setq type-break-time-last-command (current-time)))) | 334 | (setq type-break-time-last-command (current-time)))) |
| 326 | 335 | ||
| @@ -330,10 +339,12 @@ keystroke threshold has been exceeded." | |||
| 330 | 339 | ||
| 331 | (cond | 340 | (cond |
| 332 | ((input-pending-p)) | 341 | ((input-pending-p)) |
| 342 | ((eq (selected-window) (minibuffer-window))) | ||
| 333 | (type-break-alarm-p | 343 | (type-break-alarm-p |
| 334 | (cond | 344 | (cond |
| 335 | ((and min-threshold | 345 | ((and min-threshold |
| 336 | (< type-break-keystroke-count min-threshold))) | 346 | (< type-break-keystroke-count min-threshold)) |
| 347 | (type-break-schedule)) | ||
| 337 | (t | 348 | (t |
| 338 | ;; If the keystroke count is within min-threshold characters of | 349 | ;; If the keystroke count is within min-threshold characters of |
| 339 | ;; the maximum threshold, set the count to min-threshold. That | 350 | ;; the maximum threshold, set the count to min-threshold. That |
| @@ -401,6 +412,8 @@ keystroke threshold has been exceeded." | |||
| 401 | (condition-case () | 412 | (condition-case () |
| 402 | (progn | 413 | (progn |
| 403 | (life 3) | 414 | (life 3) |
| 415 | ;; wait for user to return | ||
| 416 | (read-char) | ||
| 404 | (kill-buffer "*Life*")) | 417 | (kill-buffer "*Life*")) |
| 405 | (life-extinct | 418 | (life-extinct |
| 406 | (message (get 'life-extinct 'error-message)) | 419 | (message (get 'life-extinct 'error-message)) |
| @@ -431,13 +444,10 @@ Current keystroke count : %s" | |||
| 431 | (if (and type-break-mode type-break-time-next-break) | 444 | (if (and type-break-mode type-break-time-next-break) |
| 432 | (format "%s\t(%s from now)" | 445 | (format "%s\t(%s from now)" |
| 433 | (current-time-string type-break-time-next-break) | 446 | (current-time-string type-break-time-next-break) |
| 434 | (let* ((secs (type-break-time-difference | 447 | (type-break-format-time |
| 435 | (current-time) | 448 | (type-break-time-difference |
| 436 | type-break-time-next-break)) | 449 | (current-time) |
| 437 | (mins (/ secs 60))) | 450 | type-break-time-next-break))) |
| 438 | (if (> mins 0) | ||
| 439 | (format "%d minutes" mins) | ||
| 440 | (format "%d seconds" secs)))) | ||
| 441 | "none scheduled") | 451 | "none scheduled") |
| 442 | (or (car type-break-keystroke-threshold) "none") | 452 | (or (car type-break-keystroke-threshold) "none") |
| 443 | (or (cdr type-break-keystroke-threshold) "none") | 453 | (or (cdr type-break-keystroke-threshold) "none") |