guile feature
[bpt/emacs.git] / lisp / calendar / timeclock.el
index 9b766e1..2b4db9a 100644 (file)
@@ -1,6 +1,6 @@
 ;;; timeclock.el --- mode for keeping track of how much you work
 
-;; Copyright (C) 1999-201 Free Software Foundation, Inc.
+;; Copyright (C) 1999-2014 Free Software Foundation, Inc.
 
 ;; Author: John Wiegley <johnw@gnu.org>
 ;; Created: 25 Mar 1999
 ;;   (define-key ctl-x-map "to" 'timeclock-out)
 ;;   (define-key ctl-x-map "tc" 'timeclock-change)
 ;;   (define-key ctl-x-map "tr" 'timeclock-reread-log)
-;;   (define-key ctl-x-map "tu" 'timeclock-update-modeline)
+;;   (define-key ctl-x-map "tu" 'timeclock-update-mode-line)
 ;;   (define-key ctl-x-map "tw" 'timeclock-when-to-leave-string)
 
 ;; If you want Emacs to display the amount of time "left" to your
-;; workday in the modeline, you can either set the value of
-;; `timeclock-modeline-display' to t using M-x customize, or you
-;; can add this code to your .emacs file:
+;; workday in the mode-line, you can either set the value of
+;; `timeclock-mode-line-display' to t using M-x customize, or you can
+;; add this code to your init file:
 ;;
 ;;   (require 'timeclock)
-;;   (timeclock-modeline-display)
+;;   (timeclock-mode-line-display)
 ;;
-;; To cancel this modeline display at any time, just call
-;; `timeclock-modeline-display' again.
+;; To cancel this mode line display at any time, just call
+;; `timeclock-mode-line-display' again.
 
 ;; You may also want Emacs to ask you before exiting, if you are
 ;; currently working on a project.  This can be done either by setting
 ;; `timeclock-ask-before-exiting' to t using M-x customize (this is
-;; the default), or by adding the following to your .emacs file:
+;; the default), or by adding the following to your init file:
 ;;
 ;;   (add-hook 'kill-emacs-query-functions 'timeclock-query-out)
 
-;; NOTE: If you change your .timelog file without using timeclock's
+;; NOTE: If you change your timelog file without using timeclock's
 ;; functions, or if you change the value of any of timeclock's
 ;; customizable variables, you should run the command
 ;; `timeclock-reread-log'.  This will recompute any discrepancies in
@@ -81,8 +81,9 @@
 
 ;;; User Variables:
 
-(defcustom timeclock-file (convert-standard-filename "~/.timelog")
+(defcustom timeclock-file (locate-user-emacs-file "timelog" ".timelog")
   "The file used to store timeclock data in."
+  :version "24.4"                      ; added locate-user-emacs-file
   :type 'file
   :group 'timeclock)
 
@@ -98,7 +99,7 @@ work four hours on Monday, then the amount of time \"remaining\" on
 Tuesday is twelve hours -- relative to an averaged work period of
 eight hours -- or eight hours, non-relative.  So relative time takes
 into account any discrepancy of time under-worked or over-worked on
-previous days.  This only affects the timeclock modeline display."
+previous days.  This only affects the timeclock mode line display."
   :type 'boolean
   :group 'timeclock)
 
@@ -136,7 +137,7 @@ This variable only has effect if set with \\[customize]."
         (if value
             (add-hook 'kill-emacs-query-functions 'timeclock-query-out)
           (remove-hook 'kill-emacs-query-functions 'timeclock-query-out))
-        (setq timeclock-ask-before-exiting value))
+        (set symbol value))
   :type 'boolean
   :group 'timeclock)
 
@@ -145,40 +146,41 @@ This variable only has effect if set with \\[customize]."
 
 ;; For byte-compiler.
 (defvar display-time-hook)
-(defvar timeclock-modeline-display)
+(defvar timeclock-mode-line-display)
 
 (defcustom timeclock-use-display-time t
-  "If non-nil, use `display-time-hook' for doing modeline updates.
+  "If non-nil, use `display-time-hook' for doing mode line updates.
 The advantage of this is that one less timer has to be set running
-amok in Emacs' process space.  The disadvantage is that it requires
+amok in Emacs's process space.  The disadvantage is that it requires
 you to have `display-time' running.  If you don't want to use
-`display-time', but still want the modeline to show how much time is
+`display-time', but still want the mode line to show how much time is
 left, set this variable to nil.  Changing the value of this variable
-while timeclock information is being displayed in the modeline has no
-effect.  You should call the function `timeclock-modeline-display' with
+while timeclock information is being displayed in the mode line has no
+effect.  You should call the function `timeclock-mode-line-display' with
 a positive argument to force an update."
   :set (lambda (symbol value)
         (let ((currently-displaying
-               (and (boundp 'timeclock-modeline-display)
-                    timeclock-modeline-display)))
+               (and (boundp 'timeclock-mode-line-display)
+                    timeclock-mode-line-display)))
           ;; if we're changing to the state that
-          ;; `timeclock-modeline-display' is already using, don't
+          ;; `timeclock-mode-line-display' is already using, don't
           ;; bother toggling it.  This happens on the initial loading
           ;; of timeclock.el.
           (if (and currently-displaying
                    (or (and value
                             (boundp 'display-time-hook)
-                            (memq 'timeclock-update-modeline
+                            (memq 'timeclock-update-mode-line
                                   display-time-hook))
                        (and (not value)
                             timeclock-update-timer)))
               (setq currently-displaying nil))
           (and currently-displaying
-               (set-variable 'timeclock-modeline-display nil))
-          (setq timeclock-use-display-time value)
+               (setq timeclock-mode-line-display nil))
+          (set symbol value)
           (and currently-displaying
-               (set-variable 'timeclock-modeline-display t))
-          timeclock-use-display-time))
+               (setq timeclock-mode-line-display t))
+           ;; FIXME: The return value isn't used, AFAIK!
+          value))
   :type 'boolean
   :group 'timeclock
   :require 'time)
@@ -205,7 +207,7 @@ to today."
 (defcustom timeclock-day-over-hook nil
   "A hook that is run when the workday has been completed.
 This hook is only run if the current time remaining is being displayed
-in the modeline.  See the variable `timeclock-modeline-display'."
+in the mode line.  See the variable `timeclock-mode-line-display'."
   :type 'hook
   :group 'timeclock)
 
@@ -251,7 +253,7 @@ worked so far today.  Also, if `timeclock-relative' is nil, this value
 will be the same as `timeclock-discrepancy'.")
 
 (defvar timeclock-use-elapsed nil
-  "Non-nil if the modeline should display time elapsed, not remaining.")
+  "Non-nil if the mode line should display time elapsed, not remaining.")
 
 (defvar timeclock-last-period nil
   "Integer representing the number of seconds in the last period.
@@ -259,7 +261,7 @@ Note that you shouldn't access this value, but instead should use the
 function `timeclock-last-period'.")
 
 (defvar timeclock-mode-string nil
-  "The timeclock string (optionally) displayed in the modeline.
+  "The timeclock string (optionally) displayed in the mode line.
 The time is bracketed by <> if you are clocked in, otherwise by [].")
 
 (defvar timeclock-day-over nil
@@ -267,68 +269,56 @@ The time is bracketed by <> if you are clocked in, otherwise by [].")
 
 ;;; User Functions:
 
+(define-obsolete-function-alias 'timeclock-modeline-display
+  'timeclock-mode-line-display "24.3")
+(define-obsolete-variable-alias 'timeclock-modeline-display
+  'timeclock-mode-line-display "24.3")
+
 ;;;###autoload
-(defun timeclock-modeline-display (&optional arg)
-  "Toggle display of the amount of time left today in the modeline.
+(define-minor-mode timeclock-mode-line-display
+  "Toggle display of the amount of time left today in the mode line.
 If `timeclock-use-display-time' is non-nil (the default), then
-the function `display-time-mode' must be active, and the modeline
+the function `display-time-mode' must be active, and the mode line
 will be updated whenever the time display is updated.  Otherwise,
 the timeclock will use its own sixty second timer to do its
-updating.  With prefix ARG, turn modeline display on if and only
-if ARG is positive.  Returns the new status of timeclock modeline
+updating.  With prefix ARG, turn mode line display on if and only
+if ARG is positive.  Returns the new status of timeclock mode line
 display (non-nil means on)."
-  (interactive "P")
+  :global t
   ;; cf display-time-mode.
   (setq timeclock-mode-string "")
   (or global-mode-string (setq global-mode-string '("")))
-  (let ((on-p (if arg
-                 (> (prefix-numeric-value arg) 0)
-               (not timeclock-modeline-display))))
-    (if on-p
-        (progn
-          (or (memq 'timeclock-mode-string global-mode-string)
-              (setq global-mode-string
-                    (append global-mode-string '(timeclock-mode-string))))
-         (unless (memq 'timeclock-update-modeline timeclock-event-hook)
-           (add-hook 'timeclock-event-hook 'timeclock-update-modeline))
-         (when timeclock-update-timer
-           (cancel-timer timeclock-update-timer)
-           (setq timeclock-update-timer nil))
-         (if (boundp 'display-time-hook)
-             (remove-hook 'display-time-hook 'timeclock-update-modeline))
-         (if timeclock-use-display-time
-              (progn
-                ;; Update immediately so there is a visible change
-                ;; on calling this function.
-                (if display-time-mode (timeclock-update-modeline)
-                  (message "Activate `display-time-mode' or turn off \
+  (if timeclock-mode-line-display
+      (progn
+        (or (memq 'timeclock-mode-string global-mode-string)
+            (setq global-mode-string
+                  (append global-mode-string '(timeclock-mode-string))))
+        (add-hook 'timeclock-event-hook 'timeclock-update-mode-line)
+        (when timeclock-update-timer
+          (cancel-timer timeclock-update-timer)
+          (setq timeclock-update-timer nil))
+        (if (boundp 'display-time-hook)
+            (remove-hook 'display-time-hook 'timeclock-update-mode-line))
+        (if timeclock-use-display-time
+            (progn
+              ;; Update immediately so there is a visible change
+              ;; on calling this function.
+              (if display-time-mode
+                  (timeclock-update-mode-line)
+                (message "Activate `display-time-mode' or turn off \
 `timeclock-use-display-time' to see timeclock information"))
-                (add-hook 'display-time-hook 'timeclock-update-modeline))
-           (setq timeclock-update-timer
-                 (run-at-time nil 60 'timeclock-update-modeline))))
-      (setq global-mode-string
-           (delq 'timeclock-mode-string global-mode-string))
-      (remove-hook 'timeclock-event-hook 'timeclock-update-modeline)
-      (if (boundp 'display-time-hook)
-         (remove-hook 'display-time-hook
-                      'timeclock-update-modeline))
-      (when timeclock-update-timer
-       (cancel-timer timeclock-update-timer)
-       (setq timeclock-update-timer nil)))
-    (force-mode-line-update)
-    (setq timeclock-modeline-display on-p)))
-
-;; This has to be here so that the function definition of
-;; `timeclock-modeline-display' is known to the "set" function.
-(defcustom timeclock-modeline-display nil
-  "Toggle modeline display of time remaining.
-You must modify via \\[customize] for this variable to have an effect."
-  :set (lambda (symbol value)
-        (setq timeclock-modeline-display
-              (timeclock-modeline-display (or value 0))))
-  :type 'boolean
-  :group 'timeclock
-  :require 'timeclock)
+              (add-hook 'display-time-hook 'timeclock-update-mode-line))
+          (setq timeclock-update-timer
+                (run-at-time nil 60 'timeclock-update-mode-line))))
+    (setq global-mode-string
+          (delq 'timeclock-mode-string global-mode-string))
+    (remove-hook 'timeclock-event-hook 'timeclock-update-mode-line)
+    (if (boundp 'display-time-hook)
+        (remove-hook 'display-time-hook
+                     'timeclock-update-mode-line))
+    (when timeclock-update-timer
+      (cancel-timer timeclock-update-timer)
+      (setq timeclock-update-timer nil))))
 
 (defsubst timeclock-time-to-date (time)
   "Convert the TIME value to a textual date string."
@@ -477,8 +467,8 @@ Returns the new value of `timeclock-discrepancy'."
   (interactive)
   (setq timeclock-discrepancy nil)
   (timeclock-find-discrep)
-  (if (and timeclock-discrepancy timeclock-modeline-display)
-      (timeclock-update-modeline))
+  (if (and timeclock-discrepancy timeclock-mode-line-display)
+      (timeclock-update-mode-line))
   timeclock-discrepancy)
 
 (defun timeclock-seconds-to-string (seconds &optional show-seconds
@@ -645,8 +635,11 @@ arguments of `completing-read'."
   (timeclock-completing-read "Reason for clocking out: "
                             (mapcar 'list timeclock-reason-list)))
 
-(defun timeclock-update-modeline ()
-  "Update the `timeclock-mode-string' displayed in the modeline.
+(define-obsolete-function-alias 'timeclock-update-modeline
+  'timeclock-update-mode-line "24.3")
+
+(defun timeclock-update-mode-line ()
+  "Update the `timeclock-mode-string' displayed in the mode line.
 The value of `timeclock-relative' affects the display as described in
 that variable's documentation."
   (interactive)
@@ -826,25 +819,24 @@ This is only provided for coherency when used by
   "Return a list of all the projects in DAY."
   (timeclock-entry-list-projects (cddr day)))
 
-(defmacro timeclock-day-list-template (func)
+(defun timeclock-day-list-template (func day-list)
   "Template for summing the result of FUNC on each element of DAY-LIST."
-  `(let ((length 0))
-     (while day-list
-       (setq length (+ length (,(eval func) (car day-list)))
-            day-list (cdr day-list)))
-     length))
+  (let ((length 0))
+    (dolist (day day-list)
+      (setq length (+ length (funcall func day))))
+    length))
 
 (defun timeclock-day-list-required (day-list)
   "Return total required length of DAY-LIST, in seconds."
-  (timeclock-day-list-template 'timeclock-day-required))
+  (timeclock-day-list-template #'timeclock-day-required day-list))
 
 (defun timeclock-day-list-length (day-list)
   "Return actual length of DAY-LIST, in seconds."
-  (timeclock-day-list-template 'timeclock-day-length))
+  (timeclock-day-list-template #'timeclock-day-length day-list))
 
 (defun timeclock-day-list-debt (day-list)
   "Return total debt (required - actual) of DAY-LIST."
-  (timeclock-day-list-template 'timeclock-day-debt))
+  (timeclock-day-list-template #'timeclock-day-debt day-list))
 
 (defsubst timeclock-day-list-begin (day-list)
   "Return the start time of DAY-LIST."
@@ -856,11 +848,11 @@ This is only provided for coherency when used by
 
 (defun timeclock-day-list-span (day-list)
   "Return the span of DAY-LIST."
-  (timeclock-day-list-template 'timeclock-day-span))
+  (timeclock-day-list-template #'timeclock-day-span day-list))
 
 (defun timeclock-day-list-break (day-list)
   "Return the total break of DAY-LIST."
-  (timeclock-day-list-template 'timeclock-day-break))
+  (timeclock-day-list-template #'timeclock-day-break day-list))
 
 (defun timeclock-day-list-projects (day-list)
   "Return a list of all the projects in DAY-LIST."