summaryrefslogtreecommitdiff
path: root/emacs/.config/emacs/lisp/kj-timer.el
diff options
context:
space:
mode:
Diffstat (limited to 'emacs/.config/emacs/lisp/kj-timer.el')
-rw-r--r--emacs/.config/emacs/lisp/kj-timer.el47
1 files changed, 47 insertions, 0 deletions
diff --git a/emacs/.config/emacs/lisp/kj-timer.el b/emacs/.config/emacs/lisp/kj-timer.el
new file mode 100644
index 0000000..6e200a7
--- /dev/null
+++ b/emacs/.config/emacs/lisp/kj-timer.el
@@ -0,0 +1,47 @@
+;;; kj-timer.el -- countdown timer -*- lexical-binding: t -*-
+
+(defun kj/display-timer (seconds current &optional next)
+ (with-current-buffer (get-buffer-create "*timer*")
+ (let* ((stopped (< seconds 0))
+ (seconds (if stopped 0 (truncate seconds))))
+ (erase-buffer)
+ (insert
+ (propertize (format "%02d:%02d" (/ seconds 60)
+ (% seconds 60))
+ 'face
+ (append '(:height 1000)
+ (when stopped
+ '(:inherit 'org-imminent-deadline))))
+ "\n" (propertize (concat current " ยท " (if next next "done"))
+ 'face '(:foreground "gray" :height 500)))
+ (set-left-margin (point-min) (point-max) 10))))
+
+(defvar kj/current-timer nil)
+(defvar kj/roster nil)
+(defvar kj/timer-seconds)
+
+(defun kj/run-single-timer (seconds current next)
+ (let* ((stop-time (+ (float-time) seconds))
+ (display-fn (lambda ()
+ (kj/display-timer
+ (- stop-time (float-time))
+ current next))))
+ (setq kj/current-timer (run-at-time t 0.5 display-fn))))
+
+(defun kj/timer (seconds &rest roster)
+ (with-current-buffer (get-buffer-create "*timer*")
+ (display-buffer (current-buffer))
+ (setq cursor-type nil)
+ (use-local-map (define-keymap "SPC" 'kj/timer-next))
+ (setq kj/roster roster)
+ (setq kj/timer-seconds seconds)
+ (kj/timer-next)))
+
+(defun kj/timer-next ()
+ (interactive)
+ (unless kj/roster
+ (error "The timers are done."))
+ (when kj/current-timer
+ (cancel-timer kj/current-timer))
+ (kj/run-single-timer kj/timer-seconds (nth 0 kj/roster) (nth 1 kj/roster))
+ (setq kj/roster (cdr kj/roster)))