aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.org42
-rw-r--r--chime.el63
-rw-r--r--tests/test-chime-make-tooltip.el7
-rw-r--r--tests/test-chime-notification-text.el9
-rw-r--r--tests/test-chime-propertize-modeline.el7
-rw-r--r--tests/test-chime-time-left.el21
6 files changed, 82 insertions, 67 deletions
diff --git a/README.org b/README.org
index 258cabc..fd8081c 100644
--- a/README.org
+++ b/README.org
@@ -436,7 +436,7 @@ Customize which components are shown:
Available placeholders:
- =%t= - Event title
- =%T= - Event time (formatted per =chime-display-time-format-string=)
-- =%u= - Time until event (formatted per =chime-time-left-format-*=)
+- =%u= - Time until event (formatted per =chime-time-left-formats=)
***** Event Time Format
@@ -471,24 +471,35 @@ Available format codes:
Customize how the countdown is displayed:
+All three formats live in one alist, =chime-time-left-formats=, with three keys:
+=at-event= (literal string when the event has arrived), =short=
+(=format-seconds= template for under 1 hour), and =long= (template for 1 hour
+or more).
+
#+BEGIN_SRC elisp
;; Default: verbose format
-(setq chime-time-left-format-short "in %M") ; Under 1 hour
-(setq chime-time-left-format-long "in %H %M") ; 1 hour or more
+(setq chime-time-left-formats
+ '((at-event . "right now")
+ (short . "in %M")
+ (long . "in %H %M")))
;; → "in 10 minutes" or "in 1 hour 30 minutes"
;; Compact format
-(setq chime-time-left-format-short "in %mm")
-(setq chime-time-left-format-long "in %hh %mm")
+(setq chime-time-left-formats
+ '((at-event . "right now")
+ (short . "in %mm")
+ (long . "in %hh %mm")))
;; → "in 10m" or "in 1h 30m"
;; Very compact (no prefix)
-(setq chime-time-left-format-short "%mm")
-(setq chime-time-left-format-long "%hh%mm")
+(setq chime-time-left-formats
+ '((at-event . "right now")
+ (short . "%mm")
+ (long . "%hh%mm")))
;; → "10m" or "1h30m"
-;; Custom "at event time" message
-(setq chime-time-left-format-at-event "NOW!")
+;; Tweak just one key — `setf' on `alist-get' is fine for one-shots
+(setf (alist-get 'at-event chime-time-left-formats) "NOW!")
;; → "NOW!" instead of "right now"
#+END_SRC
@@ -529,8 +540,10 @@ For maximum modeline space savings:
(setq chime-modeline-lookahead-minutes 60)
(setq chime-modeline-format " ⏰ %s") ; Minimal prefix
(setq chime-notification-text-format "%t (%u)") ; No time shown
-(setq chime-time-left-format-short "%mm") ; Compact short
-(setq chime-time-left-format-long "%hh%mm") ; Compact long
+(setq chime-time-left-formats ; Compact countdown
+ '((at-event . "right now")
+ (short . "%mm")
+ (long . "%hh%mm")))
(setq chime-max-title-length 20) ; Truncate long titles
;; Result: "⏰ Dentist (10m)" or "⏰ Retrospective o... (1h30m)"
#+END_SRC
@@ -835,9 +848,10 @@ If you have custom variables that need to be available in chime's async subproce
(setq chime-modeline-format " ⏰%s") ; Minimal prefix
(setq chime-notification-text-format "%t (%u)") ; Title + countdown only
(setq chime-display-time-format-string "%H:%M") ; 24-hour time
- (setq chime-time-left-format-short "in %mm") ; Compact: "in 5m"
- (setq chime-time-left-format-long "%hh%mm") ; Compact: "1h30m"
- (setq chime-time-left-format-at-event "NOW!") ; Custom at-event message
+ (setq chime-time-left-formats ; Countdown formats
+ '((at-event . "NOW!")
+ (short . "in %mm")
+ (long . "%hh%mm")))
;; Notification settings
(setq chime-notification-title "Reminder")
diff --git a/chime.el b/chime.el
index e843537..9de2e72 100644
--- a/chime.el
+++ b/chime.el
@@ -224,43 +224,40 @@ Note: Avoid using seconds (%S) as chime polls once per minute."
(warn "chime-display-time-format-string: Using seconds (%%S) is not recommended as chime polls once per minute"))
(set-default symbol value)))
-(defcustom chime-time-left-format-at-event "right now"
- "Format string for when event time has arrived (0 or negative seconds).
-This is a literal string with no format codes."
- :package-version '(chime . "0.6.0")
- :group 'chime
- :type 'string)
-
-(defcustom chime-time-left-format-short "in %M"
- "Format string for times under 1 hour.
-Uses `format-seconds' codes:
+(defcustom chime-time-left-formats
+ '((at-event . "right now")
+ (short . "in %M")
+ (long . "in %H %M"))
+ "Format strings for time-until-event display, keyed by regime.
+An alist with three keys:
+
+ at-event - Literal string when event time has arrived (0 or negative
+ seconds). No format codes.
+ short - `format-seconds' template for times under 1 hour.
+ long - `format-seconds' template for times 1 hour or longer.
+
+Available `format-seconds' codes for short/long:
%m - minutes as number only (e.g., \"37\")
%M - minutes with unit name (e.g., \"37 minutes\")
+ %h - hours as number only (e.g., \"1\")
+ %H - hours with unit name (e.g., \"1 hour\")
-Examples:
+Examples for short:
\"in %M\" -> \"in 37 minutes\"
\"in %mm\" -> \"in 37m\"
- \"%m min\" -> \"37 min\""
- :package-version '(chime . "0.6.0")
- :group 'chime
- :type 'string)
+ \"%m min\" -> \"37 min\"
-(defcustom chime-time-left-format-long "in %H %M"
- "Format string for times 1 hour or longer.
-Uses `format-seconds' codes:
- %h - hours as number only (e.g., \"1\")
- %H - hours with unit name (e.g., \"1 hour\")
- %m - minutes as number only (e.g., \"37\")
- %M - minutes with unit name (e.g., \"37 minutes\")
-
-Examples:
+Examples for long:
\"in %H %M\" -> \"in 1 hour 37 minutes\"
\"in %hh %mm\" -> \"in 1h 37m\"
\"(%h hr %m min)\" -> \"(1 hr 37 min)\"
\"%hh%mm\" -> \"1h37m\""
- :package-version '(chime . "0.6.0")
+ :package-version '(chime . "0.8.0")
:group 'chime
- :type 'string)
+ :type '(alist :key-type (choice (const at-event)
+ (const short)
+ (const long))
+ :value-type string))
(defcustom chime-predicate-whitelist nil
"Receive notifications for events matching these predicates only.
@@ -699,16 +696,16 @@ Returns non-nil only if the timestamp includes HH:MM time information."
(defun chime--time-left (seconds)
"Human-friendly representation for SECONDS.
-Format is controlled by `chime-time-left-format-at-event',
-`chime-time-left-format-short', and `chime-time-left-format-long'."
+Format is controlled by `chime-time-left-formats' (keys: at-event,
+short, long)."
;; Don't fold this into a `(-> seconds (pcase ...) ...)' threading form —
;; edebug's defun parser rejects threaded pcase, which breaks coverage
;; instrumentation (undercover) on this file.
- (let ((format-string
- (pcase seconds
- ((pred (>= 0)) chime-time-left-format-at-event)
- ((pred (>= 3600)) chime-time-left-format-short)
- (_ chime-time-left-format-long))))
+ (let* ((regime (pcase seconds
+ ((pred (>= 0)) 'at-event)
+ ((pred (>= 3600)) 'short)
+ (_ 'long)))
+ (format-string (alist-get regime chime-time-left-formats)))
(format-seconds format-string seconds)))
(defun chime--get-hh-mm-from-org-time-string (time-string)
diff --git a/tests/test-chime-make-tooltip.el b/tests/test-chime-make-tooltip.el
index 2c9cf37..7ace684 100644
--- a/tests/test-chime-make-tooltip.el
+++ b/tests/test-chime-make-tooltip.el
@@ -40,9 +40,10 @@
(setq chime-modeline-tooltip-max-events 5)
(setq chime-tooltip-header-format "Upcoming Events as of %a %b %d %Y @ %I:%M %p")
(setq chime-display-time-format-string "%I:%M %p")
- (setq chime-time-left-format-at-event "right now")
- (setq chime-time-left-format-short "in %M")
- (setq chime-time-left-format-long "in %H %M"))
+ (setq chime-time-left-formats
+ (list (cons 'at-event "right now")
+ (cons 'short "in %M")
+ (cons 'long "in %H %M"))))
(defun test-chime-make-tooltip-teardown ()
"Teardown function run after each test."
diff --git a/tests/test-chime-notification-text.el b/tests/test-chime-notification-text.el
index 2446004..a707d29 100644
--- a/tests/test-chime-notification-text.el
+++ b/tests/test-chime-notification-text.el
@@ -40,9 +40,10 @@
;; Reset notification text format to default
(setq chime-notification-text-format "%t at %T (%u)")
;; Reset time-left formats to defaults
- (setq chime-time-left-format-at-event "right now")
- (setq chime-time-left-format-short "in %M")
- (setq chime-time-left-format-long "in %H %M")
+ (setq chime-time-left-formats
+ (list (cons 'at-event "right now")
+ (cons 'short "in %M")
+ (cons 'long "in %H %M")))
;; Reset title truncation to default (no truncation)
(setq chime-max-title-length nil))
@@ -331,7 +332,7 @@ REFACTORED: Uses dynamic timestamps"
(str-interval (cons (test-timestamp-string time) '(10 . medium)))
(event '((title . "Meeting")))
(chime-notification-text-format "%t (%u)")
- (chime-time-left-format-short "in %mm"))
+ (chime-time-left-formats '((at-event . "right now") (short . "in %mm") (long . "in %H %M"))))
(let ((result (chime--notification-text str-interval event)))
(should (stringp result))
(should (string-equal "Meeting (in 10m)" result))))
diff --git a/tests/test-chime-propertize-modeline.el b/tests/test-chime-propertize-modeline.el
index 3856831..cc0dbb2 100644
--- a/tests/test-chime-propertize-modeline.el
+++ b/tests/test-chime-propertize-modeline.el
@@ -38,9 +38,10 @@
(chime-create-test-base-dir)
(setq chime-tooltip-header-format "Upcoming Events as of %a %b %d %Y @ %I:%M %p")
(setq chime-display-time-format-string "%I:%M %p")
- (setq chime-time-left-format-at-event "right now")
- (setq chime-time-left-format-short "in %M")
- (setq chime-time-left-format-long "in %H %M"))
+ (setq chime-time-left-formats
+ (list (cons 'at-event "right now")
+ (cons 'short "in %M")
+ (cons 'long "in %H %M"))))
(defun test-chime-propertize-teardown ()
"Teardown function."
diff --git a/tests/test-chime-time-left.el b/tests/test-chime-time-left.el
index 25b41d9..b9bd176 100644
--- a/tests/test-chime-time-left.el
+++ b/tests/test-chime-time-left.el
@@ -35,9 +35,10 @@
"Setup function run before each test."
(chime-create-test-base-dir)
;; Reset format strings to defaults
- (setq chime-time-left-format-at-event "right now")
- (setq chime-time-left-format-short "in %M")
- (setq chime-time-left-format-long "in %H %M"))
+ (setq chime-time-left-formats
+ (list (cons 'at-event "right now")
+ (cons 'short "in %M")
+ (cons 'long "in %H %M"))))
(defun test-chime-time-left-teardown ()
"Teardown function run after each test."
@@ -216,7 +217,7 @@
(test-chime-time-left-setup)
(unwind-protect
(progn
- (setq chime-time-left-format-short "in %mm")
+ (setf (alist-get 'short chime-time-left-formats) "in %mm")
(let ((result (chime--time-left 300))) ; 5 minutes
(should (stringp result))
(should (string-equal "in 5m" result))))
@@ -227,7 +228,7 @@
(test-chime-time-left-setup)
(unwind-protect
(progn
- (setq chime-time-left-format-long "in %hh %mm")
+ (setf (alist-get 'long chime-time-left-formats) "in %hh %mm")
(let ((result (chime--time-left 5820))) ; 1 hour 37 minutes
(should (stringp result))
(should (string-equal "in 1h 37m" result))))
@@ -238,7 +239,7 @@
(test-chime-time-left-setup)
(unwind-protect
(progn
- (setq chime-time-left-format-long "(%h hr %m min)")
+ (setf (alist-get 'long chime-time-left-formats) "(%h hr %m min)")
(let ((result (chime--time-left 5820))) ; 1 hour 37 minutes
(should (stringp result))
(should (string-equal "(1 hr 37 min)" result))))
@@ -249,7 +250,7 @@
(test-chime-time-left-setup)
(unwind-protect
(progn
- (setq chime-time-left-format-long "%hh%mm")
+ (setf (alist-get 'long chime-time-left-formats) "%hh%mm")
(let ((result (chime--time-left 5820))) ; 1 hour 37 minutes
(should (stringp result))
(should (string-equal "1h37m" result))))
@@ -260,7 +261,7 @@
(test-chime-time-left-setup)
(unwind-protect
(progn
- (setq chime-time-left-format-at-event "NOW!")
+ (setf (alist-get 'at-event chime-time-left-formats) "NOW!")
(let ((result (chime--time-left 0)))
(should (stringp result))
(should (string-equal "NOW!" result))))
@@ -271,7 +272,7 @@
(test-chime-time-left-setup)
(unwind-protect
(progn
- (setq chime-time-left-format-short "%m min")
+ (setf (alist-get 'short chime-time-left-formats) "%m min")
(let ((result (chime--time-left 300))) ; 5 minutes
(should (stringp result))
(should (string-equal "5 min" result))))
@@ -282,7 +283,7 @@
(test-chime-time-left-setup)
(unwind-protect
(progn
- (setq chime-time-left-format-long "🕐 %hh%mm")
+ (setf (alist-get 'long chime-time-left-formats) "🕐 %hh%mm")
(let ((result (chime--time-left 5820))) ; 1 hour 37 minutes
(should (stringp result))
(should (string-equal "🕐 1h37m" result))))