diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/textprop.c | 32 |
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 | ||
| 364 | static bool | 367 | static bool |
| 365 | add_properties (Lisp_Object plist, INTERVAL i, Lisp_Object object, | 368 | add_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. */) | |||
| 1140 | static Lisp_Object | 1151 | static Lisp_Object |
| 1141 | add_text_properties_1 (Lisp_Object start, Lisp_Object end, | 1152 | add_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 | ||