;;; timeclock.el --- mode for keeping track of how much you work
-;; Copyright (C) 1999-2012 Free Software Foundation, Inc.
+;; Copyright (C) 1999-2015 Free Software Foundation, Inc.
;; Author: John Wiegley <johnw@gnu.org>
;; Created: 25 Mar 1999
;;
;; (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
;;; 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)
(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)
timeclock-update-timer)))
(setq currently-displaying nil))
(and currently-displaying
- (set-variable 'timeclock-mode-line-display nil))
- (setq timeclock-use-display-time value)
+ (setq timeclock-mode-line-display nil))
+ (set symbol value)
(and currently-displaying
- (set-variable 'timeclock-mode-line-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)
(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-mode-line-display (&optional arg)
+(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 mode line
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-mode-line-display))))
- (if on-p
- (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 \
+ (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-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)))
- (force-mode-line-update)
- (setq timeclock-mode-line-display on-p)))
-
-;; This has to be here so that the function definition of
-;; `timeclock-mode-line-display' is known to the "set" function.
-(defcustom timeclock-mode-line-display nil
- "Toggle mode line display of time remaining.
-You must modify via \\[customize] for this variable to have an effect."
- :set (lambda (symbol value)
- (setq timeclock-mode-line-display
- (timeclock-mode-line-display (or value 0))))
- :type 'boolean
- :group 'timeclock
- :require 'timeclock)
-
-(defsubst timeclock-time-to-date (time)
+ (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 (&optional time)
"Convert the TIME value to a textual date string."
(format-time-string "%Y/%m/%d" time))
(unless (and timeclock-last-event
(equal (timeclock-time-to-date
(cadr timeclock-last-event))
- (timeclock-time-to-date (current-time))))
+ (timeclock-time-to-date)))
(let ((workday (or (and (numberp arg) arg)
(and arg 0)
(and timeclock-get-workday-function
If TODAY-ONLY is non-nil, the value returned will be relative only to
the time worked today, and not to past time."
(timeclock-seconds-to-time
- (- (timeclock-time-to-seconds (current-time))
+ (- (timeclock-time-to-seconds)
(let ((discrep (timeclock-find-discrep)))
(if discrep
(if today-only
(if timeclock-use-elapsed
(timeclock-workday-elapsed)
(timeclock-workday-remaining (not timeclock-relative))))
- (last-in (equal (car timeclock-last-event) "i")))
+ (last-in (equal (car timeclock-last-event) "i"))
+ (todays-date (timeclock-time-to-date)))
(when (and (< remainder 0)
(not (and timeclock-day-over
- (equal timeclock-day-over
- (timeclock-time-to-date
- (current-time))))))
- (setq timeclock-day-over
- (timeclock-time-to-date (current-time)))
+ (equal timeclock-day-over todays-date))))
+ (setq timeclock-day-over todays-date)
(run-hooks 'timeclock-day-over-hook))
(setq timeclock-mode-string
(propertize
This is only provided for coherency when used by
`timeclock-discrepancy'."
(if (equal (car timeclock-last-event) "i")
- (- (timeclock-time-to-seconds (or moment (current-time)))
- (timeclock-time-to-seconds
- (cadr timeclock-last-event)))
+ (- (timeclock-time-to-seconds moment)
+ (timeclock-time-to-seconds (cadr timeclock-last-event)))
timeclock-last-period))
(defsubst timeclock-entry-length (entry)
"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."
(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."
(+ timeclock-last-period timeclock-elapsed)))))
(setq timeclock-last-event event
timeclock-last-event-workday
- (if (equal (timeclock-time-to-date now) last-date-limited)
+ (if (equal todays-date last-date-limited)
last-date-seconds
timeclock-workday))
(forward-line))
(defun timeclock-day-base (&optional time)
"Given a time within a day, return 0:0:0 within that day.
If optional argument TIME is non-nil, use that instead of the current time."
- (let ((decoded (decode-time (or time (current-time)))))
+ (let ((decoded (decode-time time)))
(setcar (nthcdr 0 decoded) 0)
(setcar (nthcdr 1 decoded) 0)
(setcar (nthcdr 2 decoded) 0)