[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#41758: 28.0.50; Fix and extend format-spec
From: |
Basil L. Contovounesios |
Subject: |
bug#41758: 28.0.50; Fix and extend format-spec |
Date: |
Mon, 08 Jun 2020 00:50:22 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
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
Description: Text Data
- bug#41758: 28.0.50; Fix and extend format-spec,
Basil L. Contovounesios <=