diff options
| author | Lars Magne Ingebrigtsen | 2013-06-17 17:28:22 +0200 |
|---|---|---|
| committer | Lars Magne Ingebrigtsen | 2013-06-17 17:28:22 +0200 |
| commit | 708e05f6d1b39313a63e34a5b4e1a16ae809ae25 (patch) | |
| tree | 406e73905374997269b8d123e5c0ec98dcbd872e /src/textprop.c | |
| parent | 2c149f93b425ffbb2de02e9b41e1aa98ae40e0e7 (diff) | |
| download | emacs-708e05f6d1b39313a63e34a5b4e1a16ae809ae25.tar.gz emacs-708e05f6d1b39313a63e34a5b4e1a16ae809ae25.zip | |
Implement new function `add-face-text-property'
* doc/lispref/text.texi (Changing Properties): Document `add-face-text-property'.
* src/textprop.c (property_set_type): New enum.
(add_properties): Allow appending/prepending text properties.
(add_text_properties_1): Factored out of Fadd_text_properties.
(Fadd_text_properties): Moved all the code into
add_text_properties_1.
(Fadd_face_text_property): New function that calls
add_text_properties_1.
Diffstat (limited to 'src/textprop.c')
| -rw-r--r-- | src/textprop.c | 101 |
1 files changed, 84 insertions, 17 deletions
diff --git a/src/textprop.c b/src/textprop.c index 03b8de120cd..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 | ||
| @@ -370,7 +377,8 @@ set_properties (Lisp_Object properties, INTERVAL interval, Lisp_Object object) | |||
| 370 | are actually added to I's plist) */ | 377 | are actually added to I's plist) */ |
| 371 | 378 | ||
| 372 | static bool | 379 | static bool |
| 373 | 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) | ||
| 374 | { | 382 | { |
| 375 | Lisp_Object tail1, tail2, sym1, val1; | 383 | Lisp_Object tail1, tail2, sym1, val1; |
| 376 | bool changed = 0; | 384 | bool changed = 0; |
| @@ -416,7 +424,30 @@ add_properties (Lisp_Object plist, INTERVAL i, Lisp_Object object) | |||
| 416 | } | 424 | } |
| 417 | 425 | ||
| 418 | /* I's property has a different value -- change it */ | 426 | /* I's property has a different value -- change it */ |
| 419 | 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 | } | ||
| 420 | changed = 1; | 451 | changed = 1; |
| 421 | break; | 452 | break; |
| 422 | } | 453 | } |
| @@ -1124,19 +1155,12 @@ back past position LIMIT; return LIMIT if nothing is found until LIMIT. */) | |||
| 1124 | return make_number (previous->position + LENGTH (previous)); | 1155 | return make_number (previous->position + LENGTH (previous)); |
| 1125 | } | 1156 | } |
| 1126 | 1157 | ||
| 1127 | /* Callers note, this can GC when OBJECT is a buffer (or nil). */ | 1158 | /* Used by add-text-properties and add-face-text-property. */ |
| 1128 | 1159 | ||
| 1129 | DEFUN ("add-text-properties", Fadd_text_properties, | 1160 | static Lisp_Object |
| 1130 | Sadd_text_properties, 3, 4, 0, | 1161 | add_text_properties_1 (Lisp_Object start, Lisp_Object end, |
| 1131 | doc: /* Add properties to the text from START to END. | 1162 | Lisp_Object properties, Lisp_Object object, |
| 1132 | The third argument PROPERTIES is a property list | 1163 | enum property_set_type set_type) { |
| 1133 | specifying the property values to add. If the optional fourth argument | ||
| 1134 | OBJECT is a buffer (or nil, which means the current buffer), | ||
| 1135 | START and END are buffer positions (integers or markers). | ||
| 1136 | If OBJECT is a string, START and END are 0-based indices into it. | ||
| 1137 | Return t if any property value actually changed, nil otherwise. */) | ||
| 1138 | (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object object) | ||
| 1139 | { | ||
| 1140 | INTERVAL i, unchanged; | 1164 | INTERVAL i, unchanged; |
| 1141 | ptrdiff_t s, len; | 1165 | ptrdiff_t s, len; |
| 1142 | bool modified = 0; | 1166 | bool modified = 0; |
| @@ -1230,7 +1254,7 @@ Return t if any property value actually changed, nil otherwise. */) | |||
| 1230 | 1254 | ||
| 1231 | if (LENGTH (i) == len) | 1255 | if (LENGTH (i) == len) |
| 1232 | { | 1256 | { |
| 1233 | add_properties (properties, i, object); | 1257 | add_properties (properties, i, object, set_type); |
| 1234 | if (BUFFERP (object)) | 1258 | if (BUFFERP (object)) |
| 1235 | signal_after_change (XINT (start), XINT (end) - XINT (start), | 1259 | signal_after_change (XINT (start), XINT (end) - XINT (start), |
| 1236 | XINT (end) - XINT (start)); | 1260 | XINT (end) - XINT (start)); |
| @@ -1241,7 +1265,7 @@ Return t if any property value actually changed, nil otherwise. */) | |||
| 1241 | unchanged = i; | 1265 | unchanged = i; |
| 1242 | i = split_interval_left (unchanged, len); | 1266 | i = split_interval_left (unchanged, len); |
| 1243 | copy_properties (unchanged, i); | 1267 | copy_properties (unchanged, i); |
| 1244 | add_properties (properties, i, object); | 1268 | add_properties (properties, i, object, set_type); |
| 1245 | if (BUFFERP (object)) | 1269 | if (BUFFERP (object)) |
| 1246 | signal_after_change (XINT (start), XINT (end) - XINT (start), | 1270 | signal_after_change (XINT (start), XINT (end) - XINT (start), |
| 1247 | XINT (end) - XINT (start)); | 1271 | XINT (end) - XINT (start)); |
| @@ -1249,13 +1273,31 @@ Return t if any property value actually changed, nil otherwise. */) | |||
| 1249 | } | 1273 | } |
| 1250 | 1274 | ||
| 1251 | len -= LENGTH (i); | 1275 | len -= LENGTH (i); |
| 1252 | modified |= add_properties (properties, i, object); | 1276 | modified |= add_properties (properties, i, object, set_type); |
| 1253 | i = next_interval (i); | 1277 | i = next_interval (i); |
| 1254 | } | 1278 | } |
| 1255 | } | 1279 | } |
| 1256 | 1280 | ||
| 1257 | /* 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). */ |
| 1258 | 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 | |||
| 1259 | DEFUN ("put-text-property", Fput_text_property, | 1301 | DEFUN ("put-text-property", Fput_text_property, |
| 1260 | Sput_text_property, 4, 5, 0, | 1302 | Sput_text_property, 4, 5, 0, |
| 1261 | doc: /* Set one property of the text from START to END. | 1303 | doc: /* Set one property of the text from START to END. |
| @@ -1287,6 +1329,29 @@ the designated part of OBJECT. */) | |||
| 1287 | } | 1329 | } |
| 1288 | 1330 | ||
| 1289 | 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 | |||
| 1290 | /* 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 |
| 1291 | properties PROPERTIES. OBJECT is the buffer or string containing | 1356 | properties PROPERTIES. OBJECT is the buffer or string containing |
| 1292 | the text. OBJECT nil means use the current buffer. | 1357 | the text. OBJECT nil means use the current buffer. |
| @@ -2292,6 +2357,7 @@ inherits it if NONSTICKINESS is nil. The `front-sticky' and | |||
| 2292 | DEFSYM (Qforeground, "foreground"); | 2357 | DEFSYM (Qforeground, "foreground"); |
| 2293 | DEFSYM (Qbackground, "background"); | 2358 | DEFSYM (Qbackground, "background"); |
| 2294 | DEFSYM (Qfont, "font"); | 2359 | DEFSYM (Qfont, "font"); |
| 2360 | DEFSYM (Qface, "face"); | ||
| 2295 | DEFSYM (Qstipple, "stipple"); | 2361 | DEFSYM (Qstipple, "stipple"); |
| 2296 | DEFSYM (Qunderline, "underline"); | 2362 | DEFSYM (Qunderline, "underline"); |
| 2297 | DEFSYM (Qread_only, "read-only"); | 2363 | DEFSYM (Qread_only, "read-only"); |
| @@ -2326,6 +2392,7 @@ inherits it if NONSTICKINESS is nil. The `front-sticky' and | |||
| 2326 | defsubr (&Sadd_text_properties); | 2392 | defsubr (&Sadd_text_properties); |
| 2327 | defsubr (&Sput_text_property); | 2393 | defsubr (&Sput_text_property); |
| 2328 | defsubr (&Sset_text_properties); | 2394 | defsubr (&Sset_text_properties); |
| 2395 | defsubr (&Sadd_face_text_property); | ||
| 2329 | defsubr (&Sremove_text_properties); | 2396 | defsubr (&Sremove_text_properties); |
| 2330 | defsubr (&Sremove_list_of_text_properties); | 2397 | defsubr (&Sremove_list_of_text_properties); |
| 2331 | defsubr (&Stext_property_any); | 2398 | defsubr (&Stext_property_any); |