forked from baudtack/pomodoro.el
/
pomodoro.el
147 lines (120 loc) · 4.66 KB
/
pomodoro.el
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
;;; pomodoro.el --- A timer for the Pomodoro Technique
;;; (http://www.pomodorotechnique.com)
;; Author: Dave Kerschner <docgnome@docgno.me>
;; Created: Aug 25, 2010
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Code:
(defgroup pomodoro nil
"Timer for the Pomodoro Technique in emacs"
:prefix "pomodoro-"
:group 'tools)
(defcustom pomodoro-work-time 25
"Length of time in minutes for a work period"
:group 'pomodoro
:type 'integer)
(defcustom pomodoro-break-time 5
"Length of time in minutes for a break period"
:group 'pomodoro
:type 'integer)
(defcustom pomodoro-long-break-time 15
"Length of time in minutes for a long break period"
:group 'pomodoro
:type 'integer)
(defcustom pomodoro-nth-for-longer-break 4
"Number of work cycles before a longer break"
:group 'pomodoro
:type 'integer)
(defcustom pomodoro-extra-time 2
"Number of minutes to add onto a timer when avoiding a cycle change"
:group 'pomodoro
:type 'integer)
(defcustom pomodoro-break-start-message "Break time!"
"Message show when a break period starts"
:group 'pomodoro
:type 'string)
(defcustom pomodoro-work-start-message "Back to work slave!"
"Message to show when a work period starts"
:group 'pomodoro
:type 'string)
(defcustom pomodoro-long-break-start-message "Time for a longer break!"
"Message to show when a long break starts"
:group 'pomodoro
:type 'string)
(defcustom pomodoro-work-cycle "w"
"String to display in mode line for a work cycle"
:group 'pomodoro
:type 'string)
(defcustom pomodoro-break-cycle "b"
"String to display in mode line for a break cycle"
:group 'pomodoro
:type 'string)
(defvar pomodoro-timer nil)
(defvar pomodoros 0)
(defvar pomodoro-current-cycle pomodoro-work-cycle)
(defvar pomodor-mode-line-string "")
(defun pomodoro-epoch (c)
(+ (* (car c) (expt 2 16)) (cadr c)))
(defun pomodoro-pad-time (a)
(if (< (length a) 2)
(concat "0" a)
a))
(defun pomodoro-seconds-to-time (s)
(let ((minutes (number-to-string (/ s 60)))
(seconds (number-to-string (mod s 60))))
(concat
(pomodoro-pad-time minutes)
":"
(pomodoro-pad-time seconds))))
(defun pomodoro-set-start-time (s)
(setq pomodoro-start-time (+ (pomodoro-epoch (current-time)) (* s 60))))
(defun pomodoro-tick ()
(let ((time (- pomodoro-start-time (pomodoro-epoch (current-time)))))
(if (<= time 0)
(if (string= pomodoro-current-cycle pomodoro-work-cycle)
(let ((p (if (and (not (= pomodoros 0))
(= (mod pomodoros pomodoro-nth-for-longer-break) 0))
(cons pomodoro-long-break-time pomodoro-long-break-start-message)
(cons pomodoro-break-time pomodoro-break-start-message))))
(beep)
(if (yes-or-no-p (cdr p))
(progn
(setq pomodoro-current-cycle pomodoro-break-cycle)
(setq pomodoros (incf pomodoros))
(pomodoro-set-start-time (car p)))
(pomodoro-set-start-time pomodoro-extra-time)))
(beep)
(if (yes-or-no-p pomodoro-work-start-message)
(progn
(setq pomodoro-current-cycle pomodoro-work-cycle)
(pomodoro-set-start-time pomodoro-work-time))
(pomodoro-set-start-time pomodoro-extra-time))))
(setq pomodoro-mode-line-string (concat pomodoro-current-cycle (pomodoro-seconds-to-time time) " "))
(force-mode-line-update)))
(defun pomodoro-start (arg)
(interactive "P")
(let* ((timer (or (if (listp arg)
(car arg))
arg
pomodoro-work-time)))
(setq pomodoro-work-time timer)
(pomodoro-set-start-time pomodoro-work-time)
(setq pomodoro-timer (run-with-timer 0 1 'pomodoro-tick))))
(defun pomodoro-stop ()
(interactive)
(cancel-timer pomodoro-timer)
(setq pomodoro-mode-line-string "")
(setq pomodoro-current-cycle pomodoro-work-cycle)
(force-mode-line-update))
(setq-default mode-line-format (cons '(pomodoro-mode-line-string pomodoro-mode-line-string) mode-line-format))
(provide 'pomodoro)