aboutsummaryrefslogtreecommitdiffstats
path: root/src/textprop.c
diff options
context:
space:
mode:
authorLars Magne Ingebrigtsen2013-06-17 17:28:22 +0200
committerLars Magne Ingebrigtsen2013-06-17 17:28:22 +0200
commit708e05f6d1b39313a63e34a5b4e1a16ae809ae25 (patch)
tree406e73905374997269b8d123e5c0ec98dcbd872e /src/textprop.c
parent2c149f93b425ffbb2de02e9b41e1aa98ae40e0e7 (diff)
downloademacs-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.c101
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;
60static Lisp_Object Qread_only; 60static Lisp_Object Qread_only;
61Lisp_Object Qminibuffer_prompt; 61Lisp_Object Qminibuffer_prompt;
62 62
63enum property_set_type
64{
65 TEXT_PROPERTY_REPLACE,
66 TEXT_PROPERTY_PREPEND,
67 TEXT_PROPERTY_APPEND
68};
69
63/* Sticky properties. */ 70/* Sticky properties. */
64Lisp_Object Qfront_sticky, Qrear_nonsticky; 71Lisp_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
372static bool 379static bool
373add_properties (Lisp_Object plist, INTERVAL i, Lisp_Object object) 380add_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
1129DEFUN ("add-text-properties", Fadd_text_properties, 1160static Lisp_Object
1130 Sadd_text_properties, 3, 4, 0, 1161add_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,
1132The third argument PROPERTIES is a property list 1163 enum property_set_type set_type) {
1133specifying the property values to add. If the optional fourth argument
1134OBJECT is a buffer (or nil, which means the current buffer),
1135START and END are buffer positions (integers or markers).
1136If OBJECT is a string, START and END are 0-based indices into it.
1137Return 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
1283DEFUN ("add-text-properties", Fadd_text_properties,
1284 Sadd_text_properties, 3, 4, 0,
1285 doc: /* Add properties to the text from START to END.
1286The third argument PROPERTIES is a property list
1287specifying the property values to add. If the optional fourth argument
1288OBJECT is a buffer (or nil, which means the current buffer),
1289START and END are buffer positions (integers or markers).
1290If OBJECT is a string, START and END are 0-based indices into it.
1291Return 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
1259DEFUN ("put-text-property", Fput_text_property, 1301DEFUN ("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
1332DEFUN ("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.
1335The third argument FACE specifies the face to add.
1336If any text in the region already has any face properties, this new
1337face property will be added to the front of the face property list.
1338If the optional fourth argument APPENDP is non-nil, append to the end
1339of the face property list instead.
1340If the optional fifth argument OBJECT is a buffer (or nil, which means
1341the current buffer), START and END are buffer positions (integers or
1342markers). If OBJECT is a string, START and END are 0-based indices
1343into 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);