>From 573fd67baaf17a5344fe0827641e5edb271dd599 Mon Sep 17 00:00:00 2001 From: Kyle Meyer Date: Tue, 2 Dec 2014 01:34:38 -0500 Subject: [PATCH 4/4] org-timer.el: Isolate commands of different timers * lisp/org-timer.el: Fix timer bugs resulting from crosstalk between commands for relative and countdown timers. Several issues were caused by relative timer functions trying to work with countdown timers. - When org-timer-start was called with a countdown timer, the modeline was updated for the new relative timer, but the countdown timer remained scheduled. - When org-timer-pause-or-continue was called with a countdown timer running, the modeline was put in a paused state, but the countdown timer remained scheduled. - When org-timer-stop was called with a countdown timer running, the timer was removed from the modeline, but the countdown timer remained scheduled. Another issue was due to a countdown timer function trying to work with a relative timer. - When org-timer-set-timer was called with a paused relative timer, the relative timer was not reset properly (org-timer-pause-time was still non-nil) and the modeline remained in the paused state of the relative timer, even though the countdown timer was scheduled with run-with-timer. To prevent all these issues, refuse to execute relative timer commands if a countdown timer is running, and vice versa. --- lisp/org-timer.el | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/lisp/org-timer.el b/lisp/org-timer.el index 6cecd7e..147528e 100644 --- a/lisp/org-timer.el +++ b/lisp/org-timer.el @@ -93,6 +93,8 @@ (defvar org-timer-done-hook nil (defvar org-timer-cancel-hook nil "Hook run before countdown timer is canceled.") +(defvar org-timer-timer-is-countdown nil) + ;;;###autoload (defun org-timer-start (&optional offset) "Set the starting time for the relative timer to now. @@ -105,8 +107,12 @@ (defun org-timer-start (&optional offset) the amount, with the default to make the first timer string in the region 0:00:00." (interactive "P") - (if (equal offset '(16)) - (call-interactively 'org-timer-change-times-in-region) + (cond + ((equal offset '(16)) + (call-interactively 'org-timer-change-times-in-region)) + (org-timer-timer-is-countdown + (user-error "Countdown timer is running. Cancel first")) + (t (let (delta def s) (if (not offset) (setq org-timer-start-time (current-time)) @@ -129,7 +135,7 @@ (defun org-timer-start (&optional offset) (message "Timer start time set to %s, current value is %s" (format-time-string "%T" org-timer-start-time) (org-timer-secs-to-hms (or delta 0))) - (run-hooks 'org-timer-start-hook)))) + (run-hooks 'org-timer-start-hook))))) (defun org-timer-pause-or-continue (&optional stop) "Pause or continue the relative timer. @@ -137,7 +143,10 @@ (defun org-timer-pause-or-continue (&optional stop) (interactive "P") (cond (stop (org-timer-stop)) - ((not org-timer-start-time) (error "No timer is running")) + (org-timer-timer-is-countdown + (user-error "Countdown timer is running")) + ((not org-timer-start-time) + (user-error "No relative timer is running")) (org-timer-pause-time ;; timer is paused, continue (setq org-timer-start-time @@ -160,6 +169,8 @@ (defun org-timer-pause-or-continue (&optional stop) (defun org-timer-stop () "Stop the relative timer." (interactive) + (when org-timer-timer-is-countdown + (user-error "Countdown timer is running")) (run-hooks 'org-timer-stop-hook) (setq org-timer-start-time nil org-timer-pause-time nil) @@ -192,7 +203,6 @@ (defun org-timer-value-string () (org-timer-secs-to-hms (abs (floor (org-timer-seconds)))))) -(defvar org-timer-timer-is-countdown nil) (defun org-timer-seconds () (if org-timer-timer-is-countdown (- (org-float-time org-timer-start-time) @@ -354,8 +364,8 @@ (defvar org-timer-current-timer nil) (defun org-timer-cancel-timer () "Cancel the current timer." (interactive) - (if (not org-timer-current-timer) - (message "No timer to cancel") + (if (not org-timer-timer-is-countdown) + (message "No countdown timer to cancel") (run-hooks 'org-timer-cancel-hook) (cancel-timer org-timer-current-timer) (setq org-timer-current-timer nil @@ -402,6 +412,9 @@ (defun org-timer-set-timer (&optional opt) minutes in the Effort property, if any. You can ignore this by using three `C-u' prefix arguments." (interactive "P") + (when (and org-timer-start-time + (not org-timer-timer-is-countdown)) + (user-error "Relative timer is running. Stop first")) (let* ((effort-minutes (org-get-at-eol 'effort-minutes 1)) (minutes (or (and (not (equal opt '(64))) effort-minutes @@ -435,10 +448,9 @@ (defun org-timer-set-timer (&optional opt) (concat "File:" (file-name-nondirectory (buffer-file-name))))) (t (error "Not in an Org buffer")))) timer-set) - (if (or (and org-timer-current-timer - (or (equal opt '(16)) - (y-or-n-p "Replace current timer? "))) - (not org-timer-current-timer)) + (if (or (not org-timer-current-timer) + (or (equal opt '(16)) + (y-or-n-p "Replace current countdown timer? "))) (progn (require 'org-clock) (when org-timer-current-timer -- 2.1.3