]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix copying text properties by 'format'
authorEli Zaretskii <eliz@gnu.org>
Thu, 9 Aug 2018 15:08:35 +0000 (18:08 +0300)
committerEli Zaretskii <eliz@gnu.org>
Thu, 9 Aug 2018 15:08:35 +0000 (18:08 +0300)
* 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.

src/editfns.c
test/src/editfns-tests.el

index a8acff659cd95eb4168c7b27304716f1d519f70c..081ea0b3b7cf4842f6b292a349c1f6e6cb840e4d 100644 (file)
@@ -4257,6 +4257,9 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
     /* The start and end bytepos in the output string.  */
     ptrdiff_t start, end;
 
+    /* The start of the spec in the format string.  */
+    ptrdiff_t fbeg;
+
     /* Whether the argument is a string with intervals.  */
     bool_bf intervals : 1;
   } *info;
@@ -4408,6 +4411,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
          char conversion = *format++;
          memset (&discarded[format0 - format_start], 1,
                  format - format0 - (conversion == '%'));
+         info[ispec].fbeg = format0 - format_start;
          if (conversion == '%')
            {
              new_result = true;
@@ -4981,7 +4985,9 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
                  else if (discarded[bytepos] == 1)
                    {
                      position++;
-                     if (fieldn < nspec && translated == info[fieldn].start)
+                     if (fieldn < nspec
+                         && position > info[fieldn].fbeg
+                         && translated == info[fieldn].start)
                        {
                          translated += info[fieldn].end - info[fieldn].start;
                          fieldn++;
@@ -5001,7 +5007,9 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
                  else if (discarded[bytepos] == 1)
                    {
                      position++;
-                     if (fieldn < nspec && translated == info[fieldn].start)
+                     if (fieldn < nspec
+                         && position > info[fieldn].fbeg
+                         && translated == info[fieldn].start)
                        {
                          translated += info[fieldn].end - info[fieldn].start;
                          fieldn++;
index ec411ff773b4e6fc6123db559f367fa80cdb5f96..c2ec99d8032ab089fe803b7e1eca95be6c423b60 100644 (file)
            (format "%-10s" (concat (propertize "01" 'face 'bold)
                                    (propertize "23" 'face 'underline)
                                    (propertize "45" 'face 'italic)))
-           #("012345    " 0 2 (face bold) 2 4 (face underline) 4 10 (face italic)))))
+           #("012345    "
+             0 2 (face bold) 2 4 (face underline) 4 10 (face italic))))
+  ;; Bug #32404
+  (should (ert-equal-including-properties
+           (format (concat (propertize "%s" 'face 'bold)
+                           ""
+                           (propertize "%s" 'face 'error))
+                   "foo" "bar")
+           #("foobar" 0 3 (face bold) 3 6 (face error))))
+  (should (ert-equal-including-properties
+           (format (concat "%s" (propertize "%s" 'face 'error)) "foo" "bar")
+           #("foobar" 3 6 (face error))))
+  (should (ert-equal-including-properties
+           (format (concat "%s " (propertize "%s" 'face 'error)) "foo" "bar")
+           #("foo bar" 4 7 (face error)))))
 
 ;; Tests for bug#5131.
 (defun transpose-test-reverse-word (start end)