aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/textprop.c57
1 files changed, 46 insertions, 11 deletions
diff --git a/src/textprop.c b/src/textprop.c
index ea796887457..d22178d0aa3 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -50,6 +50,12 @@ Lisp_Object Qlocal_map;
50/* Visual properties text (including strings) may have. */ 50/* Visual properties text (including strings) may have. */
51Lisp_Object Qforeground, Qbackground, Qfont, Qunderline, Qstipple; 51Lisp_Object Qforeground, Qbackground, Qfont, Qunderline, Qstipple;
52Lisp_Object Qinvisible, Qread_only; 52Lisp_Object Qinvisible, Qread_only;
53
54/* If o1 is a cons whose cdr is a cons, return non-zero and set o2 to
55 the o1's cdr. Otherwise, return zero. This is handy for
56 traversing plists. */
57#define PLIST_ELT_P(o1, o2) (CONSP (o1) && CONSP ((o2) = XCONS (o1)->cdr))
58
53 59
54/* Extract the interval at the position pointed to by BEGIN from 60/* Extract the interval at the position pointed to by BEGIN from
55 OBJECT, a string or buffer. Additionally, check that the positions 61 OBJECT, a string or buffer. Additionally, check that the positions
@@ -239,6 +245,24 @@ interval_has_some_properties (plist, i)
239 return 0; 245 return 0;
240} 246}
241 247
248/* Changing the plists of individual intervals. */
249
250/* Return the value of PROP in property-list PLIST, or Qunbound if it
251 has none. */
252static int
253property_value (plist, prop)
254{
255 Lisp_Object value;
256
257 while (PLIST_ELT_P (plist, value))
258 if (EQ (XCONS (plist)->car, prop))
259 return XCONS (value)->car;
260 else
261 plist = XCONS (value)->cdr;
262
263 return Qunbound;
264}
265
242/* Set the properties of INTERVAL to PROPERTIES, 266/* Set the properties of INTERVAL to PROPERTIES,
243 and record undo info for the previous values. 267 and record undo info for the previous values.
244 OBJECT is the string or buffer that INTERVAL belongs to. */ 268 OBJECT is the string or buffer that INTERVAL belongs to. */
@@ -248,19 +272,30 @@ set_properties (properties, interval, object)
248 Lisp_Object properties, object; 272 Lisp_Object properties, object;
249 INTERVAL interval; 273 INTERVAL interval;
250{ 274{
251 Lisp_Object oldprops; 275 Lisp_Object sym, value;
252 oldprops = interval->plist;
253 276
254 /* Record undo for old properties. */ 277 if (BUFFERP (object))
255 while (XTYPE (oldprops) == Lisp_Cons)
256 { 278 {
257 Lisp_Object sym; 279 /* For each property in the old plist which is missing from PROPERTIES,
258 sym = Fcar (oldprops); 280 or has a different value in PROPERTIES, make an undo record. */
259 record_property_change (interval->position, LENGTH (interval), 281 for (sym = interval->plist;
260 sym, Fcar_safe (Fcdr (oldprops)), 282 PLIST_ELT_P (sym, value);
261 object); 283 sym = XCONS (value)->cdr)
262 284 if (! EQ (property_value (properties, XCONS (sym)->car),
263 oldprops = Fcdr_safe (Fcdr (oldprops)); 285 XCONS (value)->car))
286 record_property_change (interval->position, LENGTH (interval),
287 XCONS (sym)->car, XCONS (value)->car,
288 object);
289
290 /* For each new property that has no value at all in the old plist,
291 make an undo record binding it to nil, so it will be removed. */
292 for (sym = properties;
293 PLIST_ELT_P (sym, value);
294 sym = XCONS (value)->cdr)
295 if (EQ (property_value (interval->plist, XCONS (sym)->car), Qunbound))
296 record_property_change (interval->position, LENGTH (interval),
297 XCONS (sym)->car, Qnil,
298 object);
264 } 299 }
265 300
266 /* Store new properties. */ 301 /* Store new properties. */