emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master b44f0c4 2/2: Allow passing unknown specs to format-


From: Lars Ingebrigtsen
Subject: [Emacs-diffs] master b44f0c4 2/2: Allow passing unknown specs to format-spec
Date: Thu, 11 Jul 2019 12:44:44 -0400 (EDT)

branch: master
commit b44f0c457997af53808218536ebfdf507ddb5995
Author: Lars Ingebrigtsen <address@hidden>
Commit: Lars Ingebrigtsen <address@hidden>

    Allow passing unknown specs to format-spec
    
    * lisp/format-spec.el (format-spec): Allow passing through format
    strings that have no specs (to be able to act as a filter).  Also
    add an example.
    * test/lisp/format-spec-tests.el (test-format-spec): Add tests for
    the new functionality.
---
 lisp/format-spec.el            | 69 +++++++++++++++++++++++++-----------------
 test/lisp/format-spec-tests.el | 12 +++++++-
 2 files changed, 53 insertions(+), 28 deletions(-)

diff --git a/lisp/format-spec.el b/lisp/format-spec.el
index 4455c59..cf2d364 100644
--- a/lisp/format-spec.el
+++ b/lisp/format-spec.el
@@ -24,40 +24,55 @@
 
 ;;; Code:
 
-(defun format-spec (format specification)
+(defun format-spec (format specification &optional only-present)
   "Return a string based on FORMAT and SPECIFICATION.
-FORMAT is a string containing `format'-like specs like \"bash %u %k\",
+FORMAT is a string containing `format'-like specs like \"su - %u %k\",
 while SPECIFICATION is an alist mapping from format spec characters
-to values.  Any text properties on a %-spec itself are propagated to
-the text that it generates."
+to values.
+
+For instance:
+
+  (format-spec \"su - %u %k\"
+               `((?u . ,(user-login-name))
+                 (?k . \"ls\")))
+
+Any text properties on a %-spec itself are propagated to the text
+that it generates.
+
+If ONLY-PRESENT, format spec characters not present in
+SPECIFICATION are ignored, and the \"%\" characters are left
+where they are, including \"%%\" strings."
   (with-temp-buffer
     (insert format)
     (goto-char (point-min))
     (while (search-forward "%" nil t)
       (cond
-       ;; Quoted percent sign.
-       ((eq (char-after) ?%)
-       (delete-char 1))
-       ;; Valid format spec.
-       ((looking-at "\\([-0-9.]*\\)\\([a-zA-Z]\\)")
-       (let* ((num (match-string 1))
-              (spec (string-to-char (match-string 2)))
-              (val (assq spec specification)))
-         (unless val
-           (error "Invalid format character: `%%%c'" spec))
-         (setq val (cdr val))
-         ;; Pad result to desired length.
-         (let ((text (format (concat "%" num "s") val)))
-           ;; Insert first, to preserve text properties.
-           (insert-and-inherit text)
-           ;; Delete the specifier body.
-            (delete-region (+ (match-beginning 0) (length text))
-                           (+ (match-end 0) (length text)))
-            ;; Delete the percent sign.
-            (delete-region (1- (match-beginning 0)) (match-beginning 0)))))
-       ;; Signal an error on bogus format strings.
-       (t
-       (error "Invalid format string"))))
+        ;; Quoted percent sign.
+        ((eq (char-after) ?%)
+         (unless only-present
+          (delete-char 1)))
+        ;; Valid format spec.
+        ((looking-at "\\([-0-9.]*\\)\\([a-zA-Z]\\)")
+        (let* ((num (match-string 1))
+               (spec (string-to-char (match-string 2)))
+               (val (assq spec specification)))
+          (if (not val)
+               (unless only-present
+                (error "Invalid format character: `%%%c'" spec))
+            (setq val (cdr val))
+            ;; Pad result to desired length.
+            (let ((text (format (concat "%" num "s") val)))
+              ;; Insert first, to preserve text properties.
+              (insert-and-inherit text)
+              ;; Delete the specifier body.
+               (delete-region (+ (match-beginning 0) (length text))
+                              (+ (match-end 0) (length text)))
+               ;; Delete the percent sign.
+               (delete-region (1- (match-beginning 0)) (match-beginning 0))))))
+        ;; Signal an error on bogus format strings.
+        (t
+          (unless only-present
+           (error "Invalid format string")))))
     (buffer-string)))
 
 (defun format-spec-make (&rest pairs)
diff --git a/test/lisp/format-spec-tests.el b/test/lisp/format-spec-tests.el
index a5c62ac..e831657 100644
--- a/test/lisp/format-spec-tests.el
+++ b/test/lisp/format-spec-tests.el
@@ -23,11 +23,21 @@
 (require 'format-spec)
 
 (ert-deftest test-format-spec ()
-  (should (equal (format-spec "foo %b zot" '((?b . "bar")))
+  (should (equal (format-spec "foo %b zot" `((?b . "bar")))
                  "foo bar zot"))
   (should (equal (format-spec "foo %-10b zot" '((?b . "bar")))
                  "foo bar        zot"))
   (should (equal (format-spec "foo %10b zot" '((?b . "bar")))
                  "foo        bar zot")))
 
+(ert-deftest test-format-unknown ()
+  (should (eq (condition-case _
+                  (format-spec "foo %b %z zot" '((?b . "bar")))
+                (error :error))
+              :error))
+  (should (equal (format-spec "foo %b %z zot" '((?b . "bar")) t)
+                 "foo bar %z zot"))
+  (should (equal (format-spec "foo %b %z %% zot" '((?b . "bar")) t)
+                 "foo bar %z %% zot")))
+
 ;;; format-spec-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]