From e0a1a678e27a6a3da5e12edfcc7323c5204f6d2a Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Tue, 27 Sep 2022 18:16:51 +0200 Subject: [PATCH] Make format-spec support functions --- lisp/format-spec.el | 15 +++++++++++++-- test/lisp/format-spec-tests.el | 12 ++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lisp/format-spec.el b/lisp/format-spec.el index 45c19aebc8..31e1d861c2 100644 --- a/lisp/format-spec.el +++ b/lisp/format-spec.el @@ -59,6 +59,16 @@ format-spec leading zeros or truncating leading characters until it's ten characters wide\". +If the value is a function, it will be evaluated only when +needed. For example: + + (format-spec \"%n\" + \\=`((?n . ,(lambda () + (read-number \"Number: \"))))) + +Note that it is better to make sure the lambda 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 +104,15 @@ format-spec (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 (and (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))))) diff --git a/test/lisp/format-spec-tests.el b/test/lisp/format-spec-tests.el index 4a3cc74c33..f137f94aaa 100644 --- a/test/lisp/format-spec-tests.el +++ b/test/lisp/format-spec-tests.el @@ -148,6 +148,18 @@ format-spec (format-spec fmt '((?b . "asd") (?a . "fgh"))) #("fgh%asdasd" 0 3 (a b) 3 4 (c d) 7 10 (e f)))))) +(ert-deftest format-spec/function () + (let* (called + (spec `((?a . "foo") + (?f . ,(lambda () + (setq called t) + "bar"))))) + (should (equal (format-spec "%a" spec) "foo")) + (should-not called) + (should (equal (format-spec "%f" spec) "bar")) + (should called))) + + (ert-deftest format-spec-unknown () (should-error (format-spec "foo %b %z zot" '((?b . "bar")))) (should-error (format-spec "foo %b %%%z zot" '((?b . "bar")))) -- 2.30.2