blob: 204116e06871ffdfd0717267e7a72aba1832c779 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
;;; kj-timer.el -- countdown timer -*- lexical-binding: t -*-
(defvar kj/current-timer nil)
(defvar kj/roster nil)
(defvar kj/timer-seconds)
(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))))
(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)))
|