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!