I’ve a ton of stuff that I want to write up, but the business busy-ness I mentioned in Elect MEPs for Freedom Now continues unabated. I’ve a good business reason for publishing these Emacs snippets, so here we go…
I nearly always have Emacs running. Although I don’t use it as my editor, it always has several useful files and utilities running. It tends to be one of the first applications I install on my workstations because it can also deputise for some more specialised tools. Among the useful utilities, I’ve been using timeclock for over a year and have grown some helper functions in my .emacs. Here’s a short tour. First of all, turn timeclock on and give myself an easy way to count with interval minutes:-
(require 'timeclock) (defun timeclock-interval (i) (list (floor (/ (- (timeclock-time-to-seconds (cadr i)) (timeclock-time-to-seconds (car i))) 60)) (caddr i))) (defun timeclock-intervals (i) (map 'list 'timeclock-interval i))
Next, I want to summarise days according to how long I worked on what:-
(defun timeclock-today (&optional daysago) (timeclock-intervals (cddr (nth (or daysago 0) (timeclock-day-alist)))))
(defun timeclock-total-today (time-projs &optional result)
(if (equal (car time-projs) nil)
result
(let ((tp (sort time-projs (lambda (a b) (string-lessp (cadr b) (cadr a))))))
(if (equal (cadar tp) (cadadr tp))
(timeclock-total-today
(cons
(list (+ (caar tp) (caadr tp)) (cadar tp))
(cddr tp))
result)
(timeclock-total-today (cdr tp) (cons (car tp) result))))))
(defun timeclock-today-interactive ()
(interactive)
(princ
(apply '+
(map 'list 'car
(princ (timeclock-total-today (timeclock-today)))))))
Then I want to total up a number of days and break it down by projects:-
(defun timeclock-print-total (i) (princ (car i)) (princ " ") (princ (cadr i)) (newline))
(defun timeclock-project-totals (&optional log-data)
(map 'list
(lambda (i) (list (apply '+ (map 'list 'car (timeclock-intervals (cdr i)))) (car i)))
(timeclock-project-alist (or log-data (timeclock-log-data)))))
(defun timeclock-print-totals (&optional data) (map 'list 'timeclock-print-total (or data (timeclock-project-totals (timeclock-log-data)))))
I think a running count in the modeline is helpful:-
(defun timeclock-update-modeline () (interactive) (setq timeclock-mode-string (propertize (format "%s %.0fm " (caddr timeclock-last-event) (/ (timeclock-last-period) 60))))) (timeclock-modeline-display)
And finally, c-X c-T shortcuts to control the timeclock quickly. There’s no sense using timeclock if you spend too much time on doing the monitoring, is there?
(define-key ctl-x-map "ti" 'timeclock-in) (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 "tl" 'timeclock-visit-timelog) (define-key ctl-x-map "ty" 'timeclock-today-interactive)
Comments and enhancements welcomed!

Pingback: mjray's status on Monday, 08-Jun-09 11:34:13 UTC - Identi.ca
Thanks for adding that — I’ve only got the barest handle on Lisp, so it’s always interesting to read code that *does* something (rather than just programming examples).
You may also want to take a look at Org mode, and in particular its time clock functions.
I’ve seen Org mode before. It goes against my http://c2.com/cgi/wiki?DoTheSimplestThingThatCouldPossiblyWork instinct. I’d probably spend more time hacking Org mode or my work habits to fit the other than I gained in productivity.
You use emacs, but not as your editor? Funny. What do you use as your editor? And do you run it in Emacs?
Mostly I use wily for GUI editing and an emacs-like editor (jed, joe or mg depending on system) for in-terminal editing. If there’s a way to run text-mode emacsclients from a GUI-based emacs, I’d appreciate being told how!
If you are running the soon to be released emacs 23 (emacs-snapshot packages from http://emacs.orebokech.com/) you can quite simply attach to a running GUI emacs in the terminal by doing emacsclient -t. I use it all the time to share my emacs between a graphical environment and a console, terminal-only one.