Mercurial > emacs
comparison lisp/type-break.el @ 8276:73b85998c868
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.
author | Noah Friedman <friedman@splode.com> |
---|---|
date | Mon, 18 Jul 1994 15:21:50 +0000 |
parents | 4fdf77f4e45c |
children | e41f372e0ea3 |
comparison
equal
deleted
inserted
replaced
8275:4fdf77f4e45c | 8276:73b85998c868 |
---|---|
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$ |
19 | 17 |
20 ;;; This program is free software; you can redistribute it and/or modify | 18 ;;; This program is free software; you can redistribute it and/or modify |
31 ;;; along with this program; if not, you can either send email to this | 29 ;;; along with this program; if not, you can either send email to this |
32 ;;; program's maintainer or write to: The Free Software Foundation, | 30 ;;; program's maintainer or write to: The Free Software Foundation, |
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 |
41 ;;;###autoload | 56 ;; Make this nil initially so that the call to type-break-mode at the end |
42 (defvar type-break-mode t | 57 ;; will cause scheduling and so forth to happen. |
58 ;;;###autoload | |
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 |
46 ;;;###autoload | 63 ;;;###autoload |
47 (defvar type-break-interval (* 60 60) | 64 (defvar type-break-interval (* 60 60) |
48 "*Number of seconds between scheduled typing breaks.") | 65 "*Number of seconds between scheduled typing breaks.") |
66 | |
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.") | |
49 | 77 |
50 ;;;###autoload | 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 |
65 (avg-word-length 5) | 93 (avg-word-length 5) |
66 (upper (* wpm avg-word-length (/ type-break-interval 60))) | 94 (upper (* wpm avg-word-length (/ type-break-interval 60))) |
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. |
70 | 98 This structure is a pair of numbers. |
71 This structure is a pair of numbers. The first number is the minimum | 99 |
72 number of keystrokes that must have been entered since the last typing | 100 The first number is the minimum number of keystrokes that must have been |
73 break before considering another one, even if the scheduled time has | 101 entered since the last typing break before considering another one, even if |
74 elapsed; the break is simply rescheduled until later if the minimum | 102 the scheduled time has elapsed; the break is simply rescheduled until later |
75 threshold hasn't been reached. | 103 if the minimum threshold hasn't been reached. If this first value is nil, |
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. |
87 It should take a string as an argument, the prompt. | 118 It should take a string as an argument, the prompt. |
88 Usually this should be set to `yes-or-no-p' or `y-or-n-p'.") | 119 Usually this should be set to `yes-or-no-p' or `y-or-n-p'.") |
96 Any function in this vector should start a demo which ceases as soon as a | 127 Any function in this vector should start a demo which ceases as soon as a |
97 key is pressed.") | 128 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 |
107 | 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 | |
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. |
111 This is a minor mode, but it is global to all buffers by default. | 154 This is a minor mode, but it is global to all buffers by default. |
112 | 155 |
124 | 167 |
125 The user may enable or disable this mode by setting the variable of the | 168 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 |
136 affect the time schedule; it simply provides a default for the | 179 affect the time schedule; it simply provides a default for the |
137 `type-break-schedule' command. | 180 `type-break-schedule' command. |
138 | 181 |
139 The variable `type-break-query-interval' specifies the number of seconds to | 182 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 |
175 (defun type-break () | 230 (defun type-break () |
176 "Take a typing break. | 231 "Take a typing break. |
180 | 235 |
181 After the typing break is finished, the next break is scheduled | 236 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)) |
195 (idx (random len)) | 251 (idx (random len)) |
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)))) |
200 | 256 |
201 (setq type-break-keystroke-count 0) | 257 (and type-break-good-rest-interval |
202 (type-break-schedule))) | 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.")) | |
262 | |
263 (setq type-break-keystroke-count 0) | |
264 (type-break-schedule)) | |
203 | 265 |
204 | 266 |
205 ;;;###autoload | 267 ;;;###autoload |
206 (defun type-break-schedule (&optional time) | 268 (defun type-break-schedule (&optional time) |
207 "Schedule a typing break for TIME seconds from now. | 269 "Schedule a typing break for TIME seconds from now. |
209 (interactive (list (and current-prefix-arg | 271 (interactive (list (and current-prefix-arg |
210 (prefix-numeric-value current-prefix-arg)))) | 272 (prefix-numeric-value current-prefix-arg)))) |
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. |
218 This does not prevent queries for typing breaks when the keystroke | 284 This does not prevent queries for typing breaks when the keystroke |
219 threshold has been reached; to turn off typing breaks altogether, turn off | 285 threshold has been reached; to turn off typing breaks altogether, turn off |
220 type-break-mode." | 286 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." |
228 (setq type-break-alarm-p t)) | 295 (setq type-break-alarm-p t)) |
229 | 296 |
232 This may be the case either because the scheduled time has come \(and the | 299 This may be the case either because the scheduled time has come \(and the |
233 minimum keystroke threshold has been reached\) or because the maximum | 300 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 () |
261 (cond | 357 (cond |
262 ((funcall type-break-query-function "Take a break from typing now? ") | 358 ((funcall type-break-query-function "Take a break from typing now? ") |
278 (progn | 374 (progn |
279 (hanoi (/ (window-width) 8)) | 375 (hanoi (/ (window-width) 8)) |
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 |
287 ;; This is a wrapper around life that calls it with a `sleep' arg to make | 385 ;; This is a wrapper around life that calls it with a `sleep' arg to make |
288 ;; it run a little more leisurely. | 386 ;; it run a little more leisurely. |
295 (progn | 393 (progn |
296 (life 3) | 394 (life 3) |
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) |
308 | 460 |
309 ;;; type-break.el ends here | 461 ;;; type-break.el ends here |