comparison src/extents.c @ 96:dbb370e3c29e r20-0final

Import from CVS: tag r20-0final
author cvs
date Mon, 13 Aug 2007 09:12:40 +0200
parents 1ce6082ce73f
children 0d2f883870bc
comparison
equal deleted inserted replaced
95:e8c07a565f9c 96:dbb370e3c29e
443 Lisp_Object Qend_closed; 443 Lisp_Object Qend_closed;
444 Lisp_Object Qread_only; 444 Lisp_Object Qread_only;
445 /* Qhighlight defined in general.c */ 445 /* Qhighlight defined in general.c */
446 Lisp_Object Qunique; 446 Lisp_Object Qunique;
447 Lisp_Object Qduplicable; 447 Lisp_Object Qduplicable;
448 Lisp_Object Qreplicating;
449 Lisp_Object Qdetachable; 448 Lisp_Object Qdetachable;
450 Lisp_Object Qpriority; 449 Lisp_Object Qpriority;
451 Lisp_Object Qmouse_face; 450 Lisp_Object Qmouse_face;
452 451
453 Lisp_Object Qglyph_layout; /* This exists only for backwards compatibility. */ 452 Lisp_Object Qglyph_layout; /* This exists only for backwards compatibility. */
2957 *bp++ = ' '; 2956 *bp++ = ' ';
2958 2957
2959 if (!NILP (extent_read_only (anc))) *bp++ = '%'; 2958 if (!NILP (extent_read_only (anc))) *bp++ = '%';
2960 if (!NILP (extent_mouse_face (anc))) *bp++ = 'H'; 2959 if (!NILP (extent_mouse_face (anc))) *bp++ = 'H';
2961 if (extent_unique_p (anc)) *bp++ = 'U'; 2960 if (extent_unique_p (anc)) *bp++ = 'U';
2962 else if (extent_replicating_p (anc)) *bp++ = 'R';
2963 else if (extent_duplicable_p (anc)) *bp++ = 'D'; 2961 else if (extent_duplicable_p (anc)) *bp++ = 'D';
2964 if (!NILP (extent_invisible (anc))) *bp++ = 'I'; 2962 if (!NILP (extent_invisible (anc))) *bp++ = 'I';
2965 2963
2966 if (!NILP (extent_read_only (anc)) || !NILP (extent_mouse_face (anc)) || 2964 if (!NILP (extent_read_only (anc)) || !NILP (extent_mouse_face (anc)) ||
2967 extent_unique_p (anc) || extent_replicating_p (anc) || 2965 extent_unique_p (anc) ||
2968 extent_duplicable_p (anc) || !NILP (extent_invisible (anc))) 2966 extent_duplicable_p (anc) || !NILP (extent_invisible (anc)))
2969 *bp++ = ' '; 2967 *bp++ = ' ';
2970 2968
2971 tail = extent_plist_slot (anc); 2969 tail = extent_plist_slot (anc);
2972 2970
5076 from the string using `concat' or `substring'. 5074 from the string using `concat' or `substring'.
5077 When `insert' or a similar function inserts the 5075 When `insert' or a similar function inserts the
5078 string into a buffer, the extents are copied back 5076 string into a buffer, the extents are copied back
5079 into the buffer. 5077 into the buffer.
5080 5078
5081 replicating Meaningful only in conjunction with `duplicable'. 5079 unique Meaningful only in conjunction with `duplicable'.
5082 If this flag is set, extents that are copied from 5080 When this is set, there may be only one instance
5083 buffers into strings are made children of the 5081 of this extent attached at a time: if it is copied
5084 original extent. When the string is pasted back 5082 to the kill ring and then yanked, the extent is
5085 into a buffer, the same extent (i.e. the `eq' 5083 not copied. If, however, it is killed (removed
5086 predicate applies) that was originally in the 5084 from the buffer) and then yanked, it will be
5087 buffer will be used if possible -- i.e. if the 5085 re-attached at the new position.
5088 extent is detached or the paste location abuts or
5089 overlaps the extent. This behavior is compatible
5090 with the old "extent replica" behavior and was
5091 apparently required by Energize.
5092
5093 unique Meaningful only in conjunction with `duplicable'
5094 and `replicating'. When this is set, there may be
5095 only one instance of this extent attached at a
5096 time: if it is copied to the kill ring and then
5097 yanked, the extent is not copied. If, however, it
5098 is killed (removed from the buffer) and then
5099 yanked, it will be re-attached at the new
5100 position.
5101 5086
5102 invisible If the value is non-nil, text under this extent 5087 invisible If the value is non-nil, text under this extent
5103 may be treated as not present for the purpose of 5088 may be treated as not present for the purpose of
5104 redisplay, or may be displayed using an ellipsis 5089 redisplay, or may be displayed using an ellipsis
5105 or other marker; see `buffer-invisibility-spec' 5090 or other marker; see `buffer-invisibility-spec'
5151 5136
5152 begin-glyph-layout The layout policy (one of `text', `whitespace', 5137 begin-glyph-layout The layout policy (one of `text', `whitespace',
5153 `inside-margin', or `outside-margin') of the extent's 5138 `inside-margin', or `outside-margin') of the extent's
5154 begin glyph. 5139 begin glyph.
5155 5140
5156 end-glyph-layout The layout policy of the extent's end glyph. 5141 end-glyph-layout The layout policy of the extent's end glyph. */
5157 */
5158 (extent, property, value)) 5142 (extent, property, value))
5159 { 5143 {
5160 /* This function can GC if property is `keymap' */ 5144 /* This function can GC if property is `keymap' */
5161 EXTENT e = decode_extent (extent, 0); 5145 EXTENT e = decode_extent (extent, 0);
5162 CHECK_SYMBOL (property); 5146 CHECK_SYMBOL (property);
5165 set_extent_read_only (e, value); 5149 set_extent_read_only (e, value);
5166 else if (EQ (property, Qunique)) 5150 else if (EQ (property, Qunique))
5167 extent_unique_p (e) = !NILP (value); 5151 extent_unique_p (e) = !NILP (value);
5168 else if (EQ (property, Qduplicable)) 5152 else if (EQ (property, Qduplicable))
5169 extent_duplicable_p (e) = !NILP (value); 5153 extent_duplicable_p (e) = !NILP (value);
5170 else if (EQ (property, Qreplicating))
5171 extent_replicating_p (e) = !NILP (value);
5172 else if (EQ (property, Qinvisible)) 5154 else if (EQ (property, Qinvisible))
5173 set_extent_invisible (e, value); 5155 set_extent_invisible (e, value);
5174 else if (EQ (property, Qdetachable)) 5156 else if (EQ (property, Qdetachable))
5175 extent_detachable_p (e) = !NILP (value); 5157 extent_detachable_p (e) = !NILP (value);
5176 5158
5253 return (extent_normal_field (e, flag) ? Qt : Qnil) 5235 return (extent_normal_field (e, flag) ? Qt : Qnil)
5254 else if (EQ (property, Qstart_open)) RETURN_FLAG (start_open); 5236 else if (EQ (property, Qstart_open)) RETURN_FLAG (start_open);
5255 else if (EQ (property, Qend_open)) RETURN_FLAG (end_open); 5237 else if (EQ (property, Qend_open)) RETURN_FLAG (end_open);
5256 else if (EQ (property, Qunique)) RETURN_FLAG (unique); 5238 else if (EQ (property, Qunique)) RETURN_FLAG (unique);
5257 else if (EQ (property, Qduplicable)) RETURN_FLAG (duplicable); 5239 else if (EQ (property, Qduplicable)) RETURN_FLAG (duplicable);
5258 else if (EQ (property, Qreplicating)) RETURN_FLAG (replicating);
5259 else if (EQ (property, Qdetachable)) RETURN_FLAG (detachable); 5240 else if (EQ (property, Qdetachable)) RETURN_FLAG (detachable);
5260 #undef RETURN_FLAG 5241 #undef RETURN_FLAG
5261 /* Support (but don't document...) the obvious antonyms. */ 5242 /* Support (but don't document...) the obvious antonyms. */
5262 else if (EQ (property, Qstart_closed)) 5243 else if (EQ (property, Qstart_closed))
5263 return (extent_start_open_p (e) ? Qnil : Qt); 5244 return (extent_start_open_p (e) ? Qnil : Qt);
5356 5337
5357 #define CONS_FLAG(flag, sym) if (extent_normal_field (anc, flag)) \ 5338 #define CONS_FLAG(flag, sym) if (extent_normal_field (anc, flag)) \
5358 result = Fcons (sym, Fcons (Qt, result)) 5339 result = Fcons (sym, Fcons (Qt, result))
5359 CONS_FLAG (end_open, Qend_open); 5340 CONS_FLAG (end_open, Qend_open);
5360 CONS_FLAG (start_open, Qstart_open); 5341 CONS_FLAG (start_open, Qstart_open);
5361 CONS_FLAG (replicating, Qreplicating);
5362 CONS_FLAG (detachable, Qdetachable); 5342 CONS_FLAG (detachable, Qdetachable);
5363 CONS_FLAG (duplicable, Qduplicable); 5343 CONS_FLAG (duplicable, Qduplicable);
5364 CONS_FLAG (unique, Qunique); 5344 CONS_FLAG (unique, Qunique);
5365 #undef CONS_FLAG 5345 #undef CONS_FLAG
5366 5346
5616 if (extent_duplicable_p (extent) && 5596 if (extent_duplicable_p (extent) &&
5617 !run_extent_copy_function (extent, start + closure->from, 5597 !run_extent_copy_function (extent, start + closure->from,
5618 end + closure->from)) 5598 end + closure->from))
5619 return 0; 5599 return 0;
5620 e = copy_extent (extent, start, end, closure->string); 5600 e = copy_extent (extent, start, end, closure->string);
5621 if (extent_replicating_p (extent))
5622 {
5623 Lisp_Object e_obj = Qnil, extent_obj = Qnil;
5624
5625 XSETEXTENT (e_obj, e);
5626 XSETEXTENT (extent_obj, extent);
5627 Fset_extent_parent (e_obj, extent_obj);
5628 }
5629 } 5601 }
5630 5602
5631 return 0; 5603 return 0;
5632 } 5604 }
5633 5605
5691 return 0; 5663 return 0;
5692 5664
5693 if (!extent_duplicable_p (extent)) 5665 if (!extent_duplicable_p (extent))
5694 return 0; 5666 return 0;
5695 5667
5696 if (!extent_replicating_p (extent)) 5668 if (!inside_undo &&
5697 { 5669 !run_extent_paste_function (extent, new_start, new_end,
5698 if (!inside_undo && 5670 closure->buffer))
5699 !run_extent_paste_function (extent, new_start, new_end, 5671 return 0;
5700 closure->buffer)) 5672 copy_extent (extent, new_start, new_end, closure->buffer);
5701 return 0; 5673
5702 copy_extent (extent, new_start, new_end, closure->buffer);
5703 }
5704 else
5705 {
5706 Bytind parstart = 0;
5707 Bytind parend = 0;
5708 Lisp_Object parent_obj = extent_parent (extent);
5709 EXTENT parent;
5710
5711 if (!EXTENTP (parent_obj))
5712 return 0;
5713 parent = XEXTENT (parent_obj);
5714 if (!EXTENT_LIVE_P (parent))
5715 return 0;
5716
5717 if (!extent_detached_p (parent))
5718 {
5719 parstart = extent_endpoint_bytind (parent, 0);
5720 parend = extent_endpoint_bytind (parent, 1);
5721 }
5722
5723 /* #### remove this crap */
5724 #ifdef ENERGIZE
5725 /* Energize extents like toplevel-forms can only be pasted
5726 in the buffer they come from. This should be parametrized
5727 in the generic extent objects. Right now just silently
5728 skip the extents if it's not from the same buffer.
5729 */
5730 if (!EQ (extent_object (parent), closure->buffer)
5731 && energize_extent_data (parent))
5732 return 0;
5733 #endif
5734
5735 /* If this is a `unique' extent, and it is currently attached
5736 somewhere other than here (non-overlapping), then don't copy
5737 it (that's what `unique' means). If however it is detached,
5738 or if we are inserting inside/adjacent to the original
5739 extent, then insert_extent() will simply reattach it, which
5740 is what we want.
5741 */
5742 if (extent_unique_p (parent)
5743 && !extent_detached_p (parent)
5744 && (!EQ (extent_object (parent), closure->buffer)
5745 || parend > new_end
5746 || parstart < new_start))
5747 return 0;
5748
5749 insert_extent (parent, new_start, new_end,
5750 closure->buffer, !inside_undo);
5751 }
5752 return 0; 5674 return 0;
5753 } 5675 }
5754 5676
5755 /* We have just inserted a section of STRING (starting at POS, of 5677 /* We have just inserted a section of STRING (starting at POS, of
5756 length LENGTH) into buffer BUF at OPOINT. Do whatever is necessary 5678 length LENGTH) into buffer BUF at OPOINT. Do whatever is necessary
5799 copy_string_extents_1_mapper (EXTENT extent, void *arg) 5721 copy_string_extents_1_mapper (EXTENT extent, void *arg)
5800 { 5722 {
5801 struct copy_string_extents_1_arg *closure = 5723 struct copy_string_extents_1_arg *closure =
5802 (struct copy_string_extents_1_arg *) arg; 5724 (struct copy_string_extents_1_arg *) arg;
5803 5725
5804 if (extent_replicating_p (extent) &&
5805 EQ (extent_parent (extent), closure->parent_in_question))
5806 {
5807 closure->found_extent = extent;
5808 return 1; /* stop mapping */
5809 }
5810
5811 return 0; 5726 return 0;
5812 } 5727 }
5813 5728
5814 static int 5729 static int
5815 copy_string_extents_mapper (EXTENT extent, void *arg) 5730 copy_string_extents_mapper (EXTENT extent, void *arg)
5829 return 0; 5744 return 0;
5830 5745
5831 new_start = old_start + closure->new_pos - closure->old_pos; 5746 new_start = old_start + closure->new_pos - closure->old_pos;
5832 new_end = old_end + closure->new_pos - closure->old_pos; 5747 new_end = old_end + closure->new_pos - closure->old_pos;
5833 5748
5834 if (extent_replicating_p (extent))
5835 {
5836 struct copy_string_extents_1_arg closure_1;
5837
5838 closure_1.parent_in_question = extent_parent (extent);
5839 closure_1.found_extent = 0;
5840
5841 /* When adding a replicating extent, we need to make sure
5842 that there isn't an existing replicating extent referring
5843 to the same parent extent that abuts or overlaps. If so,
5844 we merge with that extent rather than adding anew. */
5845 map_extents_bytind (closure->old_pos, closure->old_pos + closure->length,
5846 copy_string_extents_1_mapper,
5847 (void *) &closure, closure->new_string, 0,
5848 /* get all extents that abut the region */
5849 ME_END_CLOSED | ME_ALL_EXTENTS_CLOSED);
5850 if (closure_1.found_extent)
5851 {
5852 Bytecount exstart =
5853 extent_endpoint_bytind (closure_1.found_extent, 0);
5854 Bytecount exend =
5855 extent_endpoint_bytind (closure_1.found_extent, 1);
5856 exstart = min (exstart, new_start);
5857 exend = max (exend, new_end);
5858 set_extent_endpoints (closure_1.found_extent, exstart, exend, Qnil);
5859 return 0;
5860 }
5861 }
5862
5863 copy_extent (extent, 5749 copy_extent (extent,
5864 old_start + closure->new_pos - closure->old_pos, 5750 old_start + closure->new_pos - closure->old_pos,
5865 old_end + closure->new_pos - closure->old_pos, 5751 old_end + closure->new_pos - closure->old_pos,
5866 closure->new_string); 5752 closure->new_string);
5867 return 0; 5753 return 0;
6660 defsymbol (&Qend_closed, "end-closed"); 6546 defsymbol (&Qend_closed, "end-closed");
6661 defsymbol (&Qread_only, "read-only"); 6547 defsymbol (&Qread_only, "read-only");
6662 /* defsymbol (&Qhighlight, "highlight"); in faces.c */ 6548 /* defsymbol (&Qhighlight, "highlight"); in faces.c */
6663 defsymbol (&Qunique, "unique"); 6549 defsymbol (&Qunique, "unique");
6664 defsymbol (&Qduplicable, "duplicable"); 6550 defsymbol (&Qduplicable, "duplicable");
6665 defsymbol (&Qreplicating, "replicating");
6666 defsymbol (&Qdetachable, "detachable"); 6551 defsymbol (&Qdetachable, "detachable");
6667 defsymbol (&Qpriority, "priority"); 6552 defsymbol (&Qpriority, "priority");
6668 defsymbol (&Qmouse_face, "mouse-face"); 6553 defsymbol (&Qmouse_face, "mouse-face");
6669 6554
6670 defsymbol (&Qglyph_layout, "glyph-layout"); /* backwards compatibility */ 6555 defsymbol (&Qglyph_layout, "glyph-layout"); /* backwards compatibility */