diff options
| author | Eli Zaretskii | 2018-08-09 18:08:35 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2018-08-09 18:08:35 +0300 |
| commit | 71c92d89137b7fdde6c2bd4bed9b8dfda5fa53dd (patch) | |
| tree | cbeb28b0a8287a43796cdaaf9ad806446d22d88a | |
| parent | 96be6b6eb99ae1d77702932c97e8b3a147c6265a (diff) | |
| download | emacs-71c92d89137b7fdde6c2bd4bed9b8dfda5fa53dd.tar.gz emacs-71c92d89137b7fdde6c2bd4bed9b8dfda5fa53dd.zip | |
Fix copying text properties by 'format'
* src/editfns.c (styled_format): Add the spec beginning index
to the info recorded for each format spec, and use it to
detect the case that a format spec and its text property end
where the next spec with another property begins. (Bug#32404)
* test/src/editfns-tests.el (format-properties): Add tests for
bug#32404.
| -rw-r--r-- | src/editfns.c | 12 | ||||
| -rw-r--r-- | test/src/editfns-tests.el | 16 |
2 files changed, 25 insertions, 3 deletions
diff --git a/src/editfns.c b/src/editfns.c index a8acff659cd..081ea0b3b7c 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -4257,6 +4257,9 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4257 | /* The start and end bytepos in the output string. */ | 4257 | /* The start and end bytepos in the output string. */ |
| 4258 | ptrdiff_t start, end; | 4258 | ptrdiff_t start, end; |
| 4259 | 4259 | ||
| 4260 | /* The start of the spec in the format string. */ | ||
| 4261 | ptrdiff_t fbeg; | ||
| 4262 | |||
| 4260 | /* Whether the argument is a string with intervals. */ | 4263 | /* Whether the argument is a string with intervals. */ |
| 4261 | bool_bf intervals : 1; | 4264 | bool_bf intervals : 1; |
| 4262 | } *info; | 4265 | } *info; |
| @@ -4408,6 +4411,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4408 | char conversion = *format++; | 4411 | char conversion = *format++; |
| 4409 | memset (&discarded[format0 - format_start], 1, | 4412 | memset (&discarded[format0 - format_start], 1, |
| 4410 | format - format0 - (conversion == '%')); | 4413 | format - format0 - (conversion == '%')); |
| 4414 | info[ispec].fbeg = format0 - format_start; | ||
| 4411 | if (conversion == '%') | 4415 | if (conversion == '%') |
| 4412 | { | 4416 | { |
| 4413 | new_result = true; | 4417 | new_result = true; |
| @@ -4981,7 +4985,9 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4981 | else if (discarded[bytepos] == 1) | 4985 | else if (discarded[bytepos] == 1) |
| 4982 | { | 4986 | { |
| 4983 | position++; | 4987 | position++; |
| 4984 | if (fieldn < nspec && translated == info[fieldn].start) | 4988 | if (fieldn < nspec |
| 4989 | && position > info[fieldn].fbeg | ||
| 4990 | && translated == info[fieldn].start) | ||
| 4985 | { | 4991 | { |
| 4986 | translated += info[fieldn].end - info[fieldn].start; | 4992 | translated += info[fieldn].end - info[fieldn].start; |
| 4987 | fieldn++; | 4993 | fieldn++; |
| @@ -5001,7 +5007,9 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 5001 | else if (discarded[bytepos] == 1) | 5007 | else if (discarded[bytepos] == 1) |
| 5002 | { | 5008 | { |
| 5003 | position++; | 5009 | position++; |
| 5004 | if (fieldn < nspec && translated == info[fieldn].start) | 5010 | if (fieldn < nspec |
| 5011 | && position > info[fieldn].fbeg | ||
| 5012 | && translated == info[fieldn].start) | ||
| 5005 | { | 5013 | { |
| 5006 | translated += info[fieldn].end - info[fieldn].start; | 5014 | translated += info[fieldn].end - info[fieldn].start; |
| 5007 | fieldn++; | 5015 | fieldn++; |
diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el index ec411ff773b..c2ec99d8032 100644 --- a/test/src/editfns-tests.el +++ b/test/src/editfns-tests.el | |||
| @@ -88,7 +88,21 @@ | |||
| 88 | (format "%-10s" (concat (propertize "01" 'face 'bold) | 88 | (format "%-10s" (concat (propertize "01" 'face 'bold) |
| 89 | (propertize "23" 'face 'underline) | 89 | (propertize "23" 'face 'underline) |
| 90 | (propertize "45" 'face 'italic))) | 90 | (propertize "45" 'face 'italic))) |
| 91 | #("012345 " 0 2 (face bold) 2 4 (face underline) 4 10 (face italic))))) | 91 | #("012345 " |
| 92 | 0 2 (face bold) 2 4 (face underline) 4 10 (face italic)))) | ||
| 93 | ;; Bug #32404 | ||
| 94 | (should (ert-equal-including-properties | ||
| 95 | (format (concat (propertize "%s" 'face 'bold) | ||
| 96 | "" | ||
| 97 | (propertize "%s" 'face 'error)) | ||
| 98 | "foo" "bar") | ||
| 99 | #("foobar" 0 3 (face bold) 3 6 (face error)))) | ||
| 100 | (should (ert-equal-including-properties | ||
| 101 | (format (concat "%s" (propertize "%s" 'face 'error)) "foo" "bar") | ||
| 102 | #("foobar" 3 6 (face error)))) | ||
| 103 | (should (ert-equal-including-properties | ||
| 104 | (format (concat "%s " (propertize "%s" 'face 'error)) "foo" "bar") | ||
| 105 | #("foo bar" 4 7 (face error))))) | ||
| 92 | 106 | ||
| 93 | ;; Tests for bug#5131. | 107 | ;; Tests for bug#5131. |
| 94 | (defun transpose-test-reverse-word (start end) | 108 | (defun transpose-test-reverse-word (start end) |