]> code.delx.au - gnu-emacs/blobdiff - lisp/type-break.el
(save-abbrevs, save-some-buffers): Don't ask the user
[gnu-emacs] / lisp / type-break.el
index 1ff6e949ddb2a36d566baf99d64b992a5f254dc9..0598b5a7b60eae797968a3e6e11bce42b58685d1 100644 (file)
@@ -1,14 +1,14 @@
 ;;; type-break.el --- encourage rests from typing at appropriate intervals
 
-;; Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1994, 95, 97, 2000 Free Software Foundation, Inc.
 
-;; Author: Noah Friedman <friedman@prep.ai.mit.edu>
-;; Maintainer: friedman@prep.ai.mit.edu
+;; Author: Noah Friedman
+;; Maintainer: Noah Friedman <friedman@splode.com>
 ;; Keywords: extensions, timers
 ;; Status: Works in GNU Emacs 19.25 or later, some versions of XEmacs
 ;; Created: 1994-07-13
 
-;; $Id$
+;; $Id: type-break.el,v 1.24 2000/07/24 00:49:09 friedman Exp $
 
 ;; This file is part of GNU Emacs.
 
 
 ;; This package was inspired by Roland McGrath's hanoi-break.el.
 ;; Several people contributed feedback and ideas, including
-;;      Roland McGrath <roland@gnu.ai.mit.edu>
-;;      Kleanthes Koniaris <kgk@martigny.ai.mit.edu>
-;;      Mark Ashton <mpashton@gnu.ai.mit.edu>
+;;      Roland McGrath <roland@gnu.org>
+;;      Kleanthes Koniaris <kgk@koniaris.com>
+;;      Mark Ashton <mpashton@gnu.org>
 ;;      Matt Wilding <wilding@cli.com>
 ;;      Robert S. Boyer <boyer@cs.utexas.edu>
 
 ;;; Code:
 
 \f
+(defgroup type-break nil
+  "Encourage the user to take a rest from typing at suitable intervals."
+  :prefix "type-break"
+  :group 'keyboard)
+
 ;;;###autoload
-(defvar type-break-mode nil
-  "*Non-`nil' means typing break mode is enabled.
-See the docstring for the `type-break-mode' command for more information.")
+(defcustom type-break-mode nil
+  "Toggle typing break mode.
+See the docstring for the `type-break-mode' command for more information.
+Setting this variable directly does not take effect;
+use either \\[customize] or the function `type-break-mode'."
+  :set (lambda (symbol value)
+        (type-break-mode (if value 1 -1)))
+  :initialize 'custom-initialize-default
+  :type 'boolean
+  :group 'type-break
+  :require 'type-break)
 
 ;;;###autoload
-(defvar type-break-interval (* 60 60)
-  "*Number of seconds between scheduled typing breaks.")
+(defcustom type-break-interval (* 60 60)
+  "*Number of seconds between scheduled typing breaks."
+  :type 'integer
+  :group 'type-break)
 
 ;;;###autoload
-(defvar type-break-good-rest-interval (/ type-break-interval 6)
+(defcustom type-break-good-rest-interval (/ type-break-interval 6)
   "*Number of seconds of idle time considered to be an adequate typing rest.
 
 When this variable is non-`nil', emacs checks the idle time between
@@ -87,10 +102,12 @@ keystrokes.  If this idle time is long enough to be considered a \"good\"
 rest from typing, then the next typing break is simply rescheduled for later.
 
 If a break is interrupted before this much time elapses, the user will be
-asked whether or not really to interrupt the break.")
+asked whether or not really to interrupt the break."
+  :type 'integer
+  :group 'type-break)
 
 ;;;###autoload
-(defvar type-break-keystroke-threshold
+(defcustom type-break-keystroke-threshold
   ;; Assuming typing speed is 35wpm (on the average, do you really
   ;; type more than that in a minute?  I spend a lot of time reading mail
   ;; and simply studying code in buffers) and average word length is
@@ -105,7 +122,7 @@ asked whether or not really to interrupt the break.")
          (lower (/ upper 5)))
     (cons lower upper))
   "*Upper and lower bound on number of keystrokes for considering typing break.
-This structure is a pair of numbers.
+This structure is a pair of numbers (MIN . MAX).
 
 The first number is the minimum number of keystrokes that must have been
 entered since the last typing break before considering another one, even if
@@ -123,50 +140,74 @@ Keys with bucky bits (shift, control, meta, etc) are counted as only one
 keystroke even though they really require multiple keys to generate them.
 
 The command `type-break-guesstimate-keystroke-threshold' can be used to
-guess a reasonably good pair of values for this variable.")
+guess a reasonably good pair of values for this variable."
+  :type 'sexp
+  :group 'type-break)
 
-(defvar type-break-query-mode t
+(defcustom type-break-query-mode t
   "*Non-`nil' means ask whether or not to prompt user for breaks.
 If so, call the function specified in the value of the variable
-`type-break-query-function' to do the asking.")
+`type-break-query-function' to do the asking."
+  :type 'boolean
+  :group 'type-break)
 
-(defvar type-break-query-function 'yes-or-no-p
-  "Function to use for making query for a typing break.
+(defcustom type-break-query-function 'yes-or-no-p
+  "*Function to use for making query for a typing break.
 It should take a string as an argument, the prompt.
 Usually this should be set to `yes-or-no-p' or `y-or-n-p'.
 
-To avoid being queried at all, set `type-break-query-mode' to `nil'.")
+To avoid being queried at all, set `type-break-query-mode' to `nil'."
+  :type '(radio function
+                (function-item yes-or-no-p)
+                (function-item y-or-n-p))
+  :group 'type-break)
 
-(defvar type-break-query-interval 60
+(defcustom type-break-query-interval 60
   "*Number of seconds between queries to take a break, if put off.
 The user will continue to be prompted at this interval until he or she
-finally submits to taking a typing break.")
+finally submits to taking a typing break."
+  :type 'integer
+  :group 'type-break)
 
-(defvar type-break-time-warning-intervals '(300 120 60 30)
+(defcustom type-break-time-warning-intervals '(300 120 60 30)
   "*List of time intervals for warnings about upcoming typing break.
 At each of the intervals (specified in seconds) away from a scheduled
-typing break, print a warning in the echo area.")
+typing break, print a warning in the echo area."
+  :type '(repeat integer)
+  :group 'type-break)
 
-(defvar type-break-keystroke-warning-intervals '(300 200 100 50)
+(defcustom type-break-keystroke-warning-intervals '(300 200 100 50)
   "*List of keystroke measurements for warnings about upcoming typing break.
 At each of the intervals (specified in keystrokes) away from the upper
 keystroke threshold, print a warning in the echo area.
 If either this variable or the upper threshold is set, then no warnings
-Will occur.")
+will occur."
+  :type '(repeat integer)
+  :group 'type-break)
 
-(defvar type-break-warning-repeat 40
+(defcustom type-break-warning-repeat 40
   "*Number of keystrokes for which warnings should be repeated.
 That is, for each of this many keystrokes the warning is redisplayed
-in the echo area to make sure it's really seen.")
+in the echo area to make sure it's really seen."
+  :type 'integer
+  :group 'type-break)
+
+(defcustom type-break-time-stamp-format "[%H:%M] "
+  "*Timestamp format used to prefix messages.
+Format specifiers are as used by `format-time-string'."
+  :type 'string
+  :group 'type-break)
 
-(defvar type-break-demo-functions
+(defcustom type-break-demo-functions
   '(type-break-demo-boring type-break-demo-life type-break-demo-hanoi)
   "*List of functions to consider running as demos during typing breaks.
 When a typing break begins, one of these functions is selected randomly
 to have emacs do something interesting.
 
 Any function in this list should start a demo which ceases as soon as a
-key is pressed.")
+key is pressed."
+  :type '(repeat function)
+  :group 'type-break)
 
 (defvar type-break-post-command-hook '(type-break-check)
   "Hook run indirectly by post-command-hook for typing break functions.
@@ -180,11 +221,13 @@ remove themselves after running.")
 \f
 ;; Mode line frobs
 
-(defvar type-break-mode-line-message-mode nil
+(defcustom type-break-mode-line-message-mode nil
   "*Non-`nil' means put type-break related messages in the mode line.
 Otherwise, messages typically go in the echo area.
 
-See also `type-break-mode-line-format' and its members.")
+See also `type-break-mode-line-format' and its members."
+  :type 'boolean
+  :group 'type-break)
 
 (defvar type-break-mode-line-format
   '(type-break-mode-line-message-mode
@@ -198,13 +241,14 @@ See also `type-break-mode-line-format' and its members.")
     type-break-mode-line-break-string))
 
 (defvar type-break-mode-line-break-message-p nil)
-(defvar type-break-mode-line-break-string " *** TAKE A TYPING BREAK ***")
+(defvar type-break-mode-line-break-string " *** TAKE A TYPING BREAK NOW ***")
 
 (defvar type-break-mode-line-warning
       '(type-break-mode-line-break-message-p
         ("")
         (type-break-warning-countdown-string
-         (" ***Break in "
+         (" *** "
+          "Break in "
           type-break-warning-countdown-string
           " "
           type-break-warning-countdown-string-type
@@ -247,6 +291,7 @@ It will be either \"seconds\" or \"keystrokes\".")
                  ("\\bLucid\\b"   . lucid)
                  ("^Nemacs\\b"    . nemacs)
                  ("^GNU Emacs 19" . standard19)
+                 ("^GNU Emacs 20" . standard19)
                  ("^GNU Emacs 18" . emacs18)))
         result)
     (while alist
@@ -256,7 +301,7 @@ It will be either \"seconds\" or \"keystrokes\".")
         (setq alist nil))
        (t
         (setq alist (cdr alist)))))
-    (store-match-data data)
+    (set-match-data data)
     (cond ((eq result 'lucid)
            (and (string= emacs-version "19.8 Lucid")
                 (setq result 'lucid-19-8)))
@@ -311,19 +356,19 @@ approximate good values for this.
 There are several variables that affect how or when warning messages about
 imminent typing breaks are displayed.  They include:
 
-        type-break-mode-line-message-mode
-        type-break-time-warning-intervals
-        type-break-keystroke-warning-intervals
-        type-break-warning-repeat
-        type-break-warning-countdown-string
-        type-break-warning-countdown-string-type
+        `type-break-mode-line-message-mode'
+        `type-break-time-warning-intervals'
+        `type-break-keystroke-warning-intervals'
+        `type-break-warning-repeat'
+        `type-break-warning-countdown-string'
+        `type-break-warning-countdown-string-type'
 
 There are several variables that affect if, how, and when queries to begin
 a typing break occur.  They include:
 
-        type-break-query-mode
-        type-break-query-function
-        type-break-query-interval
+        `type-break-query-mode'
+        `type-break-query-function'
+        `type-break-query-interval'
 
 Finally, the command `type-break-statistics' prints interesting things."
   (interactive "P")
@@ -335,26 +380,26 @@ Finally, the command `type-break-statistics' prints interesting things."
     (cond
      ((and already-enabled type-break-mode)
       (and (interactive-p)
-           (message "type-break-mode is already enabled")))
+           (message "Type Break mode is already enabled")))
      (type-break-mode
       (or global-mode-string
           (setq global-mode-string '("")))
-      (or (memq 'type-break-mode-line-format
-                (default-value 'global-mode-string))
-          (setq-default global-mode-string
-                        (nconc (default-value 'global-mode-string)
-                               '(type-break-mode-line-format))))
+      (or (assq 'type-break-mode-line-message-mode
+               minor-mode-alist)
+         (setq minor-mode-alist
+               (cons type-break-mode-line-format
+                     minor-mode-alist)))
       (type-break-keystroke-reset)
       (type-break-mode-line-countdown-or-break nil)
       (type-break-schedule)
       (and (interactive-p)
-           (message "type-break-mode is enabled and reset")))
+           (message "Type Break mode is enabled and reset")))
      (t
       (type-break-keystroke-reset)
       (type-break-mode-line-countdown-or-break nil)
       (type-break-cancel-schedule)
       (and (interactive-p)
-           (message "type-break-mode is disabled")))))
+           (message "Type Break mode is disabled")))))
   type-break-mode)
 
 (defun type-break-mode-line-message-mode (&optional prefix)
@@ -368,10 +413,10 @@ variable of the same name.
 
 Variables controlling the display of messages in the mode line include:
 
-        mode-line-format
-        global-mode-string
-        type-break-mode-line-break-message
-        type-break-mode-line-warning"
+        `mode-line-format'
+        `global-mode-string'
+        `type-break-mode-line-break-message'
+        `type-break-mode-line-warning'"
   (interactive "P")
   (setq type-break-mode-line-message-mode
         (>= (prefix-numeric-value prefix) 0))
@@ -413,6 +458,7 @@ During the break, a demo selected from the functions listed in
 After the typing break is finished, the next break is scheduled
 as per the function `type-break-schedule'."
   (interactive)
+  (do-auto-save)
   (type-break-cancel-schedule)
   (let ((continue t)
         (start-time (current-time)))
@@ -448,7 +494,8 @@ as per the function `type-break-schedule'."
            ; (setq continue nil))
            ((funcall
              type-break-query-function
-             (format "You really ought to rest %s more.  Continue break? "
+             (format "%sYou really ought to rest %s more.  Continue break? "
+                     (type-break-time-stamp)
                      (type-break-format-time (- type-break-good-rest-interval
                                                 break-secs)))))
            (t
@@ -641,8 +688,14 @@ keystroke threshold has been exceeded."
                 ;; which hoses undo or yank-pop (if you happened to be
                 ;; yanking just when the query occurred).
                 (this-command this-command))
+            ;; Cancel schedule to prevent possibility of a second query
+            ;; from taking place before this one has even returned.
+            ;; The condition-case wrapper will reschedule on quit.
+            (type-break-cancel-schedule)
             (funcall type-break-query-function
-                     "Take a break from typing now? "))
+                     (format "%s%s"
+                             (type-break-time-stamp)
+                             "Take a break from typing now? ")))
           (type-break))
          (t
           (type-break-schedule type-break-query-interval)))
@@ -658,7 +711,8 @@ this or ask the user to start one right now."
    (type-break-mode-line-message-mode)
    (t
     (beep t)
-    (message "You should take a typing break now.  Do `M-x type-break'.")
+    (message "%sYou should take a typing break now.  Do `M-x type-break'."
+             (type-break-time-stamp))
     (sit-for 1)
     (beep t)
     ;; return nil so query caller knows to reset reminder, as if user
@@ -683,7 +737,8 @@ this or ask the user to start one right now."
        ((not type-break-mode-line-message-mode)
         ;; Pause for a moment so any previous message can be seen.
         (sit-for 2)
-        (message "Warning: typing break due in %s."
+        (message "%sWarning: typing break due in %s."
+                 (type-break-time-stamp)
                  (type-break-format-time timeleft))
         (setq type-break-time-warning-count
               (1- type-break-time-warning-count))))))
@@ -706,7 +761,8 @@ this or ask the user to start one right now."
      ((memq this-command '(digit-argument universal-argument)))
      ((not type-break-mode-line-message-mode)
       (sit-for 2)
-      (message "Warning: typing break due in %s keystrokes."
+      (message "%sWarning: typing break due in %s keystrokes."
+               (type-break-time-stamp)
                (- (cdr type-break-keystroke-threshold)
                   type-break-keystroke-count))
       (setq type-break-keystroke-warning-count
@@ -854,6 +910,13 @@ FRAC should be the inverse of the fractional value; for example, a value of
 
     (list high low micro)))
 
+(defun type-break-time-stamp (&optional when)
+  (if (fboundp 'format-time-string)
+      (format-time-string type-break-time-stamp-format when)
+    ;; Emacs 19.28 and prior do not have format-time-string.
+    ;; In that case, result is not customizable.  Upgrade today!
+    (format "[%s] " (substring (current-time-string when) 11 16))))
+
 (defun type-break-format-time (secs)
   (let ((mins (/ secs 60)))
     (cond
@@ -1023,4 +1086,7 @@ With optional non-nil ALL, force redisplay of all mode-lines."
 \f
 (provide 'type-break)
 
+(if type-break-mode
+    (type-break-mode 1))
+
 ;;; type-break.el ends here