aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoah Friedman1994-07-21 10:11:59 +0000
committerNoah Friedman1994-07-21 10:11:59 +0000
commitcc669dd81045a9fdc4aa566140f750918ec39600 (patch)
tree45ae55995d5e58509a159230cd404239a4bc7be6
parentfcbadd58adee0da90604c659e8609eaa605c4aa5 (diff)
downloademacs-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.el152
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
75When this variable is non-`nil', emacs checks the idle time between 76When this variable is non-`nil', emacs checks the idle time between
76keystrokes. If this idle time is long enough to be considered a "good" 77keystrokes. If this idle time is long enough to be considered a \"good\"
77rest from typing, then the next typing break is simply rescheduled for later. 78rest from typing, then the next typing break is simply rescheduled for later.
78 79
79The user will also be admonished if a forced break isn't at least as long 80If a break is interrupted before this much time elapses, the user will be
80as this time, to remind them to rest longer next time.") 81asked 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.")
124It should take a string as an argument, the prompt. 125It should take a string as an argument, the prompt.
125Usually this should be set to `yes-or-no-p' or `y-or-n-p'.") 126Usually 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.
130When a typing break begins, one of these functions is selected randomly 131When a typing break begins, one of these functions is selected randomly
131to have emacs do something interesting. 132to have emacs do something interesting.
132 133
133Any function in this vector should start a demo which ceases as soon as a 134Any function in this list should start a demo which ceases as soon as a
134key is pressed.") 135key 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
167to find a good breaking point in his or her work, but be sufficiently 174to find a good breaking point in his or her work, but be sufficiently
168annoying to discourage putting typing breaks off indefinitely. 175annoying to discourage putting typing breaks off indefinitely.
169 176
170Calling this command with no prefix argument toggles this mode.
171A negative prefix argument disables this mode. 177A negative prefix argument disables this mode.
172A non-negative prefix argument or any other non-`nil' argument enables it. 178No argument or any non-negative argument enables it.
173 179
174The user may enable or disable this mode by setting the variable of the 180The user may enable or disable this mode by setting the variable of the
175same name, though setting it in that way doesn't reschedule a break or 181same 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
185affect the time schedule; it simply provides a default for the 191affect the time schedule; it simply provides a default for the
186`type-break-schedule' command. 192`type-break-schedule' command.
187 193
188The variable `type-break-query-interval' specifies the number of seconds to 194If set, the variable `type-break-good-rest-interval' specifies the minimum
189schedule between repeated queries for breaks when the user answers \"no\" 195amount of time which is considered a reasonable typing break. Whenever
190to the previous query. 196that time has elapsed, typing breaks are automatically rescheduled for
191 197later even if emacs didn't prompt you to take one first. Also, if a break
192The variable `type-break-good-rest-interval' specifies the minimum amount 198is ended before this much time has elapsed, the user will be asked whether
193of time which is considered a reasonable typing break. Whenever that time 199or not to continue.
194has elapsed, typing breaks are automatically rescheduled for later even if
195emacs didn't prompt you to take one first. You can disable this behavior.
196 200
197The variable `type-break-keystroke-threshold' is used to determine the 201The variable `type-break-keystroke-threshold' is used to determine the
198thresholds at which typing breaks should be considered. You can use 202thresholds at which typing breaks should be considered. You can use
199the command `type-break-guestimate-keystroke-threshold' to try to 203the command `type-break-guestimate-keystroke-threshold' to try to
200approximate good values for this. 204approximate good values for this.
201 205
202The variable `type-break-query-function' should contain a function (or the
203symbolic name of a function) to be used to query the user for typing
204breaks.
205
206Finally, the command `type-break-statistics' prints interesting things." 206Finally, 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
239During the break, a demo selected from the functions listed in 231During 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
242After the typing break is finished, the next break is scheduled 234After the typing break is finished, the next break is scheduled
243as per the function `type-break-schedule', and the keystroke counter is 235as per the function `type-break-schedule'."
244reset."
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")