diff options
| author | Noah Friedman | 1994-07-18 15:21:50 +0000 |
|---|---|---|
| committer | Noah Friedman | 1994-07-18 15:21:50 +0000 |
| commit | be8d412c3fafc89c961972e956fb12dda188a642 (patch) | |
| tree | 11f3ee67773971f79457e52b512e1cdf794caebb | |
| parent | 4cf64c15e59e8fa7a5bec836aed35442843c9d88 (diff) | |
| download | emacs-be8d412c3fafc89c961972e956fb12dda188a642.tar.gz emacs-be8d412c3fafc89c961972e956fb12dda188a642.zip | |
type-break-mode: Make variable `nil' by default.
type-break-mode (function): If setting to t and mode was already enabled,
don't reschedule breaks or reset keystroke counter.
type-break-good-rest-interval: New variable.
type-break-time-difference: New inline function (defsubst).
tyype-break-time-last-break, type-break-time-next-break,
type-break-time-last-command: New variables.
type-break-check: Reset timers and counters if user has been idle more than
type-break-good-rest-interval seconds (assuming it's set).
Never set keystroke counter to be less than the min threshold.
type-break: Admonish user if s/he rested less than
type-break-good-rest-interval seconds (assuming it's set).
type-break-demo-hanoi: Eat a char when quitting.
type-break-statistics, type-break-guestimate-keystroke-threshold: New
commands.
| -rw-r--r-- | lisp/type-break.el | 278 |
1 files changed, 215 insertions, 63 deletions
diff --git a/lisp/type-break.el b/lisp/type-break.el index 7390613498a..abd7a5d3d9d 100644 --- a/lisp/type-break.el +++ b/lisp/type-break.el | |||
| @@ -1,18 +1,16 @@ | |||
| 1 | ;;; type-break.el --- take breaks from typing at appropriate intervals | 1 | ;;; type-break.el --- encourage rests from typing at appropriate intervals |
| 2 | 2 | ||
| 3 | ;;; Copyright (C) 1994 Roland McGrath | ||
| 4 | ;;; Copyright (C) 1994 Noah S. Friedman | 3 | ;;; Copyright (C) 1994 Noah S. Friedman |
| 5 | 4 | ||
| 6 | ;;; Author: Noah Friedman <friedman@prep.ai.mit.edu> | 5 | ;;; Author: Noah Friedman <friedman@prep.ai.mit.edu> |
| 7 | ;;; Roland McGrath <roland@prep.ai.mit.edu> | ||
| 8 | ;;; Maintainer: friedman@prep.ai.mit.edu | 6 | ;;; Maintainer: friedman@prep.ai.mit.edu |
| 9 | ;;; Keywords: extensions, timers | 7 | ;;; Keywords: extensions, timers |
| 10 | ;;; Status: works in GNU Emacs 19 | 8 | ;;; Status: known to work in GNU Emacs 19.25 or later. |
| 11 | ;;; Created: 1994-07-13 | 9 | ;;; Created: 1994-07-13 |
| 12 | 10 | ||
| 13 | ;;; LCD Archive Entry: | 11 | ;;; LCD Archive Entry: |
| 14 | ;;; type-break|Noah Friedman|friedman@prep.ai.mit.edu| | 12 | ;;; type-break|Noah Friedman|friedman@prep.ai.mit.edu| |
| 15 | ;;; take breaks from typing at appropriate intervals| | 13 | ;;; encourage rests from typing at appropriate intervals| |
| 16 | ;;; $Date$|$Revision$|| | 14 | ;;; $Date$|$Revision$|| |
| 17 | 15 | ||
| 18 | ;;; $Id$ | 16 | ;;; $Id$ |
| @@ -33,13 +31,32 @@ | |||
| 33 | ;;; Inc.; 675 Massachusetts Avenue; Cambridge, MA 02139, USA. | 31 | ;;; Inc.; 675 Massachusetts Avenue; Cambridge, MA 02139, USA. |
| 34 | 32 | ||
| 35 | ;;; Commentary: | 33 | ;;; Commentary: |
| 34 | |||
| 35 | ;;; The docstring for the function `type-break-mode' summarizes most of the | ||
| 36 | ;;; details of the interface. | ||
| 37 | |||
| 38 | ;;; This package relies on the assumption that you live entirely in emacs, | ||
| 39 | ;;; as the author does. If that's not the case for you (e.g. you often | ||
| 40 | ;;; suspend emacs or work in other windows) then this won't help very much; | ||
| 41 | ;;; it will depend on just how often you switch back to emacs. At the very | ||
| 42 | ;;; least, you will want to turn off the keystroke thresholds and rest | ||
| 43 | ;;; interval tracking. | ||
| 44 | |||
| 45 | ;;; Setting type-break-good-rest-interval makes emacs cons like a maniac | ||
| 46 | ;;; because of repeated calls to `current-time'. There's not really any | ||
| 47 | ;;; good way to avoid this without disabling the variable. | ||
| 48 | |||
| 49 | ;;; This package was inspired by Roland McGrath's hanoi-break.el. | ||
| 50 | |||
| 36 | ;;; Code: | 51 | ;;; Code: |
| 37 | 52 | ||
| 38 | 53 | ||
| 39 | (require 'timer) | 54 | (require 'timer) |
| 40 | 55 | ||
| 56 | ;; Make this nil initially so that the call to type-break-mode at the end | ||
| 57 | ;; will cause scheduling and so forth to happen. | ||
| 41 | ;;;###autoload | 58 | ;;;###autoload |
| 42 | (defvar type-break-mode t | 59 | (defvar type-break-mode nil |
| 43 | "*Non-`nil' means typing break mode is enabled. | 60 | "*Non-`nil' means typing break mode is enabled. |
| 44 | See the docstring for the `type-break-mode' command for more information.") | 61 | See the docstring for the `type-break-mode' command for more information.") |
| 45 | 62 | ||
| @@ -48,6 +65,17 @@ See the docstring for the `type-break-mode' command for more information.") | |||
| 48 | "*Number of seconds between scheduled typing breaks.") | 65 | "*Number of seconds between scheduled typing breaks.") |
| 49 | 66 | ||
| 50 | ;;;###autoload | 67 | ;;;###autoload |
| 68 | (defvar type-break-good-rest-interval (/ type-break-interval 6) | ||
| 69 | "*Number of seconds of idle time considered to be an adequate typing rest. | ||
| 70 | |||
| 71 | When this variable is non-`nil', emacs checks the idle time between | ||
| 72 | keystrokes. If this idle time is long enough to be considered a "good" | ||
| 73 | rest from typing, then the next typing break is simply rescheduled for later. | ||
| 74 | |||
| 75 | The user will also be admonished if a forced break isn't at least as long | ||
| 76 | as this time, to remind them to rest longer next time.") | ||
| 77 | |||
| 78 | ;;;###autoload | ||
| 51 | (defvar type-break-query-interval 60 | 79 | (defvar type-break-query-interval 60 |
| 52 | "*Number of seconds between queries to take a break, if put off. | 80 | "*Number of seconds between queries to take a break, if put off. |
| 53 | The user will continue to be prompted at this interval until he or she | 81 | The user will continue to be prompted at this interval until he or she |
| @@ -67,20 +95,23 @@ finally submits to taking a typing break.") | |||
| 67 | (lower (/ upper 4))) | 95 | (lower (/ upper 4))) |
| 68 | (cons lower upper)) | 96 | (cons lower upper)) |
| 69 | "*Upper and lower bound on number of keystrokes for considering typing break. | 97 | "*Upper and lower bound on number of keystrokes for considering typing break. |
| 98 | This structure is a pair of numbers. | ||
| 70 | 99 | ||
| 71 | This structure is a pair of numbers. The first number is the minimum | 100 | The first number is the minimum number of keystrokes that must have been |
| 72 | number of keystrokes that must have been entered since the last typing | 101 | entered since the last typing break before considering another one, even if |
| 73 | break before considering another one, even if the scheduled time has | 102 | the scheduled time has elapsed; the break is simply rescheduled until later |
| 74 | elapsed; the break is simply rescheduled until later if the minimum | 103 | if the minimum threshold hasn't been reached. If this first value is nil, |
| 75 | threshold hasn't been reached. | 104 | then there is no minimum threshold; as soon as the scheduled time has |
| 105 | elapsed, the user will always be queried. | ||
| 76 | 106 | ||
| 77 | The second number is the maximum number of keystrokes that can be entered | 107 | The second number is the maximum number of keystrokes that can be entered |
| 78 | before a typing break is requested immediately, pre-empting the originally | 108 | before a typing break is requested immediately, pre-empting the originally |
| 79 | scheduled break. | 109 | scheduled break. If this second value is nil, then no pre-emptive breaks |
| 110 | will occur; only scheduled ones will. | ||
| 80 | 111 | ||
| 81 | Keys with bucky bits (shift, control, meta, etc) are counted as only one | 112 | Keys with bucky bits (shift, control, meta, etc) are counted as only one |
| 82 | keystroke even though they really require multiple keys to generate them.") | 113 | keystroke even though they really require multiple keys to generate them.") |
| 83 | 114 | ||
| 84 | ;;;###autoload | 115 | ;;;###autoload |
| 85 | (defvar type-break-query-function 'yes-or-no-p | 116 | (defvar type-break-query-function 'yes-or-no-p |
| 86 | "*Function to use for making query for a typing break. | 117 | "*Function to use for making query for a typing break. |
| @@ -98,13 +129,25 @@ key is pressed.") | |||
| 98 | 129 | ||
| 99 | ;; These are internal variables. Do not set them yourself. | 130 | ;; These are internal variables. Do not set them yourself. |
| 100 | 131 | ||
| 101 | ;; Number of commands (roughly # of keystrokes) recorded since last break. | ||
| 102 | (defvar type-break-keystroke-count 0) | ||
| 103 | |||
| 104 | ;; Non-nil when a scheduled typing break is due. | 132 | ;; Non-nil when a scheduled typing break is due. |
| 105 | (defvar type-break-alarm-p nil) | 133 | (defvar type-break-alarm-p nil) |
| 106 | 134 | ||
| 135 | (defvar type-break-keystroke-count 0) | ||
| 136 | |||
| 137 | (defvar type-break-time-last-break nil) | ||
| 138 | (defvar type-break-time-next-break nil) | ||
| 139 | (defvar type-break-time-last-command (current-time)) | ||
| 140 | |||
| 107 | 141 | ||
| 142 | ;; Compute the difference, in seconds, between a and b, two structures | ||
| 143 | ;; similar to those returned by `current-time'. | ||
| 144 | ;; Use addition rather than logand since I found it convenient to add | ||
| 145 | ;; seconds to the cdr of some of my stored time values, which may throw off | ||
| 146 | ;; the number of bits in the cdr. | ||
| 147 | (defsubst type-break-time-difference (a b) | ||
| 148 | (+ (lsh (- (car b) (car a)) 16) | ||
| 149 | (- (car (cdr b)) (car (cdr a))))) | ||
| 150 | |||
| 108 | ;;;###autoload | 151 | ;;;###autoload |
| 109 | (defun type-break-mode (&optional prefix) | 152 | (defun type-break-mode (&optional prefix) |
| 110 | "Enable or disable typing-break mode. | 153 | "Enable or disable typing-break mode. |
| @@ -126,10 +169,10 @@ The user may enable or disable this mode by setting the variable of the | |||
| 126 | same name, though setting it in that way doesn't reschedule a break or | 169 | same name, though setting it in that way doesn't reschedule a break or |
| 127 | reset the keystroke counter. | 170 | reset the keystroke counter. |
| 128 | 171 | ||
| 129 | When this function enables the mode, it schedules a break with | 172 | If the mode was previously disabled and is enabled as a consequence of |
| 130 | `type-break-schedule' to make sure one occurs (the user can call that | 173 | calling this function, it schedules a break with `type-break-schedule' to |
| 131 | command to reschedule the break at any time). It also initializes the | 174 | make sure one occurs (the user can call that command to reschedule the |
| 132 | keystroke counter. | 175 | break at any time). It also initializes the keystroke counter. |
| 133 | 176 | ||
| 134 | The variable `type-break-interval' specifies the number of seconds to | 177 | The variable `type-break-interval' specifies the number of seconds to |
| 135 | schedule between regular typing breaks. This variable doesn't directly | 178 | schedule between regular typing breaks. This variable doesn't directly |
| @@ -140,35 +183,47 @@ The variable `type-break-query-interval' specifies the number of seconds to | |||
| 140 | schedule between repeated queries for breaks when the user answers \"no\" | 183 | schedule between repeated queries for breaks when the user answers \"no\" |
| 141 | to the previous query. | 184 | to the previous query. |
| 142 | 185 | ||
| 143 | The variable `type-break-keystroke-theshold' is used to determine the | 186 | The variable `type-break-good-rest-interval' specifies the minimum amount |
| 144 | thresholds at which typing breaks should be considered. | 187 | of time which is considered a reasonable typing break. Whenever that time |
| 188 | has elapsed, typing breaks are automatically rescheduled for later even if | ||
| 189 | emacs didn't prompt you to take one first. You can disable this behavior. | ||
| 190 | |||
| 191 | The variable `type-break-keystroke-threshold' is used to determine the | ||
| 192 | thresholds at which typing breaks should be considered. You can use | ||
| 193 | the command `type-break-guestimate-keystroke-threshold' to try to | ||
| 194 | approximate good values for this. | ||
| 145 | 195 | ||
| 146 | The variable `type-break-query-function' should contain a function (or the | 196 | The variable `type-break-query-function' should contain a function (or the |
| 147 | symbolic name of a function) to be used to query the user for typing | 197 | symbolic name of a function) to be used to query the user for typing |
| 148 | breaks." | 198 | breaks. |
| 199 | |||
| 200 | Finally, the command `type-break-statistics' prints interesting things." | ||
| 149 | (interactive "P") | 201 | (interactive "P") |
| 150 | ;; make sure it's there. | 202 | ;; make sure it's there. |
| 151 | (add-hook 'post-command-hook 'type-break-check 'append) | 203 | (add-hook 'post-command-hook 'type-break-check 'append) |
| 152 | 204 | ||
| 153 | (cond | 205 | (let ((already-enabled type-break-mode)) |
| 154 | ((null prefix) | 206 | (cond |
| 155 | (setq type-break-mode (not type-break-mode))) | 207 | ((null prefix) |
| 156 | ((numberp (prefix-numeric-value prefix)) | 208 | (setq type-break-mode (not type-break-mode))) |
| 157 | (setq type-break-mode (>= (prefix-numeric-value prefix) 0))) | 209 | ((numberp (prefix-numeric-value prefix)) |
| 158 | (prefix | 210 | (setq type-break-mode (>= (prefix-numeric-value prefix) 0))) |
| 159 | (setq type-break-mode t)) | 211 | (prefix |
| 160 | (t | 212 | (setq type-break-mode t)) |
| 161 | (setq type-break-mode nil))) | 213 | (t |
| 162 | 214 | (setq type-break-mode nil))) | |
| 163 | (cond | 215 | |
| 164 | (type-break-mode | 216 | (cond |
| 165 | (setq type-break-keystroke-count 0) | 217 | ((and already-enabled type-break-mode) |
| 166 | (type-break-schedule) | 218 | (and (interactive-p) |
| 167 | (and (interactive-p) | 219 | (message "type-break-mode was already enabled"))) |
| 168 | (message "type-break-mode is enabled and reset"))) | 220 | (type-break-mode |
| 169 | ((interactive-p) | 221 | (setq type-break-keystroke-count 0) |
| 170 | (message "type-break-mode is disabled"))) | 222 | (type-break-schedule) |
| 171 | 223 | (and (interactive-p) | |
| 224 | (message "type-break-mode is enabled and reset"))) | ||
| 225 | ((interactive-p) | ||
| 226 | (message "type-break-mode is disabled")))) | ||
| 172 | type-break-mode) | 227 | type-break-mode) |
| 173 | 228 | ||
| 174 | ;;;###autoload | 229 | ;;;###autoload |
| @@ -182,13 +237,14 @@ After the typing break is finished, the next break is scheduled | |||
| 182 | as per the function `type-break-schedule', and the keystroke counter is | 237 | as per the function `type-break-schedule', and the keystroke counter is |
| 183 | reset." | 238 | reset." |
| 184 | (interactive) | 239 | (interactive) |
| 240 | (setq type-break-time-last-break (current-time)) | ||
| 185 | (save-window-excursion | 241 | (save-window-excursion |
| 186 | ;; Eat the screen. | 242 | ;; Eat the screen. |
| 187 | (and (eq (selected-window) (minibuffer-window)) | 243 | (and (eq (selected-window) (minibuffer-window)) |
| 188 | (other-window 1)) | 244 | (other-window 1)) |
| 189 | (delete-other-windows) | 245 | (delete-other-windows) |
| 190 | (scroll-right (window-width)) | 246 | (scroll-right (window-width)) |
| 191 | (message "Press any key to finish typing break.") | 247 | (message "Press any key to resume from typing break.") |
| 192 | 248 | ||
| 193 | (random t) | 249 | (random t) |
| 194 | (let* ((len (length type-break-demo-function-vector)) | 250 | (let* ((len (length type-break-demo-function-vector)) |
| @@ -196,10 +252,16 @@ reset." | |||
| 196 | (fn (aref type-break-demo-function-vector idx))) | 252 | (fn (aref type-break-demo-function-vector idx))) |
| 197 | (condition-case () | 253 | (condition-case () |
| 198 | (funcall fn) | 254 | (funcall fn) |
| 199 | (error nil))) | 255 | (error nil)))) |
| 256 | |||
| 257 | (and type-break-good-rest-interval | ||
| 258 | (< (type-break-time-difference type-break-time-last-command | ||
| 259 | (current-time)) | ||
| 260 | type-break-good-rest-interval) | ||
| 261 | (message "That typing break wasn't really long enough. Rest more next time.")) | ||
| 200 | 262 | ||
| 201 | (setq type-break-keystroke-count 0) | 263 | (setq type-break-keystroke-count 0) |
| 202 | (type-break-schedule))) | 264 | (type-break-schedule)) |
| 203 | 265 | ||
| 204 | 266 | ||
| 205 | ;;;###autoload | 267 | ;;;###autoload |
| @@ -211,7 +273,11 @@ If time is not specified, default to `type-break-interval'." | |||
| 211 | (or time (setq time type-break-interval)) | 273 | (or time (setq time type-break-interval)) |
| 212 | ;; Remove any old scheduled break | 274 | ;; Remove any old scheduled break |
| 213 | (type-break-cancel-schedule) | 275 | (type-break-cancel-schedule) |
| 214 | (run-at-time time nil 'type-break-alarm)) | 276 | (run-at-time time nil 'type-break-alarm) |
| 277 | |||
| 278 | (setq type-break-time-next-break (current-time)) | ||
| 279 | (setcar (cdr type-break-time-next-break) | ||
| 280 | (+ time (car (cdr type-break-time-next-break))))) | ||
| 215 | 281 | ||
| 216 | (defun type-break-cancel-schedule () | 282 | (defun type-break-cancel-schedule () |
| 217 | "Cancel scheduled typing breaks. | 283 | "Cancel scheduled typing breaks. |
| @@ -221,7 +287,8 @@ type-break-mode." | |||
| 221 | (interactive) | 287 | (interactive) |
| 222 | (let ((timer-dont-exit t)) | 288 | (let ((timer-dont-exit t)) |
| 223 | (cancel-function-timers 'type-break-alarm)) | 289 | (cancel-function-timers 'type-break-alarm)) |
| 224 | (setq type-break-alarm-p nil)) | 290 | (setq type-break-alarm-p nil) |
| 291 | (setq type-break-time-next-break nil)) | ||
| 225 | 292 | ||
| 226 | (defun type-break-alarm () | 293 | (defun type-break-alarm () |
| 227 | "This function is run when a scheduled typing break is due." | 294 | "This function is run when a scheduled typing break is due." |
| @@ -234,27 +301,56 @@ minimum keystroke threshold has been reached\) or because the maximum | |||
| 234 | keystroke threshold has been exceeded." | 301 | keystroke threshold has been exceeded." |
| 235 | (cond | 302 | (cond |
| 236 | (type-break-mode | 303 | (type-break-mode |
| 237 | (let* ((pair (and (consp type-break-keystroke-threshold) | 304 | (let* ((threshold-pair (and (consp type-break-keystroke-threshold) |
| 238 | type-break-keystroke-threshold)) | 305 | type-break-keystroke-threshold)) |
| 239 | (min-threshold (car pair)) | 306 | (min-threshold (car threshold-pair)) |
| 240 | (max-threshold (cdr pair))) | 307 | (max-threshold (cdr threshold-pair))) |
| 241 | (and pair | 308 | |
| 242 | (stringp (this-command-keys)) | 309 | ;; Reset schedule and keystroke count if user has been idle longer |
| 310 | ;; than a normal resting period. | ||
| 311 | (cond | ||
| 312 | (type-break-good-rest-interval | ||
| 313 | (and (> (type-break-time-difference type-break-time-last-command | ||
| 314 | (current-time)) | ||
| 315 | type-break-good-rest-interval) | ||
| 316 | (progn | ||
| 317 | (setq type-break-keystroke-count 0) | ||
| 318 | (type-break-schedule))) | ||
| 319 | (setq type-break-time-last-command (current-time)))) | ||
| 320 | |||
| 321 | (and threshold-pair | ||
| 243 | (setq type-break-keystroke-count | 322 | (setq type-break-keystroke-count |
| 244 | (+ type-break-keystroke-count (length (this-command-keys))))) | 323 | (+ type-break-keystroke-count (length (this-command-keys))))) |
| 324 | |||
| 245 | (cond | 325 | (cond |
| 246 | ((input-pending-p)) | 326 | ((input-pending-p)) |
| 247 | ((and (numberp max-threshold) | ||
| 248 | (> type-break-keystroke-count max-threshold)) | ||
| 249 | (setq type-break-keystroke-count 0) | ||
| 250 | (type-break-query)) | ||
| 251 | (type-break-alarm-p | 327 | (type-break-alarm-p |
| 252 | (cond | 328 | (cond |
| 253 | ((and (numberp min-threshold) | 329 | ((and min-threshold |
| 254 | (< type-break-keystroke-count min-threshold))) | 330 | (< type-break-keystroke-count min-threshold))) |
| 255 | (t | 331 | (t |
| 256 | (setq type-break-keystroke-count 0) | 332 | ;; If the keystroke count is within min-threshold characters of |
| 257 | (type-break-query))))))))) | 333 | ;; the maximum threshold, set the count to min-threshold. That |
| 334 | ;; way, if the count was really close the threshold and the user | ||
| 335 | ;; doesn't choose to take a break now, s/he won't be pestered | ||
| 336 | ;; almost immediately after saying "no"; that's what the query | ||
| 337 | ;; interval delay is for. | ||
| 338 | ;; On the other hand, don't set it too small (make it at least | ||
| 339 | ;; min-threshold); that way we can be sure the user will be asked | ||
| 340 | ;; again to take a break after the query interval has elapsed. | ||
| 341 | ;; If the user chooses to take a break now, the break function | ||
| 342 | ;; will reset the keystroke count anyway. | ||
| 343 | (and max-threshold | ||
| 344 | min-threshold | ||
| 345 | (> (- max-threshold type-break-keystroke-count) min-threshold) | ||
| 346 | (setq type-break-keystroke-count min-threshold)) | ||
| 347 | (type-break-query)))) | ||
| 348 | ((and max-threshold | ||
| 349 | (> type-break-keystroke-count max-threshold)) | ||
| 350 | ;; Set it to the min threshold if possible, to be sure the user | ||
| 351 | ;; will be pestered again in at least a minute. | ||
| 352 | (setq type-break-keystroke-count (or min-threshold 0)) | ||
| 353 | (type-break-query))))))) | ||
| 258 | 354 | ||
| 259 | (defun type-break-query () | 355 | (defun type-break-query () |
| 260 | (condition-case () | 356 | (condition-case () |
| @@ -280,7 +376,9 @@ keystroke threshold has been exceeded." | |||
| 280 | ;; Wait for user to come back. | 376 | ;; Wait for user to come back. |
| 281 | (read-char) | 377 | (read-char) |
| 282 | (kill-buffer "*Hanoi*")) | 378 | (kill-buffer "*Hanoi*")) |
| 283 | (quit | 379 | (quit |
| 380 | ;; eat char | ||
| 381 | (read-char) | ||
| 284 | (and (get-buffer "*Hanoi*") | 382 | (and (get-buffer "*Hanoi*") |
| 285 | (kill-buffer "*Hanoi*"))))) | 383 | (kill-buffer "*Hanoi*"))))) |
| 286 | 384 | ||
| @@ -297,11 +395,65 @@ keystroke threshold has been exceeded." | |||
| 297 | ;; Wait for user to come back. | 395 | ;; Wait for user to come back. |
| 298 | (read-char) | 396 | (read-char) |
| 299 | (kill-buffer "*Life*")) | 397 | (kill-buffer "*Life*")) |
| 300 | (quit | 398 | (quit |
| 301 | (and (get-buffer "*Life*") | 399 | (and (get-buffer "*Life*") |
| 302 | (kill-buffer "*Life*"))))) | 400 | (kill-buffer "*Life*"))))) |
| 303 | 401 | ||
| 304 | 402 | ||
| 403 | ;;;###autoload | ||
| 404 | (defun type-break-statistics () | ||
| 405 | "Print statistics about typing breaks in a temporary buffer. | ||
| 406 | This includes the last time a typing break was taken, when the next one is | ||
| 407 | scheduled, the keystroke thresholds and the current keystroke count, etc." | ||
| 408 | (interactive) | ||
| 409 | (with-output-to-temp-buffer "*Typing Break Statistics*" | ||
| 410 | (princ (format "Typing break statistics\n-----------------------\n | ||
| 411 | Last typing break : %s | ||
| 412 | Next scheduled typing break : %s\n | ||
| 413 | Minimum keystroke threshold : %s | ||
| 414 | Maximum keystroke threshold : %s | ||
| 415 | Current keystroke count : %s" | ||
| 416 | (if type-break-time-last-break | ||
| 417 | (current-time-string type-break-time-last-break) | ||
| 418 | "never") | ||
| 419 | (if (and type-break-mode type-break-time-next-break) | ||
| 420 | (format "%s\t(%d minutes from now)" | ||
| 421 | (current-time-string type-break-time-next-break) | ||
| 422 | (/ (type-break-time-difference | ||
| 423 | (current-time) type-break-time-next-break) | ||
| 424 | 60)) | ||
| 425 | "none scheduled") | ||
| 426 | (or (car type-break-keystroke-threshold) "none") | ||
| 427 | (or (cdr type-break-keystroke-threshold) "none") | ||
| 428 | type-break-keystroke-count)))) | ||
| 429 | |||
| 430 | ;;;###autoload | ||
| 431 | (defun type-break-guestimate-keystroke-threshold (wpm &optional wordlen frac) | ||
| 432 | "Guess values for the minimum/maximum keystroke threshold for typing breaks. | ||
| 433 | If called interactively, the user is prompted for their guess as to how | ||
| 434 | many words per minute they usually type. From that, the command sets the | ||
| 435 | values in `type-break-keystroke-threshold' based on a fairly simple | ||
| 436 | algorithm involving assumptions about the average length of words (5). | ||
| 437 | For the minimum threshold, it uses about a quarter of the computed maximum | ||
| 438 | threshold. | ||
| 439 | |||
| 440 | When called from lisp programs, the optional args WORDLEN and FRAC can be | ||
| 441 | used to override the default assumption about average word length and the | ||
| 442 | fraction of the maximum threshold to which to set the minimum threshold. | ||
| 443 | FRAC should be the inverse of the fractional value; for example, a value of | ||
| 444 | 2 would mean to use one half, a value of 4 would mean to use one quarter, etc." | ||
| 445 | (interactive "nHow many words per minute do you type? ") | ||
| 446 | (let* ((upper (* wpm (or wordlen 5) (/ type-break-interval 60))) | ||
| 447 | (lower (/ upper (or frac 4)))) | ||
| 448 | (or type-break-keystroke-threshold | ||
| 449 | (setq type-break-keystroke-threshold (cons nil nil))) | ||
| 450 | (setcar type-break-keystroke-threshold lower) | ||
| 451 | (setcdr type-break-keystroke-threshold upper) | ||
| 452 | (if (interactive-p) | ||
| 453 | (message "min threshold: %d\tmax threshold: %d" lower upper) | ||
| 454 | type-break-keystroke-threshold))) | ||
| 455 | |||
| 456 | |||
| 305 | (provide 'type-break) | 457 | (provide 'type-break) |
| 306 | 458 | ||
| 307 | (type-break-mode t) | 459 | (type-break-mode t) |