summaryrefslogtreecommitdiff
path: root/lisp/format-spec.el
diff options
context:
space:
mode:
authorStefan Kangas <stefankangas@gmail.com>2022-09-27 18:16:51 +0200
committerStefan Kangas <stefankangas@gmail.com>2022-09-29 15:39:27 +0200
commit5281946fbf6b3cdbec5ce82e0057c71849faf4d2 (patch)
tree8f519625372642a2faaa4a1bf314a07e2e283a6b /lisp/format-spec.el
parent423bdd5f7f273f40f750eac83017074501d52823 (diff)
downloademacs-5281946fbf6b3cdbec5ce82e0057c71849faf4d2.tar.gz
Make format-spec accept function substitutions
* lisp/format-spec.el (format-spec): Accept a function producing the substitution for a character. * doc/lispref/strings.texi (Custom Format Strings): Document the above change. * test/lisp/format-spec-tests.el (format-spec/function): New test. Ref. https://lists.gnu.org/r/emacs-devel/2022-09/msg01875.html
Diffstat (limited to 'lisp/format-spec.el')
-rw-r--r--lisp/format-spec.el17
1 files changed, 15 insertions, 2 deletions
diff --git a/lisp/format-spec.el b/lisp/format-spec.el
index 45c19aebc8b..60ff9f90864 100644
--- a/lisp/format-spec.el
+++ b/lisp/format-spec.el
@@ -59,6 +59,18 @@ value associated with ?b in SPECIFICATION, either padding it with
leading zeros or truncating leading characters until it's ten
characters wide\".
+the substitution for a specification character can also be a
+function, taking no arguments and returning a string to be used
+for the replacement. It will only be called if FORMAT uses that
+character. For example:
+
+ (format-spec \"%n\"
+ \\=`((?n . ,(lambda ()
+ (read-number \"Number: \")))))
+
+Note that it is best to make sure the function is not quoted,
+like above, so that it is compiled by the byte-compiler.
+
Any text properties of FORMAT are copied to the result, with any
text properties of a %-spec itself copied to its substitution.
@@ -94,14 +106,15 @@ is returned, where each format spec is its own element."
(width (match-string 2))
(trunc (match-string 3))
(char (string-to-char (match-string 4)))
- (text (assq char specification)))
+ (text (let ((res (cdr (assq char specification))))
+ (if (functionp res) (funcall res) res))))
(when (and split
(not (= (1- beg) split-start)))
(push (buffer-substring split-start (1- beg)) split-result))
(cond (text
;; Handle flags.
(setq text (format-spec--do-flags
- (format "%s" (cdr text))
+ (format "%s" text)
(format-spec--parse-flags flags)
(and width (string-to-number width))
(and trunc (car (read-from-string trunc 1)))))