GNU bug report logs -
#41758
28.0.50; Fix and extend format-spec
Previous Next
Reported by: "Basil L. Contovounesios" <contovob <at> tcd.ie>
Date: Sun, 7 Jun 2020 23:51:02 UTC
Severity: normal
Tags: fixed, patch
Found in version 28.0.50
Fixed in version 28.1
Done: "Basil L. Contovounesios" <contovob <at> tcd.ie>
Bug is archived. No further changes may be made.
Full log
View this message in rfc822 format
[Message part 1 (text/plain, inline)]
Tags: patch
I attach a patch which fixes and extends some of the changes made to
format-spec's behaviour in Emacs 27. Some of the proposed changes were
already alluded to in the discussion of bug#41571.
---
Before Emacs 27, format-spec was implemented in terms of 'format',
allowing e.g.:
(format-spec "%.2s" '((?s . "שָׁלוֹם"))) ; => "שָׁל"
In Emacs 27, a precision modifier ".N" is still supported (doesn't
signal an error), but is a no-op:
(format-spec "%.2s" '((?s . "שָׁלוֹם"))) ; => "שָׁלוֹם"
This is arguably a regression (since format-spec's docstring
historically said it supported "'format'-like specs" without explicitly
listing the precision modifier as one of them). I wouldn't be surprised
if someone misses this feature.
Instead, Emacs 27 added the notion of "padding or truncating" (as a
single operation) to a desired length:
(format-spec "%>2s" '((?s . "שָׁלוֹם"))) ; => "שָ"
There are two problems with this:
0. Unlike 'format', it truncates to length rather than width.
1. It is impossible to specify separate padding and truncation, e.g.:
(format "%3.2s" "שָׁלוֹם") ; => " שָׁל"
The attached patch brings back 'format'-like truncation based on string
width, and separate from padding:
(format-spec "%>2s" '((?s . "שָׁלוֹם"))) ; => "שָׁל"
(format-spec "%3.2s" '((?s . "שָׁלוֹם"))) ; => " שָׁל"
(let ((f "%3.2s")
(s "שָׁלוֹם"))
(equal (format-spec f `((?s . ,s)))
(format f s))) ; => t
---
Emacs 27 also added an optional third argument for ignoring the case
when the caller does not provide a particular replacement, e.g.:
(format-spec "%s" ()) ; => (error "Invalid format character: ‘%s’")
(format-spec "%s" () t) ; => "%s"
The problem with a non-nil third argument is that it also
unconditionally leaves '%%' verbatim in the output:
(format-spec "%%%s" () t) ; => "%%%s"
I'm sure this has its uses, but I find it a surprising default since the
replacement of '%%' is always known. The function battery-format in
lisp/battery.el is an example of where the usual replacement of '%%' is
desirable, even when some replacements are not provided.
The attached patch therefore adds two new special values to the optional
third argument:
(format-spec "%%%s" () 'ignore) ; => "%%s"
(format-spec "%%%s" () 'delete) ; => "%"
Together with the Emacs 27 behaviour, I think these should cover most
bases.
WDYT?
Thanks,
--
Basil
[0001-Fix-and-extend-format-spec.patch (text/x-diff, attachment)]
This bug report was last modified 4 years and 332 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.