aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2022-04-13 15:31:02 +0200
committerLars Ingebrigtsen2022-04-13 15:31:34 +0200
commit918669cb3db21eebc9fb409098a4395f131379ee (patch)
tree0b0dbff24165be2804c9911ba05cfca22b862ced
parente587fc05a70c08a50258b152bb5403afd013007d (diff)
downloademacs-918669cb3db21eebc9fb409098a4395f131379ee.tar.gz
emacs-918669cb3db21eebc9fb409098a4395f131379ee.zip
Make list-times not include zero elements
* doc/lispref/os.texi (Time Parsing): Mention %x. * lisp/calendar/time-date.el (format-seconds): Accept a new %x spec that removes trailing zeros (bug#54904). * lisp/emacs-lisp/timer-list.el (list-timers): Don't display trailing zero bits.
-rw-r--r--doc/lispref/os.texi4
-rw-r--r--etc/NEWS5
-rw-r--r--lisp/calendar/time-date.el56
-rw-r--r--lisp/emacs-lisp/timer-list.el2
-rw-r--r--test/lisp/calendar/time-date-tests.el9
5 files changed, 57 insertions, 19 deletions
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index 9cb9bc75d04..4ee893f860f 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -1961,6 +1961,10 @@ encountered. For example, the default format used by
1961@w{@code{"%Y, %D, %H, %M, %z%S"}} means that the number of seconds 1961@w{@code{"%Y, %D, %H, %M, %z%S"}} means that the number of seconds
1962will always be produced, but years, days, hours, and minutes will only 1962will always be produced, but years, days, hours, and minutes will only
1963be shown if they are non-zero. 1963be shown if they are non-zero.
1964@item %x
1965Non-printing control flag that works along the same lines as
1966@samp{%z}, but instead suppresses printing of trailing zero-value time
1967elements.
1964@item %% 1968@item %%
1965Produces a literal @samp{%}. 1969Produces a literal @samp{%}.
1966@end table 1970@end table
diff --git a/etc/NEWS b/etc/NEWS
index 8665a825ce7..c24f3f6ed5a 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1857,6 +1857,11 @@ month, day, or time. For example, (date-to-time "2021-12-04") now
1857assumes a time of 00:00 instead of signaling an error. 1857assumes a time of 00:00 instead of signaling an error.
1858 1858
1859+++ 1859+++
1860** 'format-seconds' now allows suppressing zero-value trailing elements.
1861The new "%x" non-printing control character will suppress zero-value
1862elements that appear after "%x".
1863
1864+++
1860** New events for taking advantage of touchscreen devices. 1865** New events for taking advantage of touchscreen devices.
1861The events 'touchscreen-begin, 'touchscreen-update', and 1866The events 'touchscreen-begin, 'touchscreen-update', and
1862'touchscreen-end' have been added to take better advantage of 1867'touchscreen-end' have been added to take better advantage of
diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el
index 51cf7eb213f..0db973ea161 100644
--- a/lisp/calendar/time-date.el
+++ b/lisp/calendar/time-date.el
@@ -287,17 +287,23 @@ use. \"%,1s\" means \"use one decimal\".
287 287
288The \"%z\" specifier does not print anything. When it is used, specifiers 288The \"%z\" specifier does not print anything. When it is used, specifiers
289must be given in order of decreasing size. To the left of \"%z\", nothing 289must be given in order of decreasing size. To the left of \"%z\", nothing
290is output until the first non-zero unit is encountered." 290is output until the first non-zero unit is encountered.
291
292The \"%x\" specifier does not print anything. When it is used,
293specifiers must be given in order of decreasing size. To the
294right of \"%x\", trailing zero units are not output."
291 (let ((start 0) 295 (let ((start 0)
292 (units '(("y" "year" 31536000) 296 (units '(("y" "year" 31536000)
293 ("d" "day" 86400) 297 ("d" "day" 86400)
294 ("h" "hour" 3600) 298 ("h" "hour" 3600)
295 ("m" "minute" 60) 299 ("m" "minute" 60)
296 ("s" "second" 1) 300 ("s" "second" 1)
297 ("z"))) 301 ("z")
302 ("x")))
298 (case-fold-search t) 303 (case-fold-search t)
299 spec match usedunits zeroflag larger prev name unit num zeropos 304 spec match usedunits zeroflag larger prev name unit num
300 fraction) 305 leading-zeropos trailing-zeropos fraction
306 chop-leading chop-trailing)
301 (while (string-match "%\\.?[0-9]*\\(,[0-9]\\)?\\(.\\)" string start) 307 (while (string-match "%\\.?[0-9]*\\(,[0-9]\\)?\\(.\\)" string start)
302 (setq start (match-end 0) 308 (setq start (match-end 0)
303 spec (match-string 2 string)) 309 spec (match-string 2 string))
@@ -306,15 +312,16 @@ is output until the first non-zero unit is encountered."
306 (error "Bad format specifier: `%s'" spec)) 312 (error "Bad format specifier: `%s'" spec))
307 (if (assoc (downcase spec) usedunits) 313 (if (assoc (downcase spec) usedunits)
308 (error "Multiple instances of specifier: `%s'" spec)) 314 (error "Multiple instances of specifier: `%s'" spec))
309 (if (string-equal (car match) "z") 315 (if (or (string-equal (car match) "z")
316 (string-equal (car match) "x"))
310 (setq zeroflag t) 317 (setq zeroflag t)
311 (unless larger 318 (unless larger
312 (setq unit (nth 2 match) 319 (setq unit (nth 2 match)
313 larger (and prev (> unit prev)) 320 larger (and prev (> unit prev))
314 prev unit))) 321 prev unit)))
315 (push match usedunits))) 322 (push match usedunits)))
316 (and zeroflag larger 323 (when (and zeroflag larger)
317 (error "Units are not in decreasing order of size")) 324 (error "Units are not in decreasing order of size"))
318 (unless (numberp seconds) 325 (unless (numberp seconds)
319 (setq seconds (float-time seconds))) 326 (setq seconds (float-time seconds)))
320 (setq fraction (mod seconds 1) 327 (setq fraction (mod seconds 1)
@@ -326,18 +333,25 @@ is output until the first non-zero unit is encountered."
326 (when (string-match 333 (when (string-match
327 (format "%%\\(\\.?[0-9]+\\)?\\(,[0-9]+\\)?\\(%s\\)" spec) 334 (format "%%\\(\\.?[0-9]+\\)?\\(,[0-9]+\\)?\\(%s\\)" spec)
328 string) 335 string)
329 (if (string-equal spec "z") ; must be last in units 336 (cond
330 (setq string 337 ((string-equal spec "z")
331 (replace-regexp-in-string 338 (setq chop-leading (and leading-zeropos
332 "%z" "" 339 (min leading-zeropos (match-beginning 0)))))
333 (substring string (min (or zeropos (match-end 0)) 340 ((string-equal spec "x")
334 (match-beginning 0))))) 341 (setq chop-trailing t))
342 (t
335 ;; Cf article-make-date-line in gnus-art. 343 ;; Cf article-make-date-line in gnus-art.
336 (setq num (floor seconds unit) 344 (setq num (floor seconds unit)
337 seconds (- seconds (* num unit))) 345 seconds (- seconds (* num unit)))
338 ;; Start position of the first non-zero unit. 346 ;; Start position of the first non-zero unit.
339 (or zeropos 347 (when (and (not leading-zeropos)
340 (setq zeropos (unless (zerop num) (match-beginning 0)))) 348 (not (zerop num)))
349 (setq leading-zeropos (match-beginning 0)))
350 (unless (zerop num)
351 (setq trailing-zeropos nil))
352 (when (and (not trailing-zeropos)
353 (zerop num))
354 (setq trailing-zeropos (match-beginning 0)))
341 (setq string 355 (setq string
342 (replace-match 356 (replace-match
343 (format (if (match-string 2 string) 357 (format (if (match-string 2 string)
@@ -360,7 +374,17 @@ is output until the first non-zero unit is encountered."
360 (format " %s%s" name 374 (format " %s%s" name
361 (if (= num 1) "" "s")))) 375 (if (= num 1) "" "s"))))
362 t t string)))))) 376 t t string))))))
363 (string-replace "%%" "%" string)) 377 (let ((pre string))
378 (when (and chop-trailing trailing-zeropos)
379 (setq string (substring string 0 trailing-zeropos)))
380 (when chop-leading
381 (setq string (substring string chop-leading)))
382 ;; If we ended up removing everything, return the formatted
383 ;; string in full.
384 (when (equal string "")
385 (setq string pre)))
386 (setq string (replace-regexp-in-string "%[zx]" "" string)))
387 (string-trim (string-replace "%%" "%" string)))
364 388
365(defvar seconds-to-string 389(defvar seconds-to-string
366 (list (list 1 "ms" 0.001) 390 (list (list 1 "ms" 0.001)
diff --git a/lisp/emacs-lisp/timer-list.el b/lisp/emacs-lisp/timer-list.el
index c93a50cabfe..aef18d0ba27 100644
--- a/lisp/emacs-lisp/timer-list.el
+++ b/lisp/emacs-lisp/timer-list.el
@@ -62,7 +62,7 @@
62 ((numberp repeat) 62 ((numberp repeat)
63 (propertize 63 (propertize
64 (format "%12s" (format-seconds 64 (format "%12s" (format-seconds
65 "%dd %hh %mm %z%,1ss" repeat)) 65 "%x%dd %hh %mm %z%,1ss" repeat))
66 'help-echo "Repeat interval")) 66 'help-echo "Repeat interval"))
67 ((null repeat) 67 ((null repeat)
68 (propertize " -" 'help-echo "Runs once")) 68 (propertize " -" 'help-echo "Runs once"))
diff --git a/test/lisp/calendar/time-date-tests.el b/test/lisp/calendar/time-date-tests.el
index 5a37c914931..fd4d5ac8a1b 100644
--- a/test/lisp/calendar/time-date-tests.el
+++ b/test/lisp/calendar/time-date-tests.el
@@ -88,14 +88,19 @@
88(ert-deftest test-format-seconds () 88(ert-deftest test-format-seconds ()
89 (should (equal (format-seconds "%y %d %h %m %s %%" 0) "0 0 0 0 0 %")) 89 (should (equal (format-seconds "%y %d %h %m %s %%" 0) "0 0 0 0 0 %"))
90 (should (equal (format-seconds "%y %d %h %m %s %%" 9999999) "0 115 17 46 39 %")) 90 (should (equal (format-seconds "%y %d %h %m %s %%" 9999999) "0 115 17 46 39 %"))
91 (should (equal (format-seconds "%y %d %h %m %z %s %%" 1) " 1 %")) 91 (should (equal (format-seconds "%y %d %h %m %z %s %%" 1) "1 %"))
92 (should (equal (format-seconds "%mm %ss" 66) "1m 6s")) 92 (should (equal (format-seconds "%mm %ss" 66) "1m 6s"))
93 (should (equal (format-seconds "%mm %5ss" 66) "1m 6s")) 93 (should (equal (format-seconds "%mm %5ss" 66) "1m 6s"))
94 (should (equal (format-seconds "%mm %.5ss" 66.4) "1m 00006s")) 94 (should (equal (format-seconds "%mm %.5ss" 66.4) "1m 00006s"))
95 95
96 (should (equal (format-seconds "%mm %,1ss" 66.4) "1m 6.4s")) 96 (should (equal (format-seconds "%mm %,1ss" 66.4) "1m 6.4s"))
97 (should (equal (format-seconds "%mm %5,1ss" 66.4) "1m 6.4s")) 97 (should (equal (format-seconds "%mm %5,1ss" 66.4) "1m 6.4s"))
98 (should (equal (format-seconds "%mm %.5,1ss" 66.4) "1m 006.4s"))) 98 (should (equal (format-seconds "%mm %.5,1ss" 66.4) "1m 006.4s"))
99
100 (should (equal (format-seconds "%hh %z%x%mm %ss" (* 60 2)) "2m"))
101 (should (equal (format-seconds "%hh %z%mm %ss" (* 60 2)) "2m 0s"))
102 (should (equal (format-seconds "%hh %x%mm %ss" (* 60 2)) "0h 2m"))
103 (should (equal (format-seconds "%hh %x%mm %ss" 0) "0h 0m 0s")))
99 104
100(ert-deftest test-ordinal () 105(ert-deftest test-ordinal ()
101 (should (equal (date-ordinal-to-time 2008 271) 106 (should (equal (date-ordinal-to-time 2008 271)