Mercurial > hg > xemacs-beta
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 { |