diff options
| author | Eli Zaretskii | 2021-02-06 11:54:08 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2021-02-06 11:54:08 +0200 |
| commit | b84b8dff709fd80ee124565222f333f53351ab4a (patch) | |
| tree | 19eb4e29ca739b28e0e12e1e5c4b9a3cf8cd26c8 | |
| parent | 431b098a206d27a2dff6a88312c28c36926f90e9 (diff) | |
| download | emacs-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.c | 10 | ||||
| -rw-r--r-- | test/src/editfns-tests.el | 22 |
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) |