aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2021-02-06 11:54:08 +0200
committerEli Zaretskii2021-02-06 11:54:08 +0200
commitb84b8dff709fd80ee124565222f333f53351ab4a (patch)
tree19eb4e29ca739b28e0e12e1e5c4b9a3cf8cd26c8
parent431b098a206d27a2dff6a88312c28c36926f90e9 (diff)
downloademacs-b84b8dff709fd80ee124565222f333f53351ab4a.tar.gz
emacs-b84b8dff709fd80ee124565222f333f53351ab4a.zip
Fix copying text properties in 'format'
* src/editfns.c (styled_format): Fix accounting for text properties that come from the format string. (Bug#46317) * test/src/editfns-tests.el (format-properties): Add new tests for bug#46317.
-rw-r--r--src/editfns.c10
-rw-r--r--test/src/editfns-tests.el22
2 files changed, 30 insertions, 2 deletions
diff --git a/src/editfns.c b/src/editfns.c
index e3285494c14..991f79abac7 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3134,6 +3134,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
3134 char *format_start = SSDATA (args[0]); 3134 char *format_start = SSDATA (args[0]);
3135 bool multibyte_format = STRING_MULTIBYTE (args[0]); 3135 bool multibyte_format = STRING_MULTIBYTE (args[0]);
3136 ptrdiff_t formatlen = SBYTES (args[0]); 3136 ptrdiff_t formatlen = SBYTES (args[0]);
3137 bool fmt_props = string_intervals (args[0]);
3137 3138
3138 /* Upper bound on number of format specs. Each uses at least 2 chars. */ 3139 /* Upper bound on number of format specs. Each uses at least 2 chars. */
3139 ptrdiff_t nspec_bound = SCHARS (args[0]) >> 1; 3140 ptrdiff_t nspec_bound = SCHARS (args[0]) >> 1;
@@ -3406,13 +3407,20 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
3406 convbytes += padding; 3407 convbytes += padding;
3407 if (convbytes <= buf + bufsize - p) 3408 if (convbytes <= buf + bufsize - p)
3408 { 3409 {
3410 /* If the format spec has properties, we should account
3411 for the padding on the left in the info[] array. */
3412 if (fmt_props)
3413 spec->start = nchars;
3409 if (! minus_flag) 3414 if (! minus_flag)
3410 { 3415 {
3411 memset (p, ' ', padding); 3416 memset (p, ' ', padding);
3412 p += padding; 3417 p += padding;
3413 nchars += padding; 3418 nchars += padding;
3414 } 3419 }
3415 spec->start = nchars; 3420 /* If the properties will come from the argument, we
3421 don't extend them to the left due to padding. */
3422 if (!fmt_props)
3423 spec->start = nchars;
3416 3424
3417 if (p > buf 3425 if (p > buf
3418 && multibyte 3426 && multibyte
diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el
index 64f9137865b..dcec971c12e 100644
--- a/test/src/editfns-tests.el
+++ b/test/src/editfns-tests.el
@@ -106,7 +106,27 @@
106 #("foobar" 3 6 (face error)))) 106 #("foobar" 3 6 (face error))))
107 (should (ert-equal-including-properties 107 (should (ert-equal-including-properties
108 (format (concat "%s " (propertize "%s" 'face 'error)) "foo" "bar") 108 (format (concat "%s " (propertize "%s" 'face 'error)) "foo" "bar")
109 #("foo bar" 4 7 (face error))))) 109 #("foo bar" 4 7 (face error))))
110 ;; Bug #46317
111 (let ((s (propertize "X" 'prop "val")))
112 (should (ert-equal-including-properties
113 (format (concat "%3s/" s) 12)
114 #(" 12/X" 4 5 (prop "val"))))
115 (should (ert-equal-including-properties
116 (format (concat "%3S/" s) 12)
117 #(" 12/X" 4 5 (prop "val"))))
118 (should (ert-equal-including-properties
119 (format (concat "%3d/" s) 12)
120 #(" 12/X" 4 5 (prop "val"))))
121 (should (ert-equal-including-properties
122 (format (concat "%-3s/" s) 12)
123 #("12 /X" 4 5 (prop "val"))))
124 (should (ert-equal-including-properties
125 (format (concat "%-3S/" s) 12)
126 #("12 /X" 4 5 (prop "val"))))
127 (should (ert-equal-including-properties
128 (format (concat "%-3d/" s) 12)
129 #("12 /X" 4 5 (prop "val"))))))
110 130
111;; Tests for bug#5131. 131;; Tests for bug#5131.
112(defun transpose-test-reverse-word (start end) 132(defun transpose-test-reverse-word (start end)