Yet another fix for copying properties by 'format'
* src/textprop.c (extend_property_ranges): Accept an additional argument OLD_END, and only extend the end of a property range if its original end is at OLD_END; all the other ranges are left intact. (Bug#23897) * src/editfns.c (styled_format): Pass the original length of the string to 'extend_property_ranges'. * src/intervals.h (extend_property_ranges): Adjust prototype. * test/src/editfns-tests.el (format-properties): Add tests for bug#23897.
This commit is contained in:
parent
d0c0b71d88
commit
d8a9c450cf
4 changed files with 21 additions and 8 deletions
|
@ -4631,7 +4631,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
|
|||
len = make_number (SCHARS (args[i]));
|
||||
Lisp_Object new_len = make_number (info[i].end - info[i].start);
|
||||
props = text_property_list (args[i], make_number (0), len, Qnil);
|
||||
props = extend_property_ranges (props, new_len);
|
||||
props = extend_property_ranges (props, len, new_len);
|
||||
/* If successive arguments have properties, be sure that
|
||||
the value of `composition' property be the copy. */
|
||||
if (1 < i && info[i - 1].end)
|
||||
|
|
|
@ -285,7 +285,7 @@ extern void set_text_properties_1 (Lisp_Object, Lisp_Object,
|
|||
Lisp_Object text_property_list (Lisp_Object, Lisp_Object, Lisp_Object,
|
||||
Lisp_Object);
|
||||
void add_text_properties_from_list (Lisp_Object, Lisp_Object, Lisp_Object);
|
||||
Lisp_Object extend_property_ranges (Lisp_Object, Lisp_Object);
|
||||
Lisp_Object extend_property_ranges (Lisp_Object, Lisp_Object, Lisp_Object);
|
||||
Lisp_Object get_char_property_and_overlay (Lisp_Object, Lisp_Object,
|
||||
Lisp_Object, Lisp_Object*);
|
||||
extern int text_property_stickiness (Lisp_Object prop, Lisp_Object pos,
|
||||
|
|
|
@ -2043,18 +2043,19 @@ add_text_properties_from_list (Lisp_Object object, Lisp_Object list, Lisp_Object
|
|||
end-points to NEW_END. */
|
||||
|
||||
Lisp_Object
|
||||
extend_property_ranges (Lisp_Object list, Lisp_Object new_end)
|
||||
extend_property_ranges (Lisp_Object list, Lisp_Object old_end, Lisp_Object new_end)
|
||||
{
|
||||
Lisp_Object prev = Qnil, head = list;
|
||||
ptrdiff_t max = XINT (new_end);
|
||||
|
||||
for (; CONSP (list); prev = list, list = XCDR (list))
|
||||
{
|
||||
Lisp_Object item, beg, end;
|
||||
Lisp_Object item, beg;
|
||||
ptrdiff_t end;
|
||||
|
||||
item = XCAR (list);
|
||||
beg = XCAR (item);
|
||||
end = XCAR (XCDR (item));
|
||||
end = XINT (XCAR (XCDR (item)));
|
||||
|
||||
if (XINT (beg) >= max)
|
||||
{
|
||||
|
@ -2065,12 +2066,14 @@ extend_property_ranges (Lisp_Object list, Lisp_Object new_end)
|
|||
else
|
||||
XSETCDR (prev, XCDR (list));
|
||||
}
|
||||
else if (XINT (end) != max)
|
||||
else if ((end == XINT (old_end) && end != max)
|
||||
|| end > max)
|
||||
{
|
||||
/* Either the end-point is past the end of the new string,
|
||||
and we need to discard the properties past the new end,
|
||||
or the caller is extending the property range, and we
|
||||
should update the end-point to reflect that. */
|
||||
should update all end-points that are on the old end of
|
||||
the range to reflect that. */
|
||||
XSETCAR (XCDR (item), new_end);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,4 +54,14 @@
|
|||
;; Bug #23859
|
||||
(should (ert-equal-including-properties
|
||||
(format "%4s" (propertize "hi" 'face 'bold))
|
||||
#(" hi" 0 4 (face bold)))))
|
||||
#(" hi" 0 4 (face bold))))
|
||||
|
||||
;; Bug #23897
|
||||
(should (ert-equal-including-properties
|
||||
(format "%s" (concat (propertize "01234" 'face 'bold) "56789"))
|
||||
#("0123456789" 0 5 (face bold))))
|
||||
(should (ert-equal-including-properties
|
||||
(format "%s" (concat (propertize "01" 'face 'bold)
|
||||
(propertize "23" 'face 'underline)
|
||||
"45"))
|
||||
#("012345" 0 2 (face bold) 2 4 (face underline)))))
|
||||
|
|
Loading…
Add table
Reference in a new issue