comparison src/extents.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents b8cc9ab3f761
children 41dbb7a9d5f2
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
225 #include "insdel.h" 225 #include "insdel.h"
226 #include "keymap.h" 226 #include "keymap.h"
227 #include "opaque.h" 227 #include "opaque.h"
228 #include "process.h" 228 #include "process.h"
229 #include "redisplay.h" 229 #include "redisplay.h"
230 #include "gutter.h"
231 230
232 /* ------------------------------- */ 231 /* ------------------------------- */
233 /* gap array */ 232 /* gap array */
234 /* ------------------------------- */ 233 /* ------------------------------- */
235 234
259 int numels; 258 int numels;
260 int elsize; 259 int elsize;
261 Gap_Array_Marker *markers; 260 Gap_Array_Marker *markers;
262 } Gap_Array; 261 } Gap_Array;
263 262
264 static Gap_Array_Marker *gap_array_marker_freelist; 263 Gap_Array_Marker *gap_array_marker_freelist;
265 264
266 /* Convert a "memory position" (i.e. taking the gap into account) into 265 /* Convert a "memory position" (i.e. taking the gap into account) into
267 the address of the element at (i.e. after) that position. "Memory 266 the address of the element at (i.e. after) that position. "Memory
268 positions" are only used internally and are of type Memind. 267 positions" are only used internally and are of type Memind.
269 "Array positions" are used externally and are of type int. */ 268 "Array positions" are used externally and are of type int. */
300 Gap_Array *start; 299 Gap_Array *start;
301 Gap_Array *end; 300 Gap_Array *end;
302 Extent_List_Marker *markers; 301 Extent_List_Marker *markers;
303 } Extent_List; 302 } Extent_List;
304 303
305 static Extent_List_Marker *extent_list_marker_freelist; 304 Extent_List_Marker *extent_list_marker_freelist;
306 305
307 #define EXTENT_LESS_VALS(e,st,nd) ((extent_start (e) < (st)) || \ 306 #define EXTENT_LESS_VALS(e,st,nd) ((extent_start (e) < (st)) || \
308 ((extent_start (e) == (st)) && \ 307 ((extent_start (e) == (st)) && \
309 (extent_end (e) > (nd)))) 308 (extent_end (e) > (nd))))
310 309
443 Lisp_Object Qoutside_margin; 442 Lisp_Object Qoutside_margin;
444 Lisp_Object Qinside_margin; 443 Lisp_Object Qinside_margin;
445 Lisp_Object Qwhitespace; 444 Lisp_Object Qwhitespace;
446 /* Qtext defined in general.c */ 445 /* Qtext defined in general.c */
447 446
447 /* partially used in redisplay */
448 Lisp_Object Qglyph_invisible;
449
448 Lisp_Object Qcopy_function; 450 Lisp_Object Qcopy_function;
449 Lisp_Object Qpaste_function; 451 Lisp_Object Qpaste_function;
450 452
451 /* The idea here is that if we're given a list of faces, we 453 /* The idea here is that if we're given a list of faces, we
452 need to "memoize" this so that two lists of faces that are `equal' 454 need to "memoize" this so that two lists of faces that are `equal'
460 Lisp_Object Vextent_face_reverse_memoize_hash_table; 462 Lisp_Object Vextent_face_reverse_memoize_hash_table;
461 Lisp_Object Vextent_face_reusable_list; 463 Lisp_Object Vextent_face_reusable_list;
462 /* FSFmacs bogosity */ 464 /* FSFmacs bogosity */
463 Lisp_Object Vdefault_text_properties; 465 Lisp_Object Vdefault_text_properties;
464 466
467
465 EXFUN (Fextent_properties, 1); 468 EXFUN (Fextent_properties, 1);
466 EXFUN (Fset_extent_property, 3); 469 EXFUN (Fset_extent_property, 3);
467
468 /* if true, we don't want to set any redisplay flags on modeline extent
469 changes */
470 int in_modeline_generation;
471 470
472 471
473 /************************************************************************/ 472 /************************************************************************/
474 /* Generalized gap array */ 473 /* Generalized gap array */
475 /************************************************************************/ 474 /************************************************************************/
889 888
890 static Extent_List * 889 static Extent_List *
891 allocate_extent_list (void) 890 allocate_extent_list (void)
892 { 891 {
893 Extent_List *el = xnew (Extent_List); 892 Extent_List *el = xnew (Extent_List);
894 el->start = make_gap_array (sizeof (EXTENT)); 893 el->start = make_gap_array (sizeof(EXTENT));
895 el->end = make_gap_array (sizeof (EXTENT)); 894 el->end = make_gap_array (sizeof(EXTENT));
896 el->markers = 0; 895 el->markers = 0;
897 return el; 896 return el;
898 } 897 }
899 898
900 static void 899 static void
909 /************************************************************************/ 908 /************************************************************************/
910 /* Auxiliary extent structure */ 909 /* Auxiliary extent structure */
911 /************************************************************************/ 910 /************************************************************************/
912 911
913 static Lisp_Object 912 static Lisp_Object
914 mark_extent_auxiliary (Lisp_Object obj) 913 mark_extent_auxiliary (Lisp_Object obj, void (*markobj) (Lisp_Object))
915 { 914 {
916 struct extent_auxiliary *data = XEXTENT_AUXILIARY (obj); 915 struct extent_auxiliary *data = XEXTENT_AUXILIARY (obj);
917 mark_object (data->begin_glyph); 916 markobj (data->begin_glyph);
918 mark_object (data->end_glyph); 917 markobj (data->end_glyph);
919 mark_object (data->invisible); 918 markobj (data->invisible);
920 mark_object (data->children); 919 markobj (data->children);
921 mark_object (data->read_only); 920 markobj (data->read_only);
922 mark_object (data->mouse_face); 921 markobj (data->mouse_face);
923 mark_object (data->initial_redisplay_function); 922 markobj (data->initial_redisplay_function);
924 mark_object (data->before_change_functions); 923 markobj (data->before_change_functions);
925 mark_object (data->after_change_functions); 924 markobj (data->after_change_functions);
926 return data->parent; 925 return data->parent;
927 } 926 }
928 927
929 DEFINE_LRECORD_IMPLEMENTATION ("extent-auxiliary", extent_auxiliary, 928 DEFINE_LRECORD_IMPLEMENTATION ("extent-auxiliary", extent_auxiliary,
930 mark_extent_auxiliary, internal_object_printer, 929 mark_extent_auxiliary, internal_object_printer,
931 0, 0, 0, 0, struct extent_auxiliary); 930 0, 0, 0, struct extent_auxiliary);
932 931
933 void 932 void
934 allocate_extent_auxiliary (EXTENT ext) 933 allocate_extent_auxiliary (EXTENT ext)
935 { 934 {
936 Lisp_Object extent_aux; 935 Lisp_Object extent_aux;
972 static struct stack_of_extents *allocate_soe (void); 971 static struct stack_of_extents *allocate_soe (void);
973 static void free_soe (struct stack_of_extents *soe); 972 static void free_soe (struct stack_of_extents *soe);
974 static void soe_invalidate (Lisp_Object obj); 973 static void soe_invalidate (Lisp_Object obj);
975 974
976 static Lisp_Object 975 static Lisp_Object
977 mark_extent_info (Lisp_Object obj) 976 mark_extent_info (Lisp_Object obj, void (*markobj) (Lisp_Object))
978 { 977 {
979 struct extent_info *data = (struct extent_info *) XEXTENT_INFO (obj); 978 struct extent_info *data = (struct extent_info *) XEXTENT_INFO (obj);
980 int i; 979 int i;
981 Extent_List *list = data->extents; 980 Extent_List *list = data->extents;
982 981
995 { 994 {
996 struct extent *extent = extent_list_at (list, i, 0); 995 struct extent *extent = extent_list_at (list, i, 0);
997 Lisp_Object exobj; 996 Lisp_Object exobj;
998 997
999 XSETEXTENT (exobj, extent); 998 XSETEXTENT (exobj, extent);
1000 mark_object (exobj); 999 markobj (exobj);
1001 } 1000 }
1002 } 1001 }
1003 1002
1004 return Qnil; 1003 return Qnil;
1005 } 1004 }
1024 } 1023 }
1025 } 1024 }
1026 1025
1027 DEFINE_LRECORD_IMPLEMENTATION ("extent-info", extent_info, 1026 DEFINE_LRECORD_IMPLEMENTATION ("extent-info", extent_info,
1028 mark_extent_info, internal_object_printer, 1027 mark_extent_info, internal_object_printer,
1029 finalize_extent_info, 0, 0, 0, 1028 finalize_extent_info, 0, 0,
1030 struct extent_info); 1029 struct extent_info);
1031 1030
1032 static Lisp_Object 1031 static Lisp_Object
1033 allocate_extent_info (void) 1032 allocate_extent_info (void)
1034 { 1033 {
1539 extent_endpoint_bytind (EXTENT extent, int endp) 1538 extent_endpoint_bytind (EXTENT extent, int endp)
1540 { 1539 {
1541 assert (EXTENT_LIVE_P (extent)); 1540 assert (EXTENT_LIVE_P (extent));
1542 assert (!extent_detached_p (extent)); 1541 assert (!extent_detached_p (extent));
1543 { 1542 {
1544 Memind i = endp ? extent_end (extent) : extent_start (extent); 1543 Memind i = (endp) ? (extent_end (extent)) :
1544 (extent_start (extent));
1545 Lisp_Object obj = extent_object (extent); 1545 Lisp_Object obj = extent_object (extent);
1546 return buffer_or_string_memind_to_bytind (obj, i); 1546 return buffer_or_string_memind_to_bytind (obj, i);
1547 } 1547 }
1548 } 1548 }
1549 1549
1551 extent_endpoint_bufpos (EXTENT extent, int endp) 1551 extent_endpoint_bufpos (EXTENT extent, int endp)
1552 { 1552 {
1553 assert (EXTENT_LIVE_P (extent)); 1553 assert (EXTENT_LIVE_P (extent));
1554 assert (!extent_detached_p (extent)); 1554 assert (!extent_detached_p (extent));
1555 { 1555 {
1556 Memind i = endp ? extent_end (extent) : extent_start (extent); 1556 Memind i = (endp) ? (extent_end (extent)) :
1557 (extent_start (extent));
1557 Lisp_Object obj = extent_object (extent); 1558 Lisp_Object obj = extent_object (extent);
1558 return buffer_or_string_memind_to_bufpos (obj, i); 1559 return buffer_or_string_memind_to_bufpos (obj, i);
1559 } 1560 }
1560 } 1561 }
1561 1562
1591 1592
1592 /* now mark the extent itself. */ 1593 /* now mark the extent itself. */
1593 1594
1594 object = extent_object (extent); 1595 object = extent_object (extent);
1595 1596
1596 if (extent_detached_p (extent)) 1597 if (!BUFFERP (object) || extent_detached_p (extent))
1598 /* #### Can changes to string extents affect redisplay?
1599 I will have to think about this. What about string glyphs?
1600 Things in the modeline? etc. */
1601 /* #### changes to string extents can certainly affect redisplay
1602 if the extent is in some generated-modeline-string: when
1603 we change an extent in generated-modeline-string, this changes
1604 its parent, which is in `modeline-format', so we should
1605 force the modeline to be updated. But how to determine whether
1606 a string is a `generated-modeline-string'? Looping through
1607 all buffers is not very efficient. Should we add all
1608 `generated-modeline-string' strings to a hash table?
1609 Maybe efficiency is not the greatest concern here and there's
1610 no big loss in looping over the buffers. */
1597 return; 1611 return;
1598 1612
1599 else if (STRINGP (object)) 1613 {
1600 { 1614 struct buffer *b;
1601 /* #### Changes to string extents can affect redisplay if they are 1615 b = XBUFFER (object);
1602 in the modeline or in the gutters. 1616 BUF_FACECHANGE (b)++;
1603 1617 MARK_EXTENTS_CHANGED;
1604 If the extent is in some generated-modeline-string: when we 1618 if (invisibility_change)
1605 change an extent in generated-modeline-string, this changes its 1619 MARK_CLIP_CHANGED;
1606 parent, which is in `modeline-format', so we should force the 1620 buffer_extent_signal_changed_region (b,
1607 modeline to be updated. But how to determine whether a string 1621 extent_endpoint_bufpos (extent, 0),
1608 is a `generated-modeline-string'? Looping through all buffers 1622 extent_endpoint_bufpos (extent, 1));
1609 is not very efficient. Should we add all 1623 }
1610 `generated-modeline-string' strings to a hash table? Maybe
1611 efficiency is not the greatest concern here and there's no big
1612 loss in looping over the buffers.
1613
1614 If the extent is in a gutter we mark the gutter as
1615 changed. This means (a) we can update extents in the gutters
1616 when we need it. (b) we don't have to update the gutters when
1617 only extents attached to buffers have changed. */
1618
1619 if (!in_modeline_generation)
1620 MARK_EXTENTS_CHANGED;
1621 gutter_extent_signal_changed_region_maybe (object,
1622 extent_endpoint_bufpos (extent, 0),
1623 extent_endpoint_bufpos (extent, 1));
1624 }
1625 else if (BUFFERP (object))
1626 {
1627 struct buffer *b;
1628 b = XBUFFER (object);
1629 BUF_FACECHANGE (b)++;
1630 MARK_EXTENTS_CHANGED;
1631 if (invisibility_change)
1632 MARK_CLIP_CHANGED;
1633 buffer_extent_signal_changed_region (b,
1634 extent_endpoint_bufpos (extent, 0),
1635 extent_endpoint_bufpos (extent, 1));
1636 }
1637 } 1624 }
1638 1625
1639 /* A change to an extent occurred that might affect redisplay. 1626 /* A change to an extent occurred that might affect redisplay.
1640 This is called when properties such as the endpoints, the layout, 1627 This is called when properties such as the endpoints, the layout,
1641 or the priority changes. Redisplay will be affected only if 1628 or the priority changes. Redisplay will be affected only if
2613 Dynarr_free (ef->begin_glyphs); 2600 Dynarr_free (ef->begin_glyphs);
2614 Dynarr_free (ef->end_glyphs); 2601 Dynarr_free (ef->end_glyphs);
2615 xfree (ef); 2602 xfree (ef);
2616 } 2603 }
2617 2604
2605 /* Note: CONST is losing, but `const' is part of the interface of qsort() */
2618 static int 2606 static int
2619 extent_priority_sort_function (const void *humpty, const void *dumpty) 2607 extent_priority_sort_function (const void *humpty, const void *dumpty)
2620 { 2608 {
2621 const EXTENT foo = * (const EXTENT *) humpty; 2609 CONST EXTENT foo = * (CONST EXTENT *) humpty;
2622 const EXTENT bar = * (const EXTENT *) dumpty; 2610 CONST EXTENT bar = * (CONST EXTENT *) dumpty;
2623 if (extent_priority (foo) < extent_priority (bar)) 2611 if (extent_priority (foo) < extent_priority (bar))
2624 return -1; 2612 return -1;
2625 return extent_priority (foo) > extent_priority (bar); 2613 return extent_priority (foo) > extent_priority (bar);
2626 } 2614 }
2627 2615
2923 2911
2924 /* These are the basic helper functions for handling the allocation of 2912 /* These are the basic helper functions for handling the allocation of
2925 extent objects. They are similar to the functions for other 2913 extent objects. They are similar to the functions for other
2926 lrecord objects. allocate_extent() is in alloc.c, not here. */ 2914 lrecord objects. allocate_extent() is in alloc.c, not here. */
2927 2915
2916 static Lisp_Object mark_extent (Lisp_Object, void (*) (Lisp_Object));
2917 static int extent_equal (Lisp_Object, Lisp_Object, int depth);
2918 static unsigned long extent_hash (Lisp_Object obj, int depth);
2919 static void print_extent (Lisp_Object obj, Lisp_Object printcharfun,
2920 int escapeflag);
2921 static Lisp_Object extent_getprop (Lisp_Object obj, Lisp_Object prop);
2922 static int extent_putprop (Lisp_Object obj, Lisp_Object prop,
2923 Lisp_Object value);
2924 static int extent_remprop (Lisp_Object obj, Lisp_Object prop);
2925 static Lisp_Object extent_plist (Lisp_Object obj);
2926
2927 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS ("extent", extent,
2928 mark_extent,
2929 print_extent,
2930 /* NOTE: If you declare a
2931 finalization method here,
2932 it will NOT be called.
2933 Shaft city. */
2934 0,
2935 extent_equal, extent_hash,
2936 extent_getprop, extent_putprop,
2937 extent_remprop, extent_plist,
2938 struct extent);
2939
2928 static Lisp_Object 2940 static Lisp_Object
2929 mark_extent (Lisp_Object obj) 2941 mark_extent (Lisp_Object obj, void (*markobj) (Lisp_Object))
2930 { 2942 {
2931 struct extent *extent = XEXTENT (obj); 2943 struct extent *extent = XEXTENT (obj);
2932 2944
2933 mark_object (extent_object (extent)); 2945 markobj (extent_object (extent));
2934 mark_object (extent_no_chase_normal_field (extent, face)); 2946 markobj (extent_no_chase_normal_field (extent, face));
2935 return extent->plist; 2947 return extent->plist;
2936 } 2948 }
2937 2949
2938 static void 2950 static void
2939 print_extent_1 (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) 2951 print_extent_1 (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
2948 if (!NILP (extent_begin_glyph (anc))) *bp++ = '*'; 2960 if (!NILP (extent_begin_glyph (anc))) *bp++ = '*';
2949 *bp++ = (extent_start_open_p (anc) ? '(': '['); 2961 *bp++ = (extent_start_open_p (anc) ? '(': '[');
2950 if (extent_detached_p (ext)) 2962 if (extent_detached_p (ext))
2951 strcpy (bp, "detached"); 2963 strcpy (bp, "detached");
2952 else 2964 else
2953 sprintf (bp, "%ld, %ld", 2965 {
2954 (long) XINT (Fextent_start_position (obj)), 2966 Bufpos from = XINT (Fextent_start_position (obj));
2955 (long) XINT (Fextent_end_position (obj))); 2967 Bufpos to = XINT (Fextent_end_position (obj));
2968 sprintf (bp, "%d, %d", from, to);
2969 }
2956 bp += strlen (bp); 2970 bp += strlen (bp);
2957 *bp++ = (extent_end_open_p (anc) ? ')': ']'); 2971 *bp++ = (extent_end_open_p (anc) ? ')': ']');
2958 if (!NILP (extent_end_glyph (anc))) *bp++ = '*'; 2972 if (!NILP (extent_end_glyph (anc))) *bp++ = '*';
2959 *bp++ = ' '; 2973 *bp++ = ' ';
2960 2974
2988 static void 3002 static void
2989 print_extent (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) 3003 print_extent (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
2990 { 3004 {
2991 if (escapeflag) 3005 if (escapeflag)
2992 { 3006 {
2993 const char *title = ""; 3007 CONST char *title = "";
2994 const char *name = ""; 3008 CONST char *name = "";
2995 const char *posttitle = ""; 3009 CONST char *posttitle = "";
2996 Lisp_Object obj2 = Qnil; 3010 Lisp_Object obj2 = Qnil;
2997 3011
2998 /* Destroyed extents have 't' in the object field, causing 3012 /* Destroyed extents have 't' in the object field, causing
2999 extent_object() to abort (maybe). */ 3013 extent_object() to abort (maybe). */
3000 if (EXTENT_LIVE_P (XEXTENT (obj))) 3014 if (EXTENT_LIVE_P (XEXTENT (obj)))
3111 /* No need to hash all of the elements; that would take too long. 3125 /* No need to hash all of the elements; that would take too long.
3112 Just hash the most common ones. */ 3126 Just hash the most common ones. */
3113 return HASH3 (extent_start (e), extent_end (e), 3127 return HASH3 (extent_start (e), extent_end (e),
3114 internal_hash (extent_object (e), depth + 1)); 3128 internal_hash (extent_object (e), depth + 1));
3115 } 3129 }
3116
3117 static const struct lrecord_description extent_description[] = {
3118 { XD_LISP_OBJECT, offsetof (struct extent, object) },
3119 { XD_LISP_OBJECT, offsetof (struct extent, flags.face) },
3120 { XD_LISP_OBJECT, offsetof (struct extent, plist) },
3121 { XD_END }
3122 };
3123 3130
3124 static Lisp_Object 3131 static Lisp_Object
3125 extent_getprop (Lisp_Object obj, Lisp_Object prop) 3132 extent_getprop (Lisp_Object obj, Lisp_Object prop)
3126 { 3133 {
3127 return Fextent_property (obj, prop, Qunbound); 3134 return Fextent_property (obj, prop, Qunbound);
3168 { 3175 {
3169 /* #### Is this correct, anyway? */ 3176 /* #### Is this correct, anyway? */
3170 return -1; 3177 return -1;
3171 } 3178 }
3172 3179
3173 return external_remprop (extent_plist_addr (ext), prop, 0, ERROR_ME); 3180 return external_remprop (&ext->plist, prop, 0, ERROR_ME);
3174 } 3181 }
3175 3182
3176 static Lisp_Object 3183 static Lisp_Object
3177 extent_plist (Lisp_Object obj) 3184 extent_plist (Lisp_Object obj)
3178 { 3185 {
3179 return Fextent_properties (obj); 3186 return Fextent_properties (obj);
3180 } 3187 }
3181
3182 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS ("extent", extent,
3183 mark_extent,
3184 print_extent,
3185 /* NOTE: If you declare a
3186 finalization method here,
3187 it will NOT be called.
3188 Shaft city. */
3189 0,
3190 extent_equal, extent_hash,
3191 extent_description,
3192 extent_getprop, extent_putprop,
3193 extent_remprop, extent_plist,
3194 struct extent);
3195 3188
3196 3189
3197 /************************************************************************/ 3190 /************************************************************************/
3198 /* basic extent accessors */ 3191 /* basic extent accessors */
3199 /************************************************************************/ 3192 /************************************************************************/
4621 Bufpos start, end; 4614 Bufpos start, end;
4622 int afterp; 4615 int afterp;
4623 int speccount; 4616 int speccount;
4624 }; 4617 };
4625 4618
4619 /* This juggling with the pointer to another file's global variable is
4620 kind of yucky. Perhaps I should just export the variable. */
4621 static int *inside_change_hook_pointer;
4622
4626 static Lisp_Object 4623 static Lisp_Object
4627 report_extent_modification_restore (Lisp_Object buffer) 4624 report_extent_modification_restore (Lisp_Object buffer)
4628 { 4625 {
4626 *inside_change_hook_pointer = 0;
4629 if (current_buffer != XBUFFER (buffer)) 4627 if (current_buffer != XBUFFER (buffer))
4630 Fset_buffer (buffer); 4628 Fset_buffer (buffer);
4631 return Qnil; 4629 return Qnil;
4632 } 4630 }
4633 4631
4648 XSETINT (endobj, closure->end); 4646 XSETINT (endobj, closure->end);
4649 4647
4650 /* Now that we are sure to call elisp, set up an unwind-protect so 4648 /* Now that we are sure to call elisp, set up an unwind-protect so
4651 inside_change_hook gets restored in case we throw. Also record 4649 inside_change_hook gets restored in case we throw. Also record
4652 the current buffer, in case we change it. Do the recording only 4650 the current buffer, in case we change it. Do the recording only
4653 once. 4651 once. */
4654
4655 One confusing thing here is that our caller never actually calls
4656 unbind_to (closure.speccount, Qnil). This is because
4657 map_extents_bytind() unbinds before, and with a smaller
4658 speccount. The additional unbind_to() in
4659 report_extent_modification() would cause XEmacs to abort. */
4660 if (closure->speccount == -1) 4652 if (closure->speccount == -1)
4661 { 4653 {
4662 closure->speccount = specpdl_depth (); 4654 closure->speccount = specpdl_depth ();
4663 record_unwind_protect (report_extent_modification_restore, 4655 record_unwind_protect (report_extent_modification_restore,
4664 Fcurrent_buffer ()); 4656 Fcurrent_buffer ());
4670 Fset_buffer (closure->buffer); 4662 Fset_buffer (closure->buffer);
4671 4663
4672 /* #### It's a shame that we can't use any of the existing run_hook* 4664 /* #### It's a shame that we can't use any of the existing run_hook*
4673 functions here. This is so because all of them work with 4665 functions here. This is so because all of them work with
4674 symbols, to be able to retrieve default values of local hooks. 4666 symbols, to be able to retrieve default values of local hooks.
4675 <sigh> 4667 <sigh> */
4676
4677 #### Idea: we could set up a dummy symbol, and call the hook
4678 functions on *that*. */
4679 4668
4680 if (!CONSP (hook) || EQ (XCAR (hook), Qlambda)) 4669 if (!CONSP (hook) || EQ (XCAR (hook), Qlambda))
4681 call3 (hook, exobj, startobj, endobj); 4670 call3 (hook, exobj, startobj, endobj);
4682 else 4671 else
4683 { 4672 {
4684 Lisp_Object tail; 4673 Lisp_Object tail;
4685 EXTERNAL_LIST_LOOP (tail, hook) 4674 EXTERNAL_LIST_LOOP (tail, hook)
4686 /* #### Shouldn't this perform the same Fset_buffer() check as
4687 above? */
4688 call3 (XCAR (tail), exobj, startobj, endobj); 4675 call3 (XCAR (tail), exobj, startobj, endobj);
4689 } 4676 }
4690 return 0; 4677 return 0;
4691 } 4678 }
4692 4679
4693 void 4680 void
4694 report_extent_modification (Lisp_Object buffer, Bufpos start, Bufpos end, 4681 report_extent_modification (Lisp_Object buffer, Bufpos start, Bufpos end,
4695 int afterp) 4682 int *inside, int afterp)
4696 { 4683 {
4697 struct report_extent_modification_closure closure; 4684 struct report_extent_modification_closure closure;
4698 4685
4699 closure.buffer = buffer; 4686 closure.buffer = buffer;
4700 closure.start = start; 4687 closure.start = start;
4701 closure.end = end; 4688 closure.end = end;
4702 closure.afterp = afterp; 4689 closure.afterp = afterp;
4703 closure.speccount = -1; 4690 closure.speccount = -1;
4704 4691
4692 inside_change_hook_pointer = inside;
4693 *inside = 1;
4694
4705 map_extents (start, end, report_extent_modification_mapper, (void *)&closure, 4695 map_extents (start, end, report_extent_modification_mapper, (void *)&closure,
4706 buffer, NULL, ME_MIGHT_CALL_ELISP); 4696 buffer, NULL, ME_MIGHT_CALL_ELISP);
4697
4698 if (closure.speccount == -1)
4699 *inside = 0;
4700 else
4701 {
4702 /* We mustn't unbind when closure.speccount != -1 because
4703 map_extents_bytind has already done that. */
4704 assert (*inside == 0);
4705 }
4707 } 4706 }
4708 4707
4709 4708
4710 /************************************************************************/ 4709 /************************************************************************/
4711 /* extent properties */ 4710 /* extent properties */
5005 5004
5006 static Lisp_Object 5005 static Lisp_Object
5007 set_extent_glyph_1 (Lisp_Object extent_obj, Lisp_Object glyph, int endp, 5006 set_extent_glyph_1 (Lisp_Object extent_obj, Lisp_Object glyph, int endp,
5008 Lisp_Object layout_obj) 5007 Lisp_Object layout_obj)
5009 { 5008 {
5010 EXTENT extent = decode_extent (extent_obj, 0); 5009 EXTENT extent = decode_extent (extent_obj, DE_MUST_HAVE_BUFFER);
5011 glyph_layout layout = symbol_to_glyph_layout (layout_obj); 5010 glyph_layout layout = symbol_to_glyph_layout (layout_obj);
5012 5011
5013 /* Make sure we've actually been given a valid glyph or it's nil 5012 /* Make sure we've actually been given a valid glyph or it's nil
5014 (meaning we're deleting a glyph from an extent). */ 5013 (meaning we're deleting a glyph from an extent). */
5015 if (!NILP (glyph)) 5014 if (!NILP (glyph))
6675 /************************************************************************/ 6674 /************************************************************************/
6676 6675
6677 void 6676 void
6678 syms_of_extents (void) 6677 syms_of_extents (void)
6679 { 6678 {
6680 INIT_LRECORD_IMPLEMENTATION (extent);
6681 INIT_LRECORD_IMPLEMENTATION (extent_info);
6682 INIT_LRECORD_IMPLEMENTATION (extent_auxiliary);
6683
6684 defsymbol (&Qextentp, "extentp"); 6679 defsymbol (&Qextentp, "extentp");
6685 defsymbol (&Qextent_live_p, "extent-live-p"); 6680 defsymbol (&Qextent_live_p, "extent-live-p");
6686 6681
6687 defsymbol (&Qall_extents_closed, "all-extents-closed"); 6682 defsymbol (&Qall_extents_closed, "all-extents-closed");
6688 defsymbol (&Qall_extents_open, "all-extents-open"); 6683 defsymbol (&Qall_extents_open, "all-extents-open");
6717 defsymbol (&Qend_glyph_layout, "end-glyph-layout"); 6712 defsymbol (&Qend_glyph_layout, "end-glyph-layout");
6718 defsymbol (&Qoutside_margin, "outside-margin"); 6713 defsymbol (&Qoutside_margin, "outside-margin");
6719 defsymbol (&Qinside_margin, "inside-margin"); 6714 defsymbol (&Qinside_margin, "inside-margin");
6720 defsymbol (&Qwhitespace, "whitespace"); 6715 defsymbol (&Qwhitespace, "whitespace");
6721 /* Qtext defined in general.c */ 6716 /* Qtext defined in general.c */
6717
6718 defsymbol (&Qglyph_invisible, "glyph-invisible");
6722 6719
6723 defsymbol (&Qpaste_function, "paste-function"); 6720 defsymbol (&Qpaste_function, "paste-function");
6724 defsymbol (&Qcopy_function, "copy-function"); 6721 defsymbol (&Qcopy_function, "copy-function");
6725 6722
6726 defsymbol (&Qtext_prop, "text-prop"); 6723 defsymbol (&Qtext_prop, "text-prop");
6794 DEFSUBR (Fnext_single_property_change); 6791 DEFSUBR (Fnext_single_property_change);
6795 DEFSUBR (Fprevious_single_property_change); 6792 DEFSUBR (Fprevious_single_property_change);
6796 } 6793 }
6797 6794
6798 void 6795 void
6799 reinit_vars_of_extents (void)
6800 {
6801 extent_auxiliary_defaults.begin_glyph = Qnil;
6802 extent_auxiliary_defaults.end_glyph = Qnil;
6803 extent_auxiliary_defaults.parent = Qnil;
6804 extent_auxiliary_defaults.children = Qnil;
6805 extent_auxiliary_defaults.priority = 0;
6806 extent_auxiliary_defaults.invisible = Qnil;
6807 extent_auxiliary_defaults.read_only = Qnil;
6808 extent_auxiliary_defaults.mouse_face = Qnil;
6809 extent_auxiliary_defaults.initial_redisplay_function = Qnil;
6810 extent_auxiliary_defaults.before_change_functions = Qnil;
6811 extent_auxiliary_defaults.after_change_functions = Qnil;
6812 }
6813
6814 void
6815 vars_of_extents (void) 6796 vars_of_extents (void)
6816 { 6797 {
6817 reinit_vars_of_extents ();
6818
6819 DEFVAR_INT ("mouse-highlight-priority", &mouse_highlight_priority /* 6798 DEFVAR_INT ("mouse-highlight-priority", &mouse_highlight_priority /*
6820 The priority to use for the mouse-highlighting pseudo-extent 6799 The priority to use for the mouse-highlighting pseudo-extent
6821 that is used to highlight extents with the `mouse-face' attribute set. 6800 that is used to highlight extents with the `mouse-face' attribute set.
6822 See `set-extent-priority'. 6801 See `set-extent-priority'.
6823 */ ); 6802 */ );
6840 staticpro (&Vlast_highlighted_extent); 6819 staticpro (&Vlast_highlighted_extent);
6841 Vlast_highlighted_extent = Qnil; 6820 Vlast_highlighted_extent = Qnil;
6842 6821
6843 Vextent_face_reusable_list = Fcons (Qnil, Qnil); 6822 Vextent_face_reusable_list = Fcons (Qnil, Qnil);
6844 staticpro (&Vextent_face_reusable_list); 6823 staticpro (&Vextent_face_reusable_list);
6824
6825 extent_auxiliary_defaults.begin_glyph = Qnil;
6826 extent_auxiliary_defaults.end_glyph = Qnil;
6827 extent_auxiliary_defaults.parent = Qnil;
6828 extent_auxiliary_defaults.children = Qnil;
6829 extent_auxiliary_defaults.priority = 0;
6830 extent_auxiliary_defaults.invisible = Qnil;
6831 extent_auxiliary_defaults.read_only = Qnil;
6832 extent_auxiliary_defaults.mouse_face = Qnil;
6833 extent_auxiliary_defaults.initial_redisplay_function = Qnil;
6834 extent_auxiliary_defaults.before_change_functions = Qnil;
6835 extent_auxiliary_defaults.after_change_functions = Qnil;
6845 } 6836 }
6846 6837
6847 void 6838 void
6848 complex_vars_of_extents (void) 6839 complex_vars_of_extents (void)
6849 { 6840 {