1 |
;;; timeclock.el --- mode for keeping track of how much you work |
;;; timeclock.el --- mode for keeping track of how much you work |
2 |
|
|
3 |
;; Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. |
;; Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc. |
4 |
|
|
5 |
;; Author: John Wiegley <johnw@gnu.org> |
;; Author: John Wiegley <johnw@gnu.org> |
6 |
;; Created: 25 Mar 1999 |
;; Created: 25 Mar 1999 |
64 |
;; `timeclock-ask-before-exiting' to t using M-x customize (this is |
;; `timeclock-ask-before-exiting' to t using M-x customize (this is |
65 |
;; the default), or by adding the following to your .emacs file: |
;; the default), or by adding the following to your .emacs file: |
66 |
;; |
;; |
67 |
;; (add-hook 'kill-emacs-hook 'timeclock-query-out) |
;; (add-hook 'kill-emacs-query-functions 'timeclock-query-out) |
68 |
|
|
69 |
;; NOTE: If you change your .timelog file without using timeclock's |
;; NOTE: If you change your .timelog file without using timeclock's |
70 |
;; functions, or if you change the value of any of timeclock's |
;; functions, or if you change the value of any of timeclock's |
135 |
"*If non-nil, ask if the user wants to clock out before exiting Emacs." |
"*If non-nil, ask if the user wants to clock out before exiting Emacs." |
136 |
:set (lambda (symbol value) |
:set (lambda (symbol value) |
137 |
(if value |
(if value |
138 |
(add-hook 'kill-emacs-hook 'timeclock-query-out) |
(add-hook 'kill-emacs-query-functions 'timeclock-query-out) |
139 |
(remove-hook 'kill-emacs-hook 'timeclock-query-out)) |
(remove-hook 'kill-emacs-query-functions 'timeclock-query-out)) |
140 |
(setq timeclock-ask-before-exiting value)) |
(setq timeclock-ask-before-exiting value)) |
141 |
:type 'boolean |
:type 'boolean |
142 |
:group 'timeclock) |
:group 'timeclock) |
252 |
`timeclock-last-period' instead.") |
`timeclock-last-period' instead.") |
253 |
|
|
254 |
(defvar timeclock-mode-string nil |
(defvar timeclock-mode-string nil |
255 |
"The timeclock string (optionally) displayed in the modeline.") |
"The timeclock string (optionally) displayed in the modeline. |
256 |
|
The time is bracketed by <> if you are clocked in, otherwise by [].") |
257 |
|
|
258 |
(defvar timeclock-day-over nil |
(defvar timeclock-day-over nil |
259 |
"The date of the last day when notified \"day over\" for.") |
"The date of the last day when notified \"day over\" for.") |
263 |
;;;###autoload |
;;;###autoload |
264 |
(defun timeclock-modeline-display (&optional arg) |
(defun timeclock-modeline-display (&optional arg) |
265 |
"Toggle display of the amount of time left today in the modeline. |
"Toggle display of the amount of time left today in the modeline. |
266 |
If `timeclock-use-display-time' is non-nil, the modeline will be |
If `timeclock-use-display-time' is non-nil (the default), then |
267 |
updated whenever the time display is updated. Otherwise, the |
the function `display-time-mode' must be active, and the modeline |
268 |
timeclock will use its own sixty second timer to do its updating. |
will be updated whenever the time display is updated. Otherwise, |
269 |
With prefix ARG, turn modeline display on if and only if ARG is |
the timeclock will use its own sixty second timer to do its |
270 |
positive. Returns the new status of timeclock modeline display |
updating. With prefix ARG, turn modeline display on if and only |
271 |
\(non-nil means on)." |
if ARG is positive. Returns the new status of timeclock modeline |
272 |
|
display (non-nil means on)." |
273 |
(interactive "P") |
(interactive "P") |
274 |
|
;; cf display-time-mode. |
275 |
|
(setq timeclock-mode-string "") |
276 |
|
(or global-mode-string (setq global-mode-string '(""))) |
277 |
(let ((on-p (if arg |
(let ((on-p (if arg |
278 |
(> (prefix-numeric-value arg) 0) |
(> (prefix-numeric-value arg) 0) |
279 |
(not timeclock-modeline-display)))) |
(not timeclock-modeline-display)))) |
280 |
(if on-p |
(if on-p |
281 |
(let ((list-entry (or (memq 'global-mode-string mode-line-format) |
(progn |
282 |
;; In Emacs 21.3 we must use assq |
(or (memq 'timeclock-mode-string global-mode-string) |
283 |
(assq 'global-mode-string mode-line-format)))) |
(setq global-mode-string |
284 |
(unless (or (null list-entry) |
(append global-mode-string '(timeclock-mode-string)))) |
|
(memq 'timeclock-mode-string mode-line-format)) |
|
|
(setcdr list-entry (cons 'timeclock-mode-string |
|
|
(cdr list-entry)))) |
|
285 |
(unless (memq 'timeclock-update-modeline timeclock-event-hook) |
(unless (memq 'timeclock-update-modeline timeclock-event-hook) |
286 |
(add-hook 'timeclock-event-hook 'timeclock-update-modeline)) |
(add-hook 'timeclock-event-hook 'timeclock-update-modeline)) |
287 |
(when timeclock-update-timer |
(when timeclock-update-timer |
290 |
(if (boundp 'display-time-hook) |
(if (boundp 'display-time-hook) |
291 |
(remove-hook 'display-time-hook 'timeclock-update-modeline)) |
(remove-hook 'display-time-hook 'timeclock-update-modeline)) |
292 |
(if timeclock-use-display-time |
(if timeclock-use-display-time |
293 |
(add-hook 'display-time-hook 'timeclock-update-modeline) |
(progn |
294 |
|
;; Update immediately so there is a visible change |
295 |
|
;; on calling this function. |
296 |
|
(if display-time-mode (timeclock-update-modeline)) |
297 |
|
(add-hook 'display-time-hook 'timeclock-update-modeline)) |
298 |
(setq timeclock-update-timer |
(setq timeclock-update-timer |
299 |
(run-at-time nil 60 'timeclock-update-modeline)))) |
(run-at-time nil 60 'timeclock-update-modeline)))) |
300 |
(setq mode-line-format |
(setq global-mode-string |
301 |
(delq 'timeclock-mode-string mode-line-format)) |
(delq 'timeclock-mode-string global-mode-string)) |
302 |
(remove-hook 'timeclock-event-hook 'timeclock-update-modeline) |
(remove-hook 'timeclock-event-hook 'timeclock-update-modeline) |
303 |
(if (boundp 'display-time-hook) |
(if (boundp 'display-time-hook) |
304 |
(remove-hook 'display-time-hook |
(remove-hook 'display-time-hook |
430 |
;;;###autoload |
;;;###autoload |
431 |
(defun timeclock-query-out () |
(defun timeclock-query-out () |
432 |
"Ask the user before clocking out. |
"Ask the user before clocking out. |
433 |
This is a useful function for adding to `kill-emacs-hook'." |
This is a useful function for adding to `kill-emacs-query-functions'." |
434 |
(if (and (equal (car timeclock-last-event) "i") |
(if (and (equal (car timeclock-last-event) "i") |
435 |
(y-or-n-p "You're currently clocking time, clock out? ")) |
(y-or-n-p "You're currently clocking time, clock out? ")) |
436 |
(timeclock-out))) |
(timeclock-out))) |
589 |
(defun timeclock-update-modeline () |
(defun timeclock-update-modeline () |
590 |
"Update the `timeclock-mode-string' displayed in the modeline." |
"Update the `timeclock-mode-string' displayed in the modeline." |
591 |
(interactive) |
(interactive) |
592 |
(let* ((remainder (timeclock-workday-remaining)) |
(let ((remainder (timeclock-workday-remaining)) |
593 |
(last-in (equal (car timeclock-last-event) "i"))) |
(last-in (equal (car timeclock-last-event) "i"))) |
594 |
(when (and (< remainder 0) |
(when (and (< remainder 0) |
595 |
(not (and timeclock-day-over |
(not (and timeclock-day-over |
596 |
(equal timeclock-day-over |
(equal timeclock-day-over |
600 |
(timeclock-time-to-date (current-time))) |
(timeclock-time-to-date (current-time))) |
601 |
(run-hooks 'timeclock-day-over-hook)) |
(run-hooks 'timeclock-day-over-hook)) |
602 |
(setq timeclock-mode-string |
(setq timeclock-mode-string |
603 |
(format " %c%s%c" |
(propertize |
604 |
(if last-in ?< ?[) |
(format " %c%s%c " |
605 |
(timeclock-seconds-to-string remainder nil t) |
(if last-in ?< ?[) |
606 |
(if last-in ?> ?]))))) |
(timeclock-seconds-to-string remainder nil t) |
607 |
|
(if last-in ?> ?])) |
608 |
|
'help-echo "timeclock: time remaining")))) |
609 |
|
|
610 |
|
(put 'timeclock-mode-string 'risky-local-variable t) |
611 |
|
|
612 |
(defun timeclock-log (code &optional project) |
(defun timeclock-log (code &optional project) |
613 |
"Log the event CODE to the timeclock log, at the time of call. |
"Log the event CODE to the timeclock log, at the time of call. |
1093 |
(setq timeclock-discrepancy accum)))) |
(setq timeclock-discrepancy accum)))) |
1094 |
(unless timeclock-last-event-workday |
(unless timeclock-last-event-workday |
1095 |
(setq timeclock-last-event-workday timeclock-workday)) |
(setq timeclock-last-event-workday timeclock-workday)) |
1096 |
(setq accum timeclock-discrepancy |
(setq accum (or timeclock-discrepancy 0) |
1097 |
elapsed (or timeclock-elapsed elapsed)) |
elapsed (or timeclock-elapsed elapsed)) |
1098 |
(if timeclock-last-event |
(if timeclock-last-event |
1099 |
(if (equal (car timeclock-last-event) "i") |
(if (equal (car timeclock-last-event) "i") |