:group 'timeclock)
(defcustom timeclock-workday (* 8 60 60)
- "The length of a work period."
+ "The length of a work period in seconds."
:type 'integer
:group 'timeclock)
(defun timeclock-in (&optional arg project find-project)
"Clock in, recording the current time moment in the timelog.
With a numeric prefix ARG, record the fact that today has only that
-many hours in it to be worked. If arg is a non-numeric prefix arg
+many hours in it to be worked. If ARG is a non-numeric prefix argument
\(non-nil, but not a number), 0 is assumed (working on a holiday or
weekend). *If not called interactively, ARG should be the number of
_seconds_ worked today*. This feature only has effect the first time
OLD-DEFAULT hours are set for every day that has no number indicated."
(interactive "P")
(if old-default (setq old-default (prefix-numeric-value old-default))
- (error "timelog-make-hours-explicit requires an explicit argument"))
+ (error "`timelog-make-hours-explicit' requires an explicit argument"))
(let ((extant-timelog (find-buffer-visiting timeclock-file))
current-date)
(with-current-buffer (find-file-noselect timeclock-file t)
(defvar timeclock-last-project nil)
(defun timeclock-completing-read (prompt alist &optional default)
- "A version of `completing-read' that works on both Emacs and XEmacs."
+ "A version of `completing-read' that works on both Emacs and XEmacs.
+PROMPT, ALIST and DEFAULT are used for the PROMPT, COLLECTION and DEF
+arguments of `completing-read'."
(if (featurep 'xemacs)
(let ((str (completing-read prompt alist)))
(if (or (null str) (= (length str) 0))
timeclock-last-period))
(defsubst timeclock-entry-length (entry)
+ "Return the length of ENTRY in seconds."
(- (timeclock-time-to-seconds (cadr entry))
(timeclock-time-to-seconds (car entry))))
(defsubst timeclock-entry-begin (entry)
+ "Return the start time of ENTRY."
(car entry))
(defsubst timeclock-entry-end (entry)
+ "Return the end time of ENTRY."
(cadr entry))
(defsubst timeclock-entry-project (entry)
+ "Return the project of ENTRY."
(nth 2 entry))
(defsubst timeclock-entry-comment (entry)
+ "Return the comment of ENTRY."
(nth 3 entry))
-
(defsubst timeclock-entry-list-length (entry-list)
+ "Return the total length of ENTRY-LIST in seconds."
(let ((length 0))
- (while entry-list
- (setq length (+ length (timeclock-entry-length (car entry-list))))
- (setq entry-list (cdr entry-list)))
+ (dolist (entry entry-list)
+ (setq length (+ length (timeclock-entry-length entry))))
length))
(defsubst timeclock-entry-list-begin (entry-list)
+ "Return the start time of the first element of ENTRY-LIST."
(timeclock-entry-begin (car entry-list)))
(defsubst timeclock-entry-list-end (entry-list)
+ "Return the end time of the last element of ENTRY-LIST."
(timeclock-entry-end (car (last entry-list))))
(defsubst timeclock-entry-list-span (entry-list)
+ "Return the total time in seconds spanned by ENTRY-LIST."
(- (timeclock-time-to-seconds (timeclock-entry-list-end entry-list))
(timeclock-time-to-seconds (timeclock-entry-list-begin entry-list))))
(defsubst timeclock-entry-list-break (entry-list)
+ "Return the total break time (span - length) in ENTRY-LIST."
(- (timeclock-entry-list-span entry-list)
(timeclock-entry-list-length entry-list)))
(defsubst timeclock-entry-list-projects (entry-list)
- (let (projects)
- (while entry-list
- (let ((project (timeclock-entry-project (car entry-list))))
- (if projects
- (add-to-list 'projects project)
- (setq projects (list project))))
- (setq entry-list (cdr entry-list)))
+ "Return a list of all the projects in ENTRY-LIST."
+ (let (projects proj)
+ (dolist (entry entry-list)
+ (setq proj (timeclock-entry-project entry))
+ (if projects
+ (add-to-list 'projects proj)
+ (setq projects (list proj))))
projects))
-
(defsubst timeclock-day-required (day)
+ "Return the required length of DAY in seconds, default `timeclock-workday'."
(or (car day) timeclock-workday))
(defsubst timeclock-day-length (day)
+ "Return the actual length of DAY in seconds."
(timeclock-entry-list-length (cdr day)))
(defsubst timeclock-day-debt (day)
+ "Return the debt (required - actual) associated with DAY, in seconds."
(- (timeclock-day-required day)
(timeclock-day-length day)))
(defsubst timeclock-day-begin (day)
+ "Return the start time of DAY."
(timeclock-entry-list-begin (cdr day)))
(defsubst timeclock-day-end (day)
+ "Return the end time of DAY."
(timeclock-entry-list-end (cdr day)))
(defsubst timeclock-day-span (day)
+ "Return the span of DAY."
(timeclock-entry-list-span (cdr day)))
(defsubst timeclock-day-break (day)
+ "Return the total break time of DAY."
(timeclock-entry-list-break (cdr day)))
(defsubst timeclock-day-projects (day)
+ "Return a list of all the projects in DAY."
(timeclock-entry-list-projects (cdr 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))))
length))
(defun timeclock-day-list-required (day-list)
+ "Return total required length of DAY-LIST, in seconds."
(timeclock-day-list-template 'timeclock-day-required))
(defun timeclock-day-list-length (day-list)
+ "Return actual length of DAY-LIST, in seconds."
(timeclock-day-list-template 'timeclock-day-length))
(defun timeclock-day-list-debt (day-list)
+ "Return total debt (required - actual) of DAY-LIST."
(timeclock-day-list-template 'timeclock-day-debt))
(defsubst timeclock-day-list-begin (day-list)
+ "Return the start time of DAY-LIST."
(timeclock-day-begin (car day-list)))
(defsubst timeclock-day-list-end (day-list)
+ "Return the end time of DAY-LIST."
(timeclock-day-end (car (last day-list))))
(defun timeclock-day-list-span (day-list)
+ "Return the span of DAY-LIST."
(timeclock-day-list-template 'timeclock-day-span))
(defun timeclock-day-list-break (day-list)
+ "Return the total break of DAY-LIST."
(timeclock-day-list-template 'timeclock-day-break))
(defun timeclock-day-list-projects (day-list)
+ "Return a list of all the projects in DAY-LIST."
(let (projects)
- (while day-list
- (let ((projs (timeclock-day-projects (car day-list))))
- (while projs
- (if projects
- (add-to-list 'projects (car projs))
- (setq projects (list (car projs))))
- (setq projs (cdr projs))))
- (setq day-list (cdr day-list)))
+ (dolist (day day-list)
+ (dolist (proj (timeclock-day-projects day))
+ (if projects
+ (add-to-list 'projects proj)
+ (setq projects (list proj)))))
projects))
-
(defsubst timeclock-current-debt (&optional log-data)
+ "Return the seconds debt from LOG-DATA, default `timeclock-log-data'."
(nth 0 (or log-data (timeclock-log-data))))
(defsubst timeclock-day-alist (&optional log-data)
+ "Return the date alist from LOG-DATA, default `timeclock-log-data'."
(nth 1 (or log-data (timeclock-log-data))))
(defun timeclock-day-list (&optional log-data)
- (let ((alist (timeclock-day-alist log-data))
- day-list)
- (while alist
- (setq day-list (cons (cdar alist) day-list)
- alist (cdr alist)))
+ "Return a list of the cdrs of the date alist from LOG-DATA."
+ (let (day-list)
+ (dolist (date-list (timeclock-day-alist log-data))
+ (setq day-list (cons (cdr date-list) day-list)))
day-list))
(defsubst timeclock-project-alist (&optional log-data)
+ "Return the project alist from LOG-DATA, default `timeclock-log-data'."
(nth 2 (or log-data (timeclock-log-data))))
-
(defun timeclock-log-data (&optional recent-only filename)
"Return the contents of the timelog file, in a useful format.
If the optional argument RECENT-ONLY is non-nil, only show the contents