aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoah Friedman1994-07-14 12:10:27 +0000
committerNoah Friedman1994-07-14 12:10:27 +0000
commit458401b6ed7a4f78a99e47e4029c4cbf185e1cbf (patch)
tree28b5ad44c1588ef99d307fcd21ed6b4fa0f44805
parent68553292534acd78ac3aee18033b7624f22026fc (diff)
downloademacs-458401b6ed7a4f78a99e47e4029c4cbf185e1cbf.tar.gz
emacs-458401b6ed7a4f78a99e47e4029c4cbf185e1cbf.zip
Real initial revision. (rewrite from hanoi-break.)
-rw-r--r--lisp/type-break.el240
1 files changed, 192 insertions, 48 deletions
diff --git a/lisp/type-break.el b/lisp/type-break.el
index d25a67ae083..47da688ad0c 100644
--- a/lisp/type-break.el
+++ b/lisp/type-break.el
@@ -1,65 +1,209 @@
1;;; type-break.el --- take breaks from typing
2
3;;; Copyright (C) 1994 Roland McGrath
4;;; Copyright (C) 1994 Noah S. Friedman
5
6;;; Author: Noah Friedman <friedman@prep.ai.mit.edu>
7;;; Roland McGrath <roland@prep.ai.mit.edu>
8;;; Maintainer: friedman@prep.ai.mit.edu
9;;; Keywords: extensions, timer, RSI, CTS, tendinitis, suffering, pain
10;;; Created: 1994-07-13
11
12;;; $Id$
13
14;;; This program is free software; you can redistribute it and/or modify
15;;; it under the terms of the GNU General Public License as published by
16;;; the Free Software Foundation; either version 2, or (at your option)
17;;; any later version.
18;;;
19;;; This program is distributed in the hope that it will be useful,
20;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22;;; GNU General Public License for more details.
23;;;
24;;; You should have received a copy of the GNU General Public License
25;;; along with this program; if not, you can either send email to this
26;;; program's maintainer or write to: The Free Software Foundation,
27;;; Inc.; 675 Massachusetts Avenue; Cambridge, MA 02139, USA.
28
29;;; Commentary:
30
31;;; Based on Roland McGrath's hanoi-break.el (unreleased).
32;;; The idea for keystroke recording was suggested by
33;;; Mark Ashton <mpashston@gnu.ai.mit.edu>
34
35;;; Code:
36
37
1(require 'timer) 38(require 'timer)
2 39
3;;;###autoload 40;;;###autoload
4(defvar hanoi-break-interval (* 60 30) 41(defvar type-break-interval (* 60 30)
5 "*Number of seconds between Hanoi breaks.") 42 "*Number of seconds between typing breaks.")
43
44;;;###autoload
45(defvar type-break-delay-interval 60
46 "*Number of seconds between queries to take a break, if put off.
47The user will continue to be prompted at this interval until he or she
48finally submits to taking a typing break.")
49
50;; Assuming average typing speed is 45wpm, default this to the average
51;; number of keystrokes one is likely to type in a break interval.
52;; That way if the user goes through a furious burst of typing activity,
53;; cause a typing break to be required sooner than originally scheduled.
54;;;###autoload
55(defvar type-break-keystroke-interval (* 45 (/ type-break-interval 60))
56 "*Number of keystrokes to record before querying for a typing break.
57If not a number, don't keep track of keystrokes.
58
59Actually, this is not the number of keystrokes per se, but the number of
60interactive commands (including self-inserting characters typed).
61Compound key bindings like C-x C-f count as a single command even though
62that consists of multiple keystrokes.")
63
64;;;###autoload
65(defvar type-break-demo-function-vector
66 [type-break-life type-break-hanoi]
67 "*Vector consisting of functions to run as demos during typing breaks.
68When a typing break begins, one of these functions is selected randomly
69to have emacs do something interesting.
6 70
7(add-hook 'post-command-hook 'hanoi-break-check t) 71Any function in this vector should start a demo which ceases as soon as a
72key is pressed.")
8 73
9(defvar hanoi-break-p nil 74;; The original motivation for this variable was that in emacs 19.25 (or
10 "Non-nil if we need a Hanoi break real soon now.") 75;; perhaps just in unreleased versions of emacs 19.26), the function
76;; keyboard.c:safe_run_hooks wasn't reentrant, so that running yes-or-no-p
77;; from a post-command-hook caused the inferior command loop to wipe out
78;; the original value of the hook. That was fixed, but it occured to me
79;; that some people might prefer y-or-n-p.
80;;;###autoload
81(defvar type-break-query-function 'yes-or-no-p
82 "*Function to use for making query for a typing break.
83Usually this will be `yes-or-no-p' or `y-or-n-p'.")
84
85;; The rest are internal variables. Do not set them yourself.
11 86
12(defun hanoi-break-check () 87;; Number of commands (roughly # of keystrokes) recorded since last break.
13 "Take a Hanoi break if the time has come." 88(defvar type-break-keystroke-count 0)
14 (and (not (input-pending-p))
15 (prog1 hanoi-break-p
16 (setq hanoi-break-p nil))
17 (hanoi-break)))
18 89
90;; Non-nil if we need a typing break soon.
91(defvar type-break-p nil)
92
93
19;;;###autoload 94;;;###autoload
20(defun hanoi-break () 95(defun type-break ()
21 "Take a Hanoi break, son." 96 "Take a typing break.
97
98If `type-break-delay-interval' seconds have passed since the last typing
99break, or `type-break-keystroke-interval' keystrokes have been recorded
100since the last typing break, ask the user to take a break now.
101
102The user can refuse by answering \"no\", in which case another query will
103be made in `type-break-delay-interval' seconds.
104
105During the typing break, a demo selected from the functions listed in
106`type-break-demo-function-vector' is run."
22 (interactive) 107 (interactive)
108 (setq type-break-p nil)
109 (setq type-break-keystroke-count 0)
110 (cancel-type-break)
23 (save-window-excursion 111 (save-window-excursion
24 (eval (condition-case error 112 (condition-case ()
25 (if (not (yes-or-no-p "Take a break now? ")) 113 (cond
26 '(hanoi-break-schedule 60) ; Bug him again in one minute. 114 ((funcall type-break-query-function "Take a break from typing now? ")
27 ;; Eat the screen. 115 ;; Eat the screen.
28 (if (eq (selected-window) (minibuffer-window)) 116 (and (eq (selected-window) (minibuffer-window))
29 (other-window 1)) 117 (other-window 1))
30 (delete-other-windows) 118 (delete-other-windows)
31 (scroll-right (window-width)) 119 (scroll-right (window-width))
32 ;; Send him on his way. 120 (message "Take a break from typing.")
33 (message "Take a break, son.") 121 (type-break-select)
34 (if (get-buffer "*Hanoi*") 122 (type-break-schedule))
35 (kill-buffer "*Hanoi*")) 123 (t
36 (condition-case () 124 (type-break-schedule type-break-delay-interval)))
37 (progn 125 (quit
38 (hanoi (/ (window-width) 8)) 126 (type-break-schedule type-break-delay-interval)))))
39 ;; Wait for him to come back. 127
40 (read-char) 128(defun type-break-select ()
41 (kill-buffer "*Hanoi*")) 129 (random t)
42 (quit nil)) 130 (let* ((len (length type-break-demo-function-vector))
43 '(hanoi-break-schedule)) ; Schedule next break. 131 (idx (random len))
44 (quit '(hanoi-break-schedule 60)) ; Bug him again in one minute. 132 (fn (aref type-break-demo-function-vector idx)))
45 ;;(error t) 133 (condition-case ()
46 )))) 134 (funcall fn)
135 (error nil))))
47 136
137
48;;;###autoload 138;;;###autoload
49(defun hanoi-break-schedule (&optional time) 139(defun type-break-schedule (&optional time)
50 "Schedule a break for ARG seconds from now (default: hanoi-break-interval)." 140 "Schedule a typing break TIME seconds from now.
141If time is not specified, default to type-break-interval."
51 (interactive (list (and current-prefix-arg 142 (interactive (list (and current-prefix-arg
52 (prefix-numeric-value current-prefix-arg)))) 143 (prefix-numeric-value current-prefix-arg))))
53 (or time (setq time hanoi-break-interval)) 144 (or time (setq time type-break-interval))
54 (run-at-time time nil 'hanoi-break-soon)) 145 ;; Remove any old scheduled break
146 (cancel-type-break)
147 (run-at-time time nil 'type-break-soon))
55 148
56(defun hanoi-break-soon () 149(defun cancel-type-break ()
57 "Take a Hanoi break very soon." 150 "Cancel scheduled typing breaks."
58 (setq hanoi-break-p t))
59
60(defun cancel-hanoi-break ()
61 "Cancel scheduled Hanoi breaks."
62 (interactive) 151 (interactive)
63 (cancel-function-timers 'hanoi-break-soon)) 152 (let ((timer-dont-exit t))
153 (cancel-function-timers 'type-break-soon)))
154
155(defun type-break-soon ()
156 "Take a typing break very soon."
157 (setq type-break-p t))
158
159(defun type-break-check ()
160 "Take a typing break if the time has come."
161 (setq type-break-keystroke-count (1+ type-break-keystroke-count))
162 (cond
163 ((input-pending-p))
164 ((or type-break-p
165 (and (natnump type-break-keystroke-interval)
166 (> type-break-keystroke-count type-break-keystroke-interval)))
167 (type-break))))
168
169
170;; This is a wrapper around hanoi that calls it with an arg large enough to
171;; make the largest discs possible that will fit in the window.
172;; Also, clean up the *Hanoi* buffer after we're done.
173(defun type-break-hanoi ()
174 "Take a hanoiing typing break."
175 (and (get-buffer "*Hanoi*")
176 (kill-buffer "*Hanoi*"))
177 (condition-case ()
178 (progn
179 (hanoi (/ (window-width) 8))
180 ;; Wait for user to come back.
181 (read-char)
182 (kill-buffer "*Hanoi*"))
183 (quit
184 (and (get-buffer "*Hanoi*")
185 (kill-buffer "*Hanoi*")))))
186
187;; This is a wrapper around life that calls it with a `sleep' arg to make
188;; it run a little more leisurely.
189;; Also, clean up the *Life* buffer after we're done.
190(defun type-break-life ()
191 "Take a typing break and get a life."
192 (and (get-buffer "*Life*")
193 (kill-buffer "*Life*"))
194 (condition-case ()
195 (progn
196 (life 3)
197 ;; Wait for user to come back.
198 (read-char)
199 (kill-buffer "*Life*"))
200 (quit
201 (and (get-buffer "*Life*")
202 (kill-buffer "*Life*")))))
203
204
205(provide 'type-break)
206
207(add-hook 'post-command-hook 'type-break-check 'append)
64 208
65(provide 'hanoi-break) 209;;; type-break.el ends here