(defvar timer-buffer-name
"*Timer*"
"Buffer name to use for timers.")
(defvar timer-default-countdown
"Default countdown time in seconds."
(* 2 60 60))
(defvar timer-things
"List of things to time."
nil)
(defvar timer-timers
"List of timers."
nil)
(defun timer-reset (things timers)
"Reset timer under `point'."
(setcar (nth (1- (line-number-at-pos)) timer-timers)
(time-add (current-time) (seconds-to-time timer-default-countdown))))
(defun timer (&optional things)
"Interface for controlling countdown timers."
(interactive)
(setq timer-things (or things
(if (and transient-mark-mode mark-active)
(cl-remove-if (lambda (x) (zerop (length x)))
(split-string (buffer-substring-no-properties (point) (mark)) "\n"))
"")))
(setq timer-timers (make-list (length things) nil))
(let ((buffer (generate-new-buffer timer-buffer-name)))
(switch-to-buffer buffer)
(local-set-key (kbd "<return>") 'timer-reset)
(buffer-disable-undo buffer)
(while t
(setq buffer-read-only nil)
(erase-buffer)
(cl-do ((things timer-things (cdr things))
(timers timer-timers (cdr timers)))
((not things))
(let ((thing (car things))
(timer (car timers)))
(if timer
(let* ((time-diff (time-subtract timer (current-time)))
(microsecs (third time-diff))
(total-seconds (+ (* (first time-diff) 65536) (second time-diff)))
(hours (floor (/ total-seconds 3600)))
(mins (floor (/ (- total-seconds (* hours 3600)) 60)))
(secs (- total-seconds (* hours 3600) (* mins 60))))
(if (plusp total-seconds)
(insert (format "%s [%2d:%02d:%02d]" thing hours mins secs))
(insert (format "%s [--:--:--]" thing))))
(insert (format "%s [--:--:--]" thing)))
(newline)))
(setq buffer-read-only t)
(sit-for 1.0))))
(provide 'timer)