;;; timeclock.el --- mode for keeping track of how much you work
-;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-;; 2008 Free Software Foundation, Inc.
+;; Copyright (C) 1999-2011 Free Software Foundation, Inc.
;; Author: John Wiegley <johnw@gnu.org>
;; Created: 25 Mar 1999
;; This file is part of GNU Emacs.
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
60 60.0) 60))))))
(timeclock-log "i" (or project
(and timeclock-get-project-function
- (or find-project (interactive-p))
+ (or find-project
+ (called-interactively-p 'interactive))
(funcall timeclock-get-project-function))))
(run-hooks 'timeclock-in-hook)))
(if arg "O" "o")
(or reason
(and timeclock-get-reason-function
- (or find-reason (interactive-p))
+ (or find-reason (called-interactively-p 'interactive))
(funcall timeclock-get-reason-function))))
(run-hooks 'timeclock-out-hook)
(if arg
(if (> remainder 0)
"remaining" "over")
(timeclock-when-to-leave-string show-seconds today-only)))
- (if (interactive-p)
+ (if (called-interactively-p 'interactive)
(message "%s" status)
status)))
working on."
(interactive "P")
(timeclock-out arg)
- (timeclock-in nil project (interactive-p)))
+ (timeclock-in nil project (called-interactively-p 'interactive)))
;;;###autoload
(defun timeclock-query-out ()
(let ((string (timeclock-seconds-to-string
(timeclock-workday-remaining today-only)
show-seconds t)))
- (if (interactive-p)
+ (if (called-interactively-p 'interactive)
(message "%s" string)
string)))
(interactive)
(let ((string (timeclock-seconds-to-string (timeclock-workday-elapsed)
show-seconds)))
- (if (interactive-p)
+ (if (called-interactively-p 'interactive)
(message "%s" string)
string)))
-(defsubst timeclock-time-to-seconds (time)
- "Convert TIME to a floating point number."
- (+ (* (car time) 65536.0)
- (cadr time)
- (/ (or (car (cdr (cdr time))) 0) 1000000.0)))
+(defalias 'timeclock-time-to-seconds (if (fboundp 'float-time) 'float-time
+ 'time-to-seconds))
-(defsubst timeclock-seconds-to-time (seconds)
- "Convert SECONDS (a floating point number) to an Emacs time structure."
- (list (floor seconds 65536)
- (floor (mod seconds 65536))
- (floor (* (- seconds (ffloor seconds)) 1000000))))
+(defalias 'timeclock-seconds-to-time 'seconds-to-time)
;; Should today-only be removed in favour of timeclock-relative? - gm
(defsubst timeclock-when-to-leave (&optional today-only)
(if show-seconds
(format-time-string "%-I:%M:%S %p" then)
(format-time-string "%-I:%M %p" then))))
- (if (interactive-p)
+ (if (called-interactively-p 'interactive)
(message "%s" string)
string)))
arguments of `completing-read'."
(if (featurep 'xemacs)
(let ((str (completing-read prompt alist)))
- (if (or (null str) (= (length str) 0))
+ (if (or (null str) (zerop (length str)))
default
str))
(completing-read prompt alist nil nil nil nil default)))
(defsubst timeclock-day-projects (day)
"Return a list of all the projects in DAY."
- (timeclock-entry-list-projects (cdr day)))
+ (timeclock-entry-list-projects (cddr day)))
(defmacro timeclock-day-list-template (func)
"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))))
- (setq day-list (cdr day-list)))
+ (setq length (+ length (,(eval func) (car day-list)))
+ day-list (cdr day-list)))
length))
(defun timeclock-day-list-required (day-list)
timeclock-current-debt LOG-DATA
See the documentation for the given function if more info is needed."
- (let* ((log-data (list 0.0 nil nil))
- (now (current-time))
- (todays-date (timeclock-time-to-date now))
- last-date-limited last-date-seconds last-date
- (line 0) last beg day entry event)
+ (let ((log-data (list 0.0 nil nil))
+ (now (current-time))
+ last-date-limited last-date-seconds last-date
+ (line 0) last beg day entry event)
(with-temp-buffer
(insert-file-contents (or filename timeclock-file))
(when recent-only
(if (null proj)
(setcar (cddr log-data)
(cons (cons desc (list entry))
- (car (cddr log-data))))
+ (nth 2 log-data)))
(nconc (cdr proj) (list entry)))))))
(forward-line))
(if day
(let* ((now (current-time))
(todays-date (timeclock-time-to-date now))
(first t) (accum 0) (elapsed 0)
- event beg last-date avg
+ event beg last-date
last-date-limited last-date-seconds)
(unless timeclock-discrepancy
(when (file-readable-p timeclock-file)
"Compute the arithmetic mean of the values in the list L."
(let ((total 0)
(count 0))
- (while l
- (setq total (+ total (car l))
- count (1+ count)
- l (cdr l)))
- (if (> count 0)
- (/ total count)
- 0)))
+ (dolist (thisl l)
+ (setq total (+ total thisl)
+ count (1+ count)))
+ (if (zerop count)
+ 0
+ (/ total count))))
(defun timeclock-generate-report (&optional html-p)
"Generate a summary report based on the current timelog file.
done)
(if (timeclock-currently-in-p)
(insert "IN")
- (if (or (null project) (= (length project) 0))
+ (if (zerop (length project))
(progn (insert "Done Working Today")
(setq done t))
(insert "OUT")))
(lengths (vector '(0 0) thirty-days-ago three-months-ago
six-months-ago one-year-ago)))
;; collect statistics from complete timelog
- (while day-list
+ (dolist (day day-list)
(let ((i 0) (l 5))
(while (< i l)
(unless (time-less-p
- (timeclock-day-begin (car day-list))
+ (timeclock-day-begin day)
(aref lengths i))
(let ((base (timeclock-time-to-seconds
(timeclock-day-base
- (timeclock-day-begin (car day-list))))))
+ (timeclock-day-begin day)))))
(nconc (aref time-in i)
(list (- (timeclock-time-to-seconds
- (timeclock-day-begin (car day-list)))
+ (timeclock-day-begin day))
base)))
- (let ((span (timeclock-day-span (car day-list)))
- (len (timeclock-day-length (car day-list)))
- (req (timeclock-day-required (car day-list))))
+ (let ((span (timeclock-day-span day))
+ (len (timeclock-day-length day))
+ (req (timeclock-day-required day)))
;; If the day's actual work length is less than
;; 70% of its span, then likely the exit time
;; and break amount are not worthwhile adding to
(> (/ (float len) (float span)) 0.70))
(nconc (aref time-out i)
(list (- (timeclock-time-to-seconds
- (timeclock-day-end (car day-list)))
+ (timeclock-day-end day))
base)))
(nconc (aref breaks i) (list (- span len))))
(if req
(setq len (+ len (- timeclock-workday req))))
(nconc (aref workday i) (list len)))))
- (setq i (1+ i))))
- (setq day-list (cdr day-list)))
+ (setq i (1+ i)))))
;; average statistics
(let ((i 0) (l 5))
(while (< i l)
(if (file-readable-p timeclock-file)
(timeclock-reread-log))
-;; arch-tag: a0be3377-deb6-44ec-b9a2-a7be28436a40
;;; timeclock.el ends here