aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Ingebrigtsen2019-10-09 05:08:32 +0200
committerLars Ingebrigtsen2019-10-09 05:08:32 +0200
commit967eed75968571edc503a770b8a631a4477c9b4d (patch)
tree989d62ec198b2596d59bb159cec1122bbd4712f0 /src
parent534783c526000a3320f1d4c0a42d26c39fff6bd0 (diff)
downloademacs-967eed75968571edc503a770b8a631a4477c9b4d.tar.gz
emacs-967eed75968571edc503a770b8a631a4477c9b4d.zip
Make add-face-text-property not be destructive on strings
* src/textprop.c (add_properties): Take a parameter to say whether it's allowed to be destructive or not (bug#20153). (add_text_properties_1): Ditto. (Fadd_face_text_property): Use this to say that it shouldn't modify face properties on strings destructively. This avoids altering the face properties of one string when altering them on a copy of the string.
Diffstat (limited to 'src')
-rw-r--r--src/textprop.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/src/textprop.c b/src/textprop.c
index d36b9e14a69..13cd87ac473 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -358,12 +358,15 @@ set_properties (Lisp_Object properties, INTERVAL interval, Lisp_Object object)
358 358
359 OBJECT should be the string or buffer the interval is in. 359 OBJECT should be the string or buffer the interval is in.
360 360
361 If DESTRUCTIVE, the function is allowed to reuse list values in the
362 properties.
363
361 Return true if this changes I (i.e., if any members of PLIST 364 Return true if this changes I (i.e., if any members of PLIST
362 are actually added to I's plist) */ 365 are actually added to I's plist) */
363 366
364static bool 367static bool
365add_properties (Lisp_Object plist, INTERVAL i, Lisp_Object object, 368add_properties (Lisp_Object plist, INTERVAL i, Lisp_Object object,
366 enum property_set_type set_type) 369 enum property_set_type set_type, bool destructive)
367{ 370{
368 Lisp_Object tail1, tail2, sym1, val1; 371 Lisp_Object tail1, tail2, sym1, val1;
369 bool changed = false; 372 bool changed = false;
@@ -414,7 +417,15 @@ add_properties (Lisp_Object plist, INTERVAL i, Lisp_Object object,
414 if (set_type == TEXT_PROPERTY_PREPEND) 417 if (set_type == TEXT_PROPERTY_PREPEND)
415 Fsetcar (this_cdr, Fcons (val1, Fcar (this_cdr))); 418 Fsetcar (this_cdr, Fcons (val1, Fcar (this_cdr)));
416 else 419 else
417 nconc2 (Fcar (this_cdr), list1 (val1)); 420 {
421 /* Appending. */
422 if (destructive)
423 nconc2 (Fcar (this_cdr), list1 (val1));
424 else
425 Fsetcar (this_cdr, CALLN (Fappend,
426 Fcar (this_cdr),
427 list1 (val1)));
428 }
418 else { 429 else {
419 /* The previous value is a single value, so make it 430 /* The previous value is a single value, so make it
420 into a list. */ 431 into a list. */
@@ -1140,7 +1151,8 @@ back past position LIMIT; return LIMIT if nothing is found until LIMIT. */)
1140static Lisp_Object 1151static Lisp_Object
1141add_text_properties_1 (Lisp_Object start, Lisp_Object end, 1152add_text_properties_1 (Lisp_Object start, Lisp_Object end,
1142 Lisp_Object properties, Lisp_Object object, 1153 Lisp_Object properties, Lisp_Object object,
1143 enum property_set_type set_type) { 1154 enum property_set_type set_type,
1155 bool destructive) {
1144 /* Ensure we run the modification hooks for the right buffer, 1156 /* Ensure we run the modification hooks for the right buffer,
1145 without switching buffers twice (bug 36190). FIXME: Switching 1157 without switching buffers twice (bug 36190). FIXME: Switching
1146 buffers is slow and often unnecessary. */ 1158 buffers is slow and often unnecessary. */
@@ -1150,7 +1162,8 @@ add_text_properties_1 (Lisp_Object start, Lisp_Object end,
1150 record_unwind_current_buffer (); 1162 record_unwind_current_buffer ();
1151 set_buffer_internal (XBUFFER (object)); 1163 set_buffer_internal (XBUFFER (object));
1152 return unbind_to (count, add_text_properties_1 (start, end, properties, 1164 return unbind_to (count, add_text_properties_1 (start, end, properties,
1153 object, set_type)); 1165 object, set_type,
1166 destructive));
1154 } 1167 }
1155 1168
1156 INTERVAL i, unchanged; 1169 INTERVAL i, unchanged;
@@ -1236,7 +1249,7 @@ add_text_properties_1 (Lisp_Object start, Lisp_Object end,
1236 1249
1237 if (LENGTH (i) == len) 1250 if (LENGTH (i) == len)
1238 { 1251 {
1239 add_properties (properties, i, object, set_type); 1252 add_properties (properties, i, object, set_type, destructive);
1240 if (BUFFERP (object)) 1253 if (BUFFERP (object))
1241 signal_after_change (XFIXNUM (start), XFIXNUM (end) - XFIXNUM (start), 1254 signal_after_change (XFIXNUM (start), XFIXNUM (end) - XFIXNUM (start),
1242 XFIXNUM (end) - XFIXNUM (start)); 1255 XFIXNUM (end) - XFIXNUM (start));
@@ -1247,7 +1260,7 @@ add_text_properties_1 (Lisp_Object start, Lisp_Object end,
1247 unchanged = i; 1260 unchanged = i;
1248 i = split_interval_left (unchanged, len); 1261 i = split_interval_left (unchanged, len);
1249 copy_properties (unchanged, i); 1262 copy_properties (unchanged, i);
1250 add_properties (properties, i, object, set_type); 1263 add_properties (properties, i, object, set_type, destructive);
1251 if (BUFFERP (object)) 1264 if (BUFFERP (object))
1252 signal_after_change (XFIXNUM (start), XFIXNUM (end) - XFIXNUM (start), 1265 signal_after_change (XFIXNUM (start), XFIXNUM (end) - XFIXNUM (start),
1253 XFIXNUM (end) - XFIXNUM (start)); 1266 XFIXNUM (end) - XFIXNUM (start));
@@ -1255,7 +1268,7 @@ add_text_properties_1 (Lisp_Object start, Lisp_Object end,
1255 } 1268 }
1256 1269
1257 len -= LENGTH (i); 1270 len -= LENGTH (i);
1258 modified |= add_properties (properties, i, object, set_type); 1271 modified |= add_properties (properties, i, object, set_type, destructive);
1259 i = next_interval (i); 1272 i = next_interval (i);
1260 } 1273 }
1261} 1274}
@@ -1275,7 +1288,7 @@ Return t if any property value actually changed, nil otherwise. */)
1275 Lisp_Object object) 1288 Lisp_Object object)
1276{ 1289{
1277 return add_text_properties_1 (start, end, properties, object, 1290 return add_text_properties_1 (start, end, properties, object,
1278 TEXT_PROPERTY_REPLACE); 1291 TEXT_PROPERTY_REPLACE, true);
1279} 1292}
1280 1293
1281/* Callers note, this can GC when OBJECT is a buffer (or nil). */ 1294/* Callers note, this can GC when OBJECT is a buffer (or nil). */
@@ -1337,7 +1350,8 @@ into it. */)
1337 add_text_properties_1 (start, end, properties, object, 1350 add_text_properties_1 (start, end, properties, object,
1338 (NILP (append) 1351 (NILP (append)
1339 ? TEXT_PROPERTY_PREPEND 1352 ? TEXT_PROPERTY_PREPEND
1340 : TEXT_PROPERTY_APPEND)); 1353 : TEXT_PROPERTY_APPEND),
1354 !STRINGP (object));
1341 return Qnil; 1355 return Qnil;
1342} 1356}
1343 1357