Hello! I decided to clean up org-clock slightly by putting all the modeline stuff in one place. While the initial goal was simply cleanup, this does include some improvements.
Tests pass after each patch on emacs 30.2. Tests pass after final patch on emacs 28 and 29. Tests pass after final patch with TZ set to UTC, Europe/Istanbul, and America/New_York. In the existing code, `org-clock-cancel' didn't cancel the timers so they would run regularly for no reason. This is fixed in the first patch. I've always been a little annoyed that the time in the modeline will update out of sync with the clock information. The second patch synchronizes everything nicely. The third patch is totally optional. Feel free to exclude it if you don't like it. Users already have control over repeated timer activations with the variable `timer-max-repeats'. I'm currently in the middle of diagnosing a hang I get when resuming from suspend. I don't believe this is a major contributor.
>From e8ee8552738d1f9e8ca5b0080038e448a8b7fcb4 Mon Sep 17 00:00:00 2001 From: Morgan Smith <[email protected]> Date: Wed, 17 Dec 2025 14:01:43 -0500 Subject: [PATCH 1/8] Consolidate org-clock mode-line logic into one function Notable changes: The mode-line update timers are now canceled in `org-clock-cancel' and they can now cancel themselves if they notice they are running when not clocked in. * lisp/org-clock.el (org-clock-in, org-clock-out, org-clock-cancel): Move mode-line related logic into `org-clock-update-mode-line' and simply call that function instead. (org-clock-update-mode-line): Receive code snippets from other functions. Now it deals with the `global-mode-string', the `frame-title-format', and the timers. --- lisp/org-clock.el | 131 ++++++++++++++++++++++------------------------ 1 file changed, 64 insertions(+), 67 deletions(-) diff --git a/lisp/org-clock.el b/lisp/org-clock.el index 753f1a202..75417ef0b 100644 --- a/lisp/org-clock.el +++ b/lisp/org-clock.el @@ -823,26 +823,66 @@ org-clock-get-last-clock-out-time (org-time-string-to-time (match-string 1)))))) (defun org-clock-update-mode-line (&optional refresh) - "Update mode line with clock information. -When optional argument is non-nil, refresh cached heading." - (if org-clock-effort - (org-clock-notify-once-if-expired) - (setq org-clock-task-overrun nil)) - (when refresh (setq org-clock-heading (org-clock--mode-line-heading))) - (setq org-mode-line-string - (propertize - (let ((clock-string (org-clock-get-clock-string org-clock-string-limit)) - (help-text "Org mode clock is running.\nmouse-1 shows a \ + "Update mode line and frame title with clock information. + +If no item is currently being clocked the the information is removed. + +When optional argument is non-nil, REFRESH cached heading. + +Information displayed is controlled by `org-clock-clocked-in-display'." + (if (org-clocking-p) + (progn + (if org-clock-effort + (org-clock-notify-once-if-expired) + (setq org-clock-task-overrun nil)) + (when refresh (setq org-clock-heading (org-clock--mode-line-heading))) + (setq org-mode-line-string + (propertize + (let ((clock-string (org-clock-get-clock-string org-clock-string-limit)) + (help-text "Org mode clock is running.\nmouse-1 shows a \ menu\nmouse-2 will jump to task")) - (propertize clock-string 'help-echo help-text)) - 'local-map org-clock-mode-line-map - 'mouse-face 'mode-line-highlight)) - (if (and org-clock-task-overrun org-clock-task-overrun-text) - (setq org-mode-line-string - (concat (propertize - org-clock-task-overrun-text - 'face 'org-mode-line-clock-overrun) - org-mode-line-string))) + (propertize clock-string 'help-echo help-text)) + 'local-map org-clock-mode-line-map + 'mouse-face 'mode-line-highlight)) + (if (and org-clock-task-overrun org-clock-task-overrun-text) + (setq org-mode-line-string + (concat (propertize + org-clock-task-overrun-text + 'face 'org-mode-line-clock-overrun) + org-mode-line-string))) + + ;; add to mode line + (when (or (eq org-clock-clocked-in-display 'mode-line) + (eq org-clock-clocked-in-display 'both)) + (or global-mode-string (setq global-mode-string '(""))) + (or (memq 'org-mode-line-string global-mode-string) + (setq global-mode-string + (append global-mode-string '(org-mode-line-string))))) + ;; add to frame title + (unless (equal frame-title-format org-clock-frame-title-format) + (when (or (eq org-clock-clocked-in-display 'frame-title) + (eq org-clock-clocked-in-display 'both)) + (setq org-frame-title-format-backup frame-title-format) + (setq frame-title-format org-clock-frame-title-format))) + ;; timers + (when (and org-clock-clocked-in-display + (null org-clock-mode-line-timer)) + (setq org-clock-mode-line-timer + (run-with-timer org-clock-update-period + org-clock-update-period + #'org-clock-update-mode-line))) + (when (null org-clock-idle-timer) + (setq org-clock-idle-timer + (run-with-timer 60 60 #'org-resolve-clocks-if-idle)))) + (when org-clock-mode-line-timer + (cancel-timer org-clock-mode-line-timer) + (setq org-clock-mode-line-timer nil)) + (when org-clock-idle-timer + (cancel-timer org-clock-idle-timer) + (setq org-clock-idle-timer nil)) + (setq global-mode-string + (delq 'org-mode-line-string global-mode-string)) + (org-clock-restore-frame-title-format)) (force-mode-line-update)) (defun org-clock-get-clocked-time () @@ -1535,32 +1575,7 @@ org-clock-in (save-excursion (org-back-to-heading t) (point)) (buffer-base-buffer)) (setq org-clock-has-been-used t) - ;; add to mode line - (when (or (eq org-clock-clocked-in-display 'mode-line) - (eq org-clock-clocked-in-display 'both)) - (or global-mode-string (setq global-mode-string '(""))) - (or (memq 'org-mode-line-string global-mode-string) - (setq global-mode-string - (append global-mode-string '(org-mode-line-string))))) - ;; add to frame title - (when (or (eq org-clock-clocked-in-display 'frame-title) - (eq org-clock-clocked-in-display 'both)) - (setq org-frame-title-format-backup frame-title-format) - (setq frame-title-format org-clock-frame-title-format)) - (org-clock-update-mode-line) - (when org-clock-mode-line-timer - (cancel-timer org-clock-mode-line-timer) - (setq org-clock-mode-line-timer nil)) - (when org-clock-clocked-in-display - (setq org-clock-mode-line-timer - (run-with-timer org-clock-update-period - org-clock-update-period - #'org-clock-update-mode-line))) - (when org-clock-idle-timer - (cancel-timer org-clock-idle-timer) - (setq org-clock-idle-timer nil)) - (setq org-clock-idle-timer - (run-with-timer 60 60 #'org-resolve-clocks-if-idle)) + (org-clock-update-mode-line) (message "Clock starts at %s - %s" ts org--msg-extra) (run-hooks 'org-clock-in-hook)))))) @@ -1811,10 +1826,7 @@ org-clock-out (interactive "P") (catch 'exit (when (not (org-clocking-p)) - (setq global-mode-string - (delq 'org-mode-line-string global-mode-string)) - (org-clock-restore-frame-title-format) - (force-mode-line-update) + (org-clock-update-mode-line) (if fail-quietly (throw 'exit t) (user-error "No active clock"))) (let ((org-clock-out-switch-to-state (if switch-to-state @@ -1858,15 +1870,7 @@ org-clock-out (delete-region (line-beginning-position) (line-beginning-position 2))) (org-clock-remove-empty-clock-drawer)) - (when org-clock-mode-line-timer - (cancel-timer org-clock-mode-line-timer) - (setq org-clock-mode-line-timer nil)) - (when org-clock-idle-timer - (cancel-timer org-clock-idle-timer) - (setq org-clock-idle-timer nil)) - (setq global-mode-string - (delq 'org-mode-line-string global-mode-string)) - (org-clock-restore-frame-title-format) + (org-clock-update-mode-line) (when org-clock-out-switch-to-state (save-excursion (org-back-to-heading t) @@ -1885,7 +1889,6 @@ org-clock-out org-clock-out-switch-to-state "\\(?:[ \t]\\|$\\)")))) (org-todo org-clock-out-switch-to-state)))))) - (force-mode-line-update) (message (if remove "Clock stopped at %s after %s => LINE REMOVED" "Clock stopped at %s after %s") @@ -1982,10 +1985,7 @@ org-clock-cancel "Cancel the running clock by removing the start timestamp." (interactive) (when (not (org-clocking-p)) - (setq global-mode-string - (delq 'org-mode-line-string global-mode-string)) - (org-clock-restore-frame-title-format) - (force-mode-line-update) + (org-clock-update-mode-line) (user-error "No active clock")) (save-excursion ; Do not replace this with `with-current-buffer'. (with-no-warnings (set-buffer (org-clocking-buffer))) @@ -1999,10 +1999,7 @@ org-clock-cancel (move-marker org-clock-marker nil) (move-marker org-clock-hd-marker nil) (setq org-clock-current-task nil) - (setq global-mode-string - (delq 'org-mode-line-string global-mode-string)) - (org-clock-restore-frame-title-format) - (force-mode-line-update) + (org-clock-update-mode-line) (message "Clock canceled") (run-hooks 'org-clock-cancel-hook)) base-commit: 1328e518db2e5876c8768fb4c74769d5b518984a -- 2.52.0
>From eb2d21cc504de544cfabf16058cb0600cdefc641 Mon Sep 17 00:00:00 2001 From: Morgan Smith <[email protected]> Date: Wed, 17 Dec 2025 14:35:11 -0500 Subject: [PATCH 2/8] Synchronize org-clock mode-line updates to their update period The org-clock mode-line displays the current clocking minutes. This number notably changes when the current minute changes. By using the builtin feature of timers to synchronize to the repeat interval we can have the mode-line update when the minute changes so it is always accurate. * lisp/org-clock.el (org-clock-update-mode-line): Synchronize `org-clock-mode-line-timer' and `org-resolve-clocks-if-idle' to their repeat period. --- lisp/org-clock.el | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lisp/org-clock.el b/lisp/org-clock.el index 75417ef0b..20b4ecdcf 100644 --- a/lisp/org-clock.el +++ b/lisp/org-clock.el @@ -868,12 +868,11 @@ org-clock-update-mode-line (when (and org-clock-clocked-in-display (null org-clock-mode-line-timer)) (setq org-clock-mode-line-timer - (run-with-timer org-clock-update-period - org-clock-update-period + (run-with-timer t org-clock-update-period #'org-clock-update-mode-line))) (when (null org-clock-idle-timer) (setq org-clock-idle-timer - (run-with-timer 60 60 #'org-resolve-clocks-if-idle)))) + (run-with-timer t 60 #'org-resolve-clocks-if-idle)))) (when org-clock-mode-line-timer (cancel-timer org-clock-mode-line-timer) (setq org-clock-mode-line-timer nil)) -- 2.52.0
>From 6c4b82b7d641684ce6d306f54136b7d7ad9f5796 Mon Sep 17 00:00:00 2001 From: Morgan Smith <[email protected]> Date: Wed, 31 Dec 2025 16:32:42 -0500 Subject: [PATCH 3/8] org-clock-update-mode-line: always reschedule timers By always rescheduling the timers we prevent them from being run repeatedly when time jumps forward (such as when Emacs was suspended). * lisp/org-clock.el (org-clock-update-mode-line): Always reschedule the timers `org-clock-mode-line-timer' and `org-clock-idle-timer'. --- lisp/org-clock.el | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/lisp/org-clock.el b/lisp/org-clock.el index 20b4ecdcf..0722c3d1c 100644 --- a/lisp/org-clock.el +++ b/lisp/org-clock.el @@ -864,21 +864,31 @@ org-clock-update-mode-line (eq org-clock-clocked-in-display 'both)) (setq org-frame-title-format-backup frame-title-format) (setq frame-title-format org-clock-frame-title-format))) - ;; timers - (when (and org-clock-clocked-in-display - (null org-clock-mode-line-timer)) - (setq org-clock-mode-line-timer - (run-with-timer t org-clock-update-period - #'org-clock-update-mode-line))) - (when (null org-clock-idle-timer) - (setq org-clock-idle-timer - (run-with-timer t 60 #'org-resolve-clocks-if-idle)))) + ;; Timers. Always reschedule timers so they aren't run + ;; repeatedly if time jumps forward. See + ;; `display-time-event-handler' which also does this. + (cl-flet ((setup-timer (timer func interval) + (if (null timer) + (run-with-timer t interval func) + (timer-set-time timer + (timer-next-integral-multiple-of-time + (current-time) interval) + interval) + (unless (memq timer timer-list) + (timer-activate timer)) + timer))) + (when org-clock-clocked-in-display + (setq org-clock-mode-line-timer + (setup-timer org-clock-mode-line-timer + #'org-clock-update-mode-line + org-clock-update-period))) + (setq + org-clock-idle-timer + (setup-timer org-clock-idle-timer #'org-resolve-clocks-if-idle 60)))) (when org-clock-mode-line-timer - (cancel-timer org-clock-mode-line-timer) - (setq org-clock-mode-line-timer nil)) + (cancel-timer org-clock-mode-line-timer)) (when org-clock-idle-timer - (cancel-timer org-clock-idle-timer) - (setq org-clock-idle-timer nil)) + (cancel-timer org-clock-idle-timer)) (setq global-mode-string (delq 'org-mode-line-string global-mode-string)) (org-clock-restore-frame-title-format)) -- 2.52.0
>From 5e4e1c32a334e90feada4978c93acab967e9dc88 Mon Sep 17 00:00:00 2001 From: Morgan Smith <[email protected]> Date: Wed, 31 Dec 2025 18:56:25 -0500 Subject: [PATCH 4/8] test-org-clock/mode-line: Simplify string comparisons * testing/lisp/test-org-clock.el (test-org-clock/mode-line): Simplify string comparisons. --- testing/lisp/test-org-clock.el | 42 ++++++++++++---------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/testing/lisp/test-org-clock.el b/testing/lisp/test-org-clock.el index 9ab8a1b67..bce12fafa 100644 --- a/testing/lisp/test-org-clock.el +++ b/testing/lisp/test-org-clock.el @@ -1491,89 +1491,75 @@ test-org-clock/mode-line ;; Test the variant without effort. (should (equal - "<before> [0:00] (Heading) <after> " + "[0:00] (Heading) " (org-test-with-temp-text "* Heading" (org-clock-in) - (prog1 (concat "<before> " - (org-clock-get-clock-string) - "<after> ") + (prog1 (org-clock-get-clock-string) (org-clock-out))))) ;; Test the variant with effort. (should (equal - "<before> [0:00/1:00] (Heading) <after> " + "[0:00/1:00] (Heading) " (org-test-with-temp-text "* Heading :PROPERTIES: :EFFORT: 1h :END:" (org-clock-in) - (prog1 (concat "<before> " - (org-clock-get-clock-string) - "<after> ") + (prog1 (org-clock-get-clock-string) (org-clock-out))))) ;; Verify that long headlines are truncated correctly (should (equal - "<before> [0:00] (This is a…) <after> " + "[0:00] (This is a…) " (org-test-with-temp-text "* This is a long headline blah blah blah" (org-clock-in) - (prog1 (concat "<before> " - (org-clock-get-clock-string 20) - "<after> ") + (prog1 (org-clock-get-clock-string 20) (org-clock-out))))) ;; Verify that long headlines with effort are truncated correctly (should (equal - "<before> [0:00/1:00] (This…) <after> " + "[0:00/1:00] (This…) " (org-test-with-temp-text "* This is a long headline blah blah blah :PROPERTIES: :EFFORT: 1h :END:" (org-clock-in) - (prog1 (concat "<before> " - (org-clock-get-clock-string 20) - "<after> ") + (prog1 (org-clock-get-clock-string 20) (org-clock-out))))) ;; Check the limit case where there's just one character of the headline ;; displayed (should (equal - "<before> [0:00] (T…) <after> " + "[0:00] (T…) " (org-test-with-temp-text "* This is a long headline blah blah blah" (org-clock-in) - (prog1 (concat "<before> " - (org-clock-get-clock-string 12) - "<after> ") + (prog1 (org-clock-get-clock-string 12) (org-clock-out))))) ;; Check the limit case where the headline can't be displayed at all (should (equal - "<before> [0:00] <after> " + "[0:00] " (org-test-with-temp-text "* This is a long headline blah blah blah" (org-clock-in) - (prog1 (concat "<before> " - (org-clock-get-clock-string 10) - "<after> ") + (prog1 (org-clock-get-clock-string 10) (org-clock-out))))) ;; Check the limit case where even the time string is truncated (should (equal - "<before> [0: <after> " + "[0: " (org-test-with-temp-text "* This is a long headline blah blah blah" (org-clock-in) - (prog1 (concat "<before> " - (org-clock-get-clock-string 3) - "<after> ") + (prog1 (org-clock-get-clock-string 3) (org-clock-out))))) ;; Verify that 'org-mode-line-clock-overrun face is applied if the task has -- 2.52.0
>From 85bc71170f68581cc9b9d8d756d997198a422307 Mon Sep 17 00:00:00 2001 From: Morgan Smith <[email protected]> Date: Wed, 31 Dec 2025 19:09:18 -0500 Subject: [PATCH 5/8] test-org-clock/mode-line: Factor duplicated code * testing/lisp/test-org-clock.el (test-org-clock/mode-line): Factor duplicated code. --- testing/lisp/test-org-clock.el | 102 +++++++++++---------------------- 1 file changed, 35 insertions(+), 67 deletions(-) diff --git a/testing/lisp/test-org-clock.el b/testing/lisp/test-org-clock.el index bce12fafa..b46ee624e 100644 --- a/testing/lisp/test-org-clock.el +++ b/testing/lisp/test-org-clock.el @@ -1488,80 +1488,48 @@ test-org-clock/mode-line in a space (to ensure that consecutive 'global-mode-string' elements display properly)\" per the Info node `(elisp)Mode Line Variables'." - ;; Test the variant without effort. - (should - (equal - "[0:00] (Heading) " - (org-test-with-temp-text - "* Heading" - (org-clock-in) - (prog1 (org-clock-get-clock-string) - (org-clock-out))))) - ;; Test the variant with effort. - (should - (equal - "[0:00/1:00] (Heading) " - (org-test-with-temp-text - "* Heading + (cl-flet* + ((check-mode-line-value (buffer-string expected &optional max-length) + (should + (equal expected + (org-test-with-temp-text + buffer-string + (org-clock-in) + (prog1 (org-clock-get-clock-string max-length) + (org-clock-out))))))) + ;; Test the variant without effort. + (check-mode-line-value "* Heading" "[0:00] (Heading) ") + ;; Test the variant with effort. + (check-mode-line-value "* Heading :PROPERTIES: :EFFORT: 1h :END:" - (org-clock-in) - (prog1 (org-clock-get-clock-string) - (org-clock-out))))) - ;; Verify that long headlines are truncated correctly - (should - (equal - "[0:00] (This is a…) " - (org-test-with-temp-text - "* This is a long headline blah blah blah" - (org-clock-in) - (prog1 (org-clock-get-clock-string 20) - (org-clock-out))))) - ;; Verify that long headlines with effort are truncated correctly - (should - (equal - "[0:00/1:00] (This…) " - (org-test-with-temp-text + "[0:00/1:00] (Heading) ") + ;; Verify that long headlines are truncated correctly + (check-mode-line-value "* This is a long headline blah blah blah" + "[0:00] (This is a…) " + 20) + ;; Verify that long headlines with effort are truncated correctly + (check-mode-line-value "* This is a long headline blah blah blah :PROPERTIES: :EFFORT: 1h :END:" - (org-clock-in) - (prog1 (org-clock-get-clock-string 20) - (org-clock-out))))) - - ;; Check the limit case where there's just one character of the headline - ;; displayed - (should - (equal - "[0:00] (T…) " - (org-test-with-temp-text - "* This is a long headline blah blah blah" - (org-clock-in) - (prog1 (org-clock-get-clock-string 12) - (org-clock-out))))) - - ;; Check the limit case where the headline can't be displayed at all - (should - (equal - "[0:00] " - (org-test-with-temp-text - "* This is a long headline blah blah blah" - (org-clock-in) - (prog1 (org-clock-get-clock-string 10) - (org-clock-out))))) - - ;; Check the limit case where even the time string is truncated - (should - (equal - "[0: " - (org-test-with-temp-text - "* This is a long headline blah blah blah" - (org-clock-in) - (prog1 (org-clock-get-clock-string 3) - (org-clock-out))))) - + "[0:00/1:00] (This…) " + 20) + ;; Check the limit case where there's just one character of the headline + ;; displayed + (check-mode-line-value "* This is a long headline blah blah blah" + "[0:00] (T…) " + 12) + ;; Check the limit case where the headline can't be displayed at all + (check-mode-line-value "* This is a long headline blah blah blah" + "[0:00] " + 10) + ;; Check the limit case where even the time string is truncated + (check-mode-line-value "* This is a long headline blah blah blah" + "[0: " + 3)) ;; Verify that 'org-mode-line-clock-overrun face is applied if the task has ;; overrun is alloted time and there is no overrun text defined (should -- 2.52.0
>From 131c9f1955059dce251fb1b673a5270320ee861a Mon Sep 17 00:00:00 2001 From: Morgan Smith <[email protected]> Date: Wed, 31 Dec 2025 19:37:00 -0500 Subject: [PATCH 6/8] test-org-clock/mode-line: Test mode-line variables * testing/lisp/test-org-clock.el (test-org-clock/mode-line): Instead of checking the format function, check the actual mode-line variables as that is what the user sees. --- testing/lisp/test-org-clock.el | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/testing/lisp/test-org-clock.el b/testing/lisp/test-org-clock.el index b46ee624e..f38646319 100644 --- a/testing/lisp/test-org-clock.el +++ b/testing/lisp/test-org-clock.el @@ -16,6 +16,9 @@ (require 'org-duration) (require 'org-clock) +(eval-when-compile + (require 'test-duplicates-detector "../testing/lisp/test-duplicates-detector")) + (defun org-test-clock-create-timestamp (input &optional inactive with-time) "Create a timestamp out of a date/time prompt string. @@ -1489,14 +1492,22 @@ test-org-clock/mode-line elements display properly)\" per the Info node `(elisp)Mode Line Variables'." (cl-flet* - ((check-mode-line-value (buffer-string expected &optional max-length) - (should - (equal expected - (org-test-with-temp-text - buffer-string - (org-clock-in) - (prog1 (org-clock-get-clock-string max-length) - (org-clock-out))))))) + ((in-global-mode-string () + (memq 'org-mode-line-string global-mode-string)) + (check-mode-line-value (buffer-string expected &optional max-length) + (org-test-ignore-duplicate + (should (not (in-global-mode-string))) + (should + (equal expected + (let ((org-clock-clocked-in-display 'mode-line) + (org-clock-string-limit (or max-length 0))) + (org-test-with-temp-text + buffer-string + (org-clock-in) + (should (in-global-mode-string)) + (prog1 org-mode-line-string + (org-clock-out)))))) + (should (not (in-global-mode-string)))))) ;; Test the variant without effort. (check-mode-line-value "* Heading" "[0:00] (Heading) ") ;; Test the variant with effort. -- 2.52.0
>From bbfabd96a471326914b3b908b42ffb304e95afe7 Mon Sep 17 00:00:00 2001 From: Morgan Smith <[email protected]> Date: Wed, 31 Dec 2025 19:39:55 -0500 Subject: [PATCH 7/8] test-org-clock/mode-line: Ensure timers are running * testing/lisp/test-org-clock.el (test-org-clock/mode-line): Ensure timers are running. --- testing/lisp/test-org-clock.el | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/testing/lisp/test-org-clock.el b/testing/lisp/test-org-clock.el index f38646319..32f96bbc7 100644 --- a/testing/lisp/test-org-clock.el +++ b/testing/lisp/test-org-clock.el @@ -1494,9 +1494,11 @@ test-org-clock/mode-line (cl-flet* ((in-global-mode-string () (memq 'org-mode-line-string global-mode-string)) + (timers-active () (memq org-clock-mode-line-timer timer-list)) (check-mode-line-value (buffer-string expected &optional max-length) (org-test-ignore-duplicate (should (not (in-global-mode-string))) + (should (not (timers-active))) (should (equal expected (let ((org-clock-clocked-in-display 'mode-line) @@ -1505,9 +1507,11 @@ test-org-clock/mode-line buffer-string (org-clock-in) (should (in-global-mode-string)) + (should (timers-active)) (prog1 org-mode-line-string (org-clock-out)))))) - (should (not (in-global-mode-string)))))) + (should (not (in-global-mode-string))) + (should (not (timers-active)))))) ;; Test the variant without effort. (check-mode-line-value "* Heading" "[0:00] (Heading) ") ;; Test the variant with effort. -- 2.52.0
>From ce08a6a08157f5a559a2c59d39d086606a3de469 Mon Sep 17 00:00:00 2001 From: Morgan Smith <[email protected]> Date: Wed, 31 Dec 2025 19:45:23 -0500 Subject: [PATCH 8/8] test-org-clock/mode-line: Add test for canceling a clock * testing/lisp/test-org-clock.el (test-org-clock/mode-line): Make sure the mode-line is updated when the clock is canceled. --- testing/lisp/test-org-clock.el | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/testing/lisp/test-org-clock.el b/testing/lisp/test-org-clock.el index 32f96bbc7..980e61bd0 100644 --- a/testing/lisp/test-org-clock.el +++ b/testing/lisp/test-org-clock.el @@ -1495,7 +1495,8 @@ test-org-clock/mode-line ((in-global-mode-string () (memq 'org-mode-line-string global-mode-string)) (timers-active () (memq org-clock-mode-line-timer timer-list)) - (check-mode-line-value (buffer-string expected &optional max-length) + (check-mode-line-value (buffer-string expected + &optional max-length cancel-clock?) (org-test-ignore-duplicate (should (not (in-global-mode-string))) (should (not (timers-active))) @@ -1509,11 +1510,15 @@ test-org-clock/mode-line (should (in-global-mode-string)) (should (timers-active)) (prog1 org-mode-line-string - (org-clock-out)))))) + (if cancel-clock? + (org-clock-cancel) + (org-clock-out))))))) (should (not (in-global-mode-string))) (should (not (timers-active)))))) - ;; Test the variant without effort. + ;; Simplest test (check-mode-line-value "* Heading" "[0:00] (Heading) ") + ;; Cancel clock test + (check-mode-line-value "* Heading" "[0:00] (Heading) " nil t) ;; Test the variant with effort. (check-mode-line-value "* Heading :PROPERTIES: -- 2.52.0
