diff options
Diffstat (limited to 'src/textprop.c')
| -rw-r--r-- | src/textprop.c | 109 |
1 files changed, 92 insertions, 17 deletions
diff --git a/src/textprop.c b/src/textprop.c index cc364d5a38c..e5d4fe06c60 100644 --- a/src/textprop.c +++ b/src/textprop.c | |||
| @@ -60,6 +60,13 @@ Lisp_Object Qinvisible, Qintangible, Qmouse_face; | |||
| 60 | static Lisp_Object Qread_only; | 60 | static Lisp_Object Qread_only; |
| 61 | Lisp_Object Qminibuffer_prompt; | 61 | Lisp_Object Qminibuffer_prompt; |
| 62 | 62 | ||
| 63 | enum property_set_type | ||
| 64 | { | ||
| 65 | TEXT_PROPERTY_REPLACE, | ||
| 66 | TEXT_PROPERTY_PREPEND, | ||
| 67 | TEXT_PROPERTY_APPEND | ||
| 68 | }; | ||
| 69 | |||
| 63 | /* Sticky properties. */ | 70 | /* Sticky properties. */ |
| 64 | Lisp_Object Qfront_sticky, Qrear_nonsticky; | 71 | Lisp_Object Qfront_sticky, Qrear_nonsticky; |
| 65 | 72 | ||
| @@ -98,6 +105,14 @@ modify_region (Lisp_Object buffer, Lisp_Object start, Lisp_Object end) | |||
| 98 | set_buffer_internal (old); | 105 | set_buffer_internal (old); |
| 99 | } | 106 | } |
| 100 | 107 | ||
| 108 | /* Complain if object is not string or buffer type. */ | ||
| 109 | |||
| 110 | static void | ||
| 111 | CHECK_STRING_OR_BUFFER (Lisp_Object x) | ||
| 112 | { | ||
| 113 | CHECK_TYPE (STRINGP (x) || BUFFERP (x), Qbuffer_or_string_p, x); | ||
| 114 | } | ||
| 115 | |||
| 101 | /* Extract the interval at the position pointed to by BEGIN from | 116 | /* Extract the interval at the position pointed to by BEGIN from |
| 102 | OBJECT, a string or buffer. Additionally, check that the positions | 117 | OBJECT, a string or buffer. Additionally, check that the positions |
| 103 | pointed to by BEGIN and END are within the bounds of OBJECT, and | 118 | pointed to by BEGIN and END are within the bounds of OBJECT, and |
| @@ -362,7 +377,8 @@ set_properties (Lisp_Object properties, INTERVAL interval, Lisp_Object object) | |||
| 362 | are actually added to I's plist) */ | 377 | are actually added to I's plist) */ |
| 363 | 378 | ||
| 364 | static bool | 379 | static bool |
| 365 | add_properties (Lisp_Object plist, INTERVAL i, Lisp_Object object) | 380 | add_properties (Lisp_Object plist, INTERVAL i, Lisp_Object object, |
| 381 | enum property_set_type set_type) | ||
| 366 | { | 382 | { |
| 367 | Lisp_Object tail1, tail2, sym1, val1; | 383 | Lisp_Object tail1, tail2, sym1, val1; |
| 368 | bool changed = 0; | 384 | bool changed = 0; |
| @@ -408,7 +424,30 @@ add_properties (Lisp_Object plist, INTERVAL i, Lisp_Object object) | |||
| 408 | } | 424 | } |
| 409 | 425 | ||
| 410 | /* I's property has a different value -- change it */ | 426 | /* I's property has a different value -- change it */ |
| 411 | Fsetcar (this_cdr, val1); | 427 | if (set_type == TEXT_PROPERTY_REPLACE) |
| 428 | Fsetcar (this_cdr, val1); | ||
| 429 | else { | ||
| 430 | if (CONSP (Fcar (this_cdr)) && | ||
| 431 | /* Special-case anonymous face properties. */ | ||
| 432 | (! EQ (sym1, Qface) || | ||
| 433 | NILP (Fkeywordp (Fcar (Fcar (this_cdr)))))) | ||
| 434 | /* The previous value is a list, so prepend (or | ||
| 435 | append) the new value to this list. */ | ||
| 436 | if (set_type == TEXT_PROPERTY_PREPEND) | ||
| 437 | Fsetcar (this_cdr, Fcons (val1, Fcar (this_cdr))); | ||
| 438 | else | ||
| 439 | nconc2 (Fcar (this_cdr), Fcons (val1, Qnil)); | ||
| 440 | else { | ||
| 441 | /* The previous value is a single value, so make it | ||
| 442 | into a list. */ | ||
| 443 | if (set_type == TEXT_PROPERTY_PREPEND) | ||
| 444 | Fsetcar (this_cdr, | ||
| 445 | Fcons (val1, Fcons (Fcar (this_cdr), Qnil))); | ||
| 446 | else | ||
| 447 | Fsetcar (this_cdr, | ||
| 448 | Fcons (Fcar (this_cdr), Fcons (val1, Qnil))); | ||
| 449 | } | ||
| 450 | } | ||
| 412 | changed = 1; | 451 | changed = 1; |
| 413 | break; | 452 | break; |
| 414 | } | 453 | } |
| @@ -1116,19 +1155,12 @@ back past position LIMIT; return LIMIT if nothing is found until LIMIT. */) | |||
| 1116 | return make_number (previous->position + LENGTH (previous)); | 1155 | return make_number (previous->position + LENGTH (previous)); |
| 1117 | } | 1156 | } |
| 1118 | 1157 | ||
| 1119 | /* Callers note, this can GC when OBJECT is a buffer (or nil). */ | 1158 | /* Used by add-text-properties and add-face-text-property. */ |
| 1120 | 1159 | ||
| 1121 | DEFUN ("add-text-properties", Fadd_text_properties, | 1160 | static Lisp_Object |
| 1122 | Sadd_text_properties, 3, 4, 0, | 1161 | add_text_properties_1 (Lisp_Object start, Lisp_Object end, |
| 1123 | doc: /* Add properties to the text from START to END. | 1162 | Lisp_Object properties, Lisp_Object object, |
| 1124 | The third argument PROPERTIES is a property list | 1163 | enum property_set_type set_type) { |
| 1125 | specifying the property values to add. If the optional fourth argument | ||
| 1126 | OBJECT is a buffer (or nil, which means the current buffer), | ||
| 1127 | START and END are buffer positions (integers or markers). | ||
| 1128 | If OBJECT is a string, START and END are 0-based indices into it. | ||
| 1129 | Return t if any property value actually changed, nil otherwise. */) | ||
| 1130 | (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object object) | ||
| 1131 | { | ||
| 1132 | INTERVAL i, unchanged; | 1164 | INTERVAL i, unchanged; |
| 1133 | ptrdiff_t s, len; | 1165 | ptrdiff_t s, len; |
| 1134 | bool modified = 0; | 1166 | bool modified = 0; |
| @@ -1222,7 +1254,7 @@ Return t if any property value actually changed, nil otherwise. */) | |||
| 1222 | 1254 | ||
| 1223 | if (LENGTH (i) == len) | 1255 | if (LENGTH (i) == len) |
| 1224 | { | 1256 | { |
| 1225 | add_properties (properties, i, object); | 1257 | add_properties (properties, i, object, set_type); |
| 1226 | if (BUFFERP (object)) | 1258 | if (BUFFERP (object)) |
| 1227 | signal_after_change (XINT (start), XINT (end) - XINT (start), | 1259 | signal_after_change (XINT (start), XINT (end) - XINT (start), |
| 1228 | XINT (end) - XINT (start)); | 1260 | XINT (end) - XINT (start)); |
| @@ -1233,7 +1265,7 @@ Return t if any property value actually changed, nil otherwise. */) | |||
| 1233 | unchanged = i; | 1265 | unchanged = i; |
| 1234 | i = split_interval_left (unchanged, len); | 1266 | i = split_interval_left (unchanged, len); |
| 1235 | copy_properties (unchanged, i); | 1267 | copy_properties (unchanged, i); |
| 1236 | add_properties (properties, i, object); | 1268 | add_properties (properties, i, object, set_type); |
| 1237 | if (BUFFERP (object)) | 1269 | if (BUFFERP (object)) |
| 1238 | signal_after_change (XINT (start), XINT (end) - XINT (start), | 1270 | signal_after_change (XINT (start), XINT (end) - XINT (start), |
| 1239 | XINT (end) - XINT (start)); | 1271 | XINT (end) - XINT (start)); |
| @@ -1241,13 +1273,31 @@ Return t if any property value actually changed, nil otherwise. */) | |||
| 1241 | } | 1273 | } |
| 1242 | 1274 | ||
| 1243 | len -= LENGTH (i); | 1275 | len -= LENGTH (i); |
| 1244 | modified |= add_properties (properties, i, object); | 1276 | modified |= add_properties (properties, i, object, set_type); |
| 1245 | i = next_interval (i); | 1277 | i = next_interval (i); |
| 1246 | } | 1278 | } |
| 1247 | } | 1279 | } |
| 1248 | 1280 | ||
| 1249 | /* Callers note, this can GC when OBJECT is a buffer (or nil). */ | 1281 | /* Callers note, this can GC when OBJECT is a buffer (or nil). */ |
| 1250 | 1282 | ||
| 1283 | DEFUN ("add-text-properties", Fadd_text_properties, | ||
| 1284 | Sadd_text_properties, 3, 4, 0, | ||
| 1285 | doc: /* Add properties to the text from START to END. | ||
| 1286 | The third argument PROPERTIES is a property list | ||
| 1287 | specifying the property values to add. If the optional fourth argument | ||
| 1288 | OBJECT is a buffer (or nil, which means the current buffer), | ||
| 1289 | START and END are buffer positions (integers or markers). | ||
| 1290 | If OBJECT is a string, START and END are 0-based indices into it. | ||
| 1291 | Return t if any property value actually changed, nil otherwise. */) | ||
| 1292 | (Lisp_Object start, Lisp_Object end, Lisp_Object properties, | ||
| 1293 | Lisp_Object object) | ||
| 1294 | { | ||
| 1295 | return add_text_properties_1 (start, end, properties, object, | ||
| 1296 | TEXT_PROPERTY_REPLACE); | ||
| 1297 | } | ||
| 1298 | |||
| 1299 | /* Callers note, this can GC when OBJECT is a buffer (or nil). */ | ||
| 1300 | |||
| 1251 | DEFUN ("put-text-property", Fput_text_property, | 1301 | DEFUN ("put-text-property", Fput_text_property, |
| 1252 | Sput_text_property, 4, 5, 0, | 1302 | Sput_text_property, 4, 5, 0, |
| 1253 | doc: /* Set one property of the text from START to END. | 1303 | doc: /* Set one property of the text from START to END. |
| @@ -1279,6 +1329,29 @@ the designated part of OBJECT. */) | |||
| 1279 | } | 1329 | } |
| 1280 | 1330 | ||
| 1281 | 1331 | ||
| 1332 | DEFUN ("add-face-text-property", Fadd_face_text_property, | ||
| 1333 | Sadd_face_text_property, 3, 5, 0, | ||
| 1334 | doc: /* Add the face property to the text from START to END. | ||
| 1335 | The third argument FACE specifies the face to add. | ||
| 1336 | If any text in the region already has any face properties, this new | ||
| 1337 | face property will be added to the front of the face property list. | ||
| 1338 | If the optional fourth argument APPENDP is non-nil, append to the end | ||
| 1339 | of the face property list instead. | ||
| 1340 | If the optional fifth argument OBJECT is a buffer (or nil, which means | ||
| 1341 | the current buffer), START and END are buffer positions (integers or | ||
| 1342 | markers). If OBJECT is a string, START and END are 0-based indices | ||
| 1343 | into it. */) | ||
| 1344 | (Lisp_Object start, Lisp_Object end, Lisp_Object face, | ||
| 1345 | Lisp_Object appendp, Lisp_Object object) | ||
| 1346 | { | ||
| 1347 | add_text_properties_1 (start, end, | ||
| 1348 | Fcons (Qface, Fcons (face, Qnil)), | ||
| 1349 | object, | ||
| 1350 | NILP (appendp)? TEXT_PROPERTY_PREPEND: | ||
| 1351 | TEXT_PROPERTY_APPEND); | ||
| 1352 | return Qnil; | ||
| 1353 | } | ||
| 1354 | |||
| 1282 | /* Replace properties of text from START to END with new list of | 1355 | /* Replace properties of text from START to END with new list of |
| 1283 | properties PROPERTIES. OBJECT is the buffer or string containing | 1356 | properties PROPERTIES. OBJECT is the buffer or string containing |
| 1284 | the text. OBJECT nil means use the current buffer. | 1357 | the text. OBJECT nil means use the current buffer. |
| @@ -2284,6 +2357,7 @@ inherits it if NONSTICKINESS is nil. The `front-sticky' and | |||
| 2284 | DEFSYM (Qforeground, "foreground"); | 2357 | DEFSYM (Qforeground, "foreground"); |
| 2285 | DEFSYM (Qbackground, "background"); | 2358 | DEFSYM (Qbackground, "background"); |
| 2286 | DEFSYM (Qfont, "font"); | 2359 | DEFSYM (Qfont, "font"); |
| 2360 | DEFSYM (Qface, "face"); | ||
| 2287 | DEFSYM (Qstipple, "stipple"); | 2361 | DEFSYM (Qstipple, "stipple"); |
| 2288 | DEFSYM (Qunderline, "underline"); | 2362 | DEFSYM (Qunderline, "underline"); |
| 2289 | DEFSYM (Qread_only, "read-only"); | 2363 | DEFSYM (Qread_only, "read-only"); |
| @@ -2318,6 +2392,7 @@ inherits it if NONSTICKINESS is nil. The `front-sticky' and | |||
| 2318 | defsubr (&Sadd_text_properties); | 2392 | defsubr (&Sadd_text_properties); |
| 2319 | defsubr (&Sput_text_property); | 2393 | defsubr (&Sput_text_property); |
| 2320 | defsubr (&Sset_text_properties); | 2394 | defsubr (&Sset_text_properties); |
| 2395 | defsubr (&Sadd_face_text_property); | ||
| 2321 | defsubr (&Sremove_text_properties); | 2396 | defsubr (&Sremove_text_properties); |
| 2322 | defsubr (&Sremove_list_of_text_properties); | 2397 | defsubr (&Sremove_list_of_text_properties); |
| 2323 | defsubr (&Stext_property_any); | 2398 | defsubr (&Stext_property_any); |