diff options
| author | Noah Friedman | 1994-07-14 12:10:27 +0000 |
|---|---|---|
| committer | Noah Friedman | 1994-07-14 12:10:27 +0000 |
| commit | 458401b6ed7a4f78a99e47e4029c4cbf185e1cbf (patch) | |
| tree | 28b5ad44c1588ef99d307fcd21ed6b4fa0f44805 | |
| parent | 68553292534acd78ac3aee18033b7624f22026fc (diff) | |
| download | emacs-458401b6ed7a4f78a99e47e4029c4cbf185e1cbf.tar.gz emacs-458401b6ed7a4f78a99e47e4029c4cbf185e1cbf.zip | |
Real initial revision. (rewrite from hanoi-break.)
| -rw-r--r-- | lisp/type-break.el | 240 |
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. | ||
| 47 | The user will continue to be prompted at this interval until he or she | ||
| 48 | finally 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. | ||
| 57 | If not a number, don't keep track of keystrokes. | ||
| 58 | |||
| 59 | Actually, this is not the number of keystrokes per se, but the number of | ||
| 60 | interactive commands (including self-inserting characters typed). | ||
| 61 | Compound key bindings like C-x C-f count as a single command even though | ||
| 62 | that 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. | ||
| 68 | When a typing break begins, one of these functions is selected randomly | ||
| 69 | to have emacs do something interesting. | ||
| 6 | 70 | ||
| 7 | (add-hook 'post-command-hook 'hanoi-break-check t) | 71 | Any function in this vector should start a demo which ceases as soon as a |
| 72 | key 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. | ||
| 83 | Usually 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 | |||
| 98 | If `type-break-delay-interval' seconds have passed since the last typing | ||
| 99 | break, or `type-break-keystroke-interval' keystrokes have been recorded | ||
| 100 | since the last typing break, ask the user to take a break now. | ||
| 101 | |||
| 102 | The user can refuse by answering \"no\", in which case another query will | ||
| 103 | be made in `type-break-delay-interval' seconds. | ||
| 104 | |||
| 105 | During 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. |
| 141 | If 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 |