Timeclock Functions in my .emacs

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!

This entry was posted in GNU/Linux and tagged , , , , , , . Bookmark the permalink.