428
|
1 /* Copyright (c) 1994, 1995 Free Software Foundation.
|
|
2 Copyright (c) 1995 Ben Wing.
|
|
3
|
|
4 This file is part of XEmacs.
|
|
5
|
|
6 XEmacs is free software; you can redistribute it and/or modify it
|
|
7 under the terms of the GNU General Public License as published by the
|
|
8 Free Software Foundation; either version 2, or (at your option) any
|
|
9 later version.
|
|
10
|
|
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
|
|
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
14 for more details.
|
|
15
|
|
16 You should have received a copy of the GNU General Public License
|
|
17 along with XEmacs; see the file COPYING. If not, write to
|
|
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
19 Boston, MA 02111-1307, USA. */
|
|
20
|
|
21 /* Synched up with: Not in FSF. */
|
|
22
|
440
|
23 #ifndef INCLUDED_extents_h_
|
|
24 #define INCLUDED_extents_h_
|
428
|
25
|
|
26 DECLARE_LRECORD (extent, struct extent);
|
|
27 #define XEXTENT(x) XRECORD (x, extent, struct extent)
|
617
|
28 #define wrap_extent(p) wrap_record (p, extent)
|
428
|
29 #define EXTENTP(x) RECORDP (x, extent)
|
|
30 #define CHECK_EXTENT(x) CHECK_RECORD (x, extent)
|
|
31 #define CONCHECK_EXTENT(x) CONCHECK_RECORD (x, extent)
|
|
32
|
|
33 /* the layouts for glyphs (extent->flags.glyph_layout). Must fit in 2 bits. */
|
|
34 typedef enum glyph_layout
|
|
35 {
|
|
36 GL_TEXT,
|
|
37 GL_OUTSIDE_MARGIN,
|
|
38 GL_INSIDE_MARGIN,
|
|
39 GL_WHITESPACE
|
|
40 } glyph_layout;
|
|
41
|
|
42 struct extent
|
|
43 {
|
|
44 struct lrecord_header lheader;
|
|
45
|
665
|
46 Membpos start;
|
|
47 Membpos end;
|
428
|
48 Lisp_Object object; /* A buffer, string, Qnil (extent detached from no
|
|
49 buffer), Qt (destroyed extent) */
|
|
50
|
|
51 /* Extent properties are conceptually a plist, but the most common
|
|
52 props are implemented as bits instead of conses. */
|
|
53 struct
|
|
54 {
|
|
55 Lisp_Object face;
|
|
56
|
|
57 /* These flags are simply an optimization for common boolean properties
|
|
58 which go onto the extent's property list. Any of them would work if
|
|
59 done in the normal way, but the space savings of doing these in this
|
|
60 way is significant. Note that if you add a flag, there are numerous
|
|
61 places in extents.c that need to know about it.
|
|
62
|
|
63 Another consideration is that some of these properties are accessed
|
|
64 during redisplay, so it's good for access to them to be fast (a bit
|
|
65 reference instead of a search down a plist).
|
|
66
|
|
67 `begin_glyph_layout' and `end_glyph_layout' are unusual in that
|
|
68 they have 4 states instead of 2.
|
|
69
|
|
70 Other special extent properties are stored in an auxiliary
|
|
71 structure that sits at the beginning of the plist. The has_aux
|
|
72 flag indicates whether this structure exists. The has_parent
|
|
73 flag is an optimization indicating whether the extent has a parent
|
|
74 (this could also be determined by looking in the aux structure). */
|
|
75
|
|
76 enum_field (glyph_layout) begin_glyph_layout :2;
|
|
77 /* 2 text, margins, or whitespace */
|
|
78 enum_field (glyph_layout) end_glyph_layout :2;
|
|
79 /* 4 text, margins, or whitespace */
|
|
80 unsigned int has_parent :1; /* 5 extent has a parent */
|
|
81 unsigned int has_aux :1; /* 6 extent has an aux. structure */
|
|
82 unsigned int start_open :1; /* 7 insertion behavior at start */
|
|
83 unsigned int end_open :1; /* 8 insertion behavior at end */
|
|
84 unsigned int unique :1; /* 9 there may be only one attached */
|
|
85 unsigned int duplicable :1; /* 10 copied to strings by kill/undo */
|
|
86 unsigned int detachable :1; /* 11 extent detaches if text deleted */
|
|
87 unsigned int internal :1; /* 12 used by map-extents etc. */
|
|
88 unsigned int in_red_event :1; /* 13 An event has been spawned for
|
|
89 initial redisplay.
|
|
90 (not exported to lisp) */
|
|
91 unsigned int unused16 :1; /* 16 unused bits */
|
|
92 /* --- Adding more flags will cause the extent struct to grow by another
|
|
93 word. It's not clear that this would make a difference, however,
|
|
94 because on 32-bit machines things tend to get allocated in chunks
|
|
95 of 4 bytes. */
|
|
96 } flags;
|
|
97 /* The plist may have an auxiliary structure as its first element */
|
|
98 Lisp_Object plist;
|
|
99 };
|
|
100
|
|
101 /* Basic properties of an extent (not affected by the extent's parent) */
|
|
102 #define extent_object(e) ((e)->object)
|
|
103 #define extent_start(e) ((e)->start + 0)
|
|
104 #define extent_end(e) ((e)->end + 0)
|
|
105 #define set_extent_start(e, val) ((void) ((e)->start = (val)))
|
|
106 #define set_extent_end(e, val) ((void) ((e)->end = (val)))
|
|
107 #define extent_endpoint(e, endp) ((endp) ? extent_end (e) : extent_start (e))
|
|
108 #define set_extent_endpoint(e, val, endp) \
|
|
109 ((endp) ? set_extent_end (e, val) : set_extent_start (e, val))
|
|
110 #define extent_detached_p(e) (extent_start (e) < 0)
|
|
111
|
|
112 /* Additional information that may be present in an extent. The idea is
|
|
113 that fast access is provided to this information, but since (hopefully)
|
|
114 most extents won't have this set on them, we usually don't need to
|
|
115 have this structure around and thus the size of an extent is smaller. */
|
|
116
|
|
117 typedef struct extent_auxiliary extent_auxiliary;
|
|
118 struct extent_auxiliary
|
|
119 {
|
|
120 struct lcrecord_header header;
|
|
121
|
|
122 Lisp_Object begin_glyph;
|
|
123 Lisp_Object end_glyph;
|
|
124 Lisp_Object parent;
|
|
125 /* We use a weak list here. Originally I didn't do this and
|
|
126 depended on having the extent's finalization method remove
|
|
127 itself from its parent's children list. This runs into
|
|
128 lots and lots of problems though because everything is in
|
|
129 a really really bizarre state when an extent's finalization
|
|
130 method is called (it happens in sweep_extents() by way of
|
|
131 ADDITIONAL_FREE_extent()) and it's extremely difficult to
|
|
132 avoid getting hosed by just-freed objects. */
|
|
133 Lisp_Object children;
|
|
134 Lisp_Object invisible;
|
|
135 Lisp_Object read_only;
|
|
136 Lisp_Object mouse_face;
|
|
137 Lisp_Object initial_redisplay_function;
|
|
138 Lisp_Object before_change_functions, after_change_functions;
|
|
139 int priority;
|
|
140 };
|
|
141
|
|
142 extern struct extent_auxiliary extent_auxiliary_defaults;
|
|
143
|
|
144 DECLARE_LRECORD (extent_auxiliary, struct extent_auxiliary);
|
|
145 #define XEXTENT_AUXILIARY(x) \
|
|
146 XRECORD (x, extent_auxiliary, struct extent_auxiliary)
|
617
|
147 #define wrap_extent_auxiliary(p) wrap_record (p, extent_auxiliary)
|
428
|
148 #define EXTENT_AUXILIARYP(x) RECORDP (x, extent_auxiliary)
|
|
149 #define CHECK_EXTENT_AUXILIARY(x) CHECK_RECORD (x, extent_auxiliary)
|
|
150 #define CONCHECK_EXTENT_AUXILIARY(x) CONCHECK_RECORD (x, extent_auxiliary)
|
|
151
|
|
152 struct extent_info
|
|
153 {
|
|
154 struct lcrecord_header header;
|
|
155
|
|
156 struct extent_list *extents;
|
|
157 struct stack_of_extents *soe;
|
|
158 };
|
|
159
|
|
160 DECLARE_LRECORD (extent_info, struct extent_info);
|
|
161 #define XEXTENT_INFO(x) XRECORD (x, extent_info, struct extent_info)
|
617
|
162 #define wrap_extent_info(p) wrap_record (p, extent_info)
|
428
|
163 #define EXTENT_INFOP(x) RECORDP (x, extent_info)
|
|
164 #define CHECK_EXTENT_INFO(x) CHECK_RECORD (x, extent_info)
|
|
165 #define CONCHECK_EXTENT_INFO(x) CONCHECK_RECORD (x, extent_info)
|
|
166
|
|
167 void flush_cached_extent_info (Lisp_Object extent_info);
|
|
168
|
|
169 /* A "normal" field is one that is stored in the `struct flags' structure
|
|
170 in an extent. an "aux" field is one that is stored in the extent's
|
|
171 auxiliary structure.
|
|
172
|
|
173 The functions below that have `extent_no_chase' in their name operate
|
|
174 on an extent directly (ignoring its parent), and should normally
|
|
175 only be used on extents known not to have a parent. The other
|
|
176 versions chase down any parent links. */
|
|
177
|
|
178 #define extent_no_chase_normal_field(e, field) ((e)->flags.field)
|
|
179
|
442
|
180 INLINE_HEADER struct extent_auxiliary *extent_aux_or_default (EXTENT e);
|
|
181 INLINE_HEADER struct extent_auxiliary *
|
428
|
182 extent_aux_or_default (EXTENT e)
|
|
183 {
|
|
184 return e->flags.has_aux ?
|
|
185 XEXTENT_AUXILIARY (XCAR (e->plist)) :
|
|
186 & extent_auxiliary_defaults;
|
|
187 }
|
|
188
|
|
189 #define extent_no_chase_aux_field(e, field) (extent_aux_or_default(e)->field)
|
|
190
|
|
191 #define extent_normal_field(e, field) \
|
|
192 extent_no_chase_normal_field (extent_ancestor (e), field)
|
|
193
|
|
194 #define extent_aux_field(e, field) \
|
|
195 extent_no_chase_aux_field (extent_ancestor (e), field)
|
|
196
|
|
197 #define set_extent_no_chase_aux_field(e, field, value) do { \
|
|
198 EXTENT sencaf_e = (e); \
|
|
199 if (! sencaf_e->flags.has_aux) \
|
|
200 allocate_extent_auxiliary (sencaf_e); \
|
|
201 XEXTENT_AUXILIARY (XCAR (sencaf_e->plist))->field = (value);\
|
|
202 } while (0)
|
|
203
|
|
204 #define set_extent_no_chase_normal_field(e, field, value) \
|
|
205 extent_no_chase_normal_field (e, field) = (value)
|
|
206
|
|
207 #define set_extent_aux_field(e, field, value) \
|
|
208 set_extent_no_chase_aux_field (extent_ancestor (e), field, value)
|
|
209
|
|
210 #define set_extent_normal_field(e, field, value) \
|
647
|
211 set_extent_no_chase_normal_field (extent_ancestor (e), field, value)
|
428
|
212
|
|
213 /* The `parent' and `children' fields are not affected by any
|
|
214 parent links. We don't provide any settors for these fields
|
|
215 because they need special handling and it's cleaner just to
|
|
216 do this in the particular functions that need to do this. */
|
|
217
|
|
218 #define extent_parent(e) extent_no_chase_aux_field (e, parent)
|
|
219 #define extent_children(e) extent_no_chase_aux_field (e, children)
|
|
220
|
|
221 #define extent_begin_glyph(e) extent_aux_field (e, begin_glyph)
|
|
222 #define extent_end_glyph(e) extent_aux_field (e, end_glyph)
|
|
223 #define extent_priority(e) extent_aux_field (e, priority)
|
|
224 #define extent_invisible(e) extent_aux_field (e, invisible)
|
|
225 #define extent_read_only(e) extent_aux_field (e, read_only)
|
|
226 #define extent_mouse_face(e) extent_aux_field (e, mouse_face)
|
|
227 #define extent_initial_redisplay_function(e) extent_aux_field (e, initial_redisplay_function)
|
|
228 #define extent_before_change_functions(e) extent_aux_field (e, before_change_functions)
|
|
229 #define extent_after_change_functions(e) extent_aux_field (e, after_change_functions)
|
|
230
|
|
231 #define set_extent_begin_glyph(e, value) \
|
|
232 set_extent_aux_field (e, begin_glyph, value)
|
|
233 #define set_extent_end_glyph(e, value) \
|
|
234 set_extent_aux_field (e, end_glyph, value)
|
|
235 #define set_extent_priority(e, value) \
|
|
236 set_extent_aux_field (e, priority, value)
|
|
237 #define set_extent_invisible_1(e, value) \
|
|
238 set_extent_aux_field (e, invisible, value)
|
|
239 #define set_extent_read_only(e, value) \
|
|
240 set_extent_aux_field (e, read_only, value)
|
|
241 #define set_extent_mouse_face(e, value) \
|
|
242 set_extent_aux_field (e, mouse_face, value)
|
|
243 /* Use Fset_extent_initial_redisplay_function unless you know what you're doing */
|
|
244 #define set_extent_initial_redisplay_function(e, value) \
|
|
245 set_extent_aux_field (e, initial_redisplay_function, value)
|
|
246 #define set_extent_before_change_functions(e, value) \
|
|
247 set_extent_aux_field (e, before_change_functions, value)
|
|
248 #define set_extent_after_change_functions(e, value) \
|
|
249 set_extent_aux_field (e, after_change_functions, value)
|
|
250
|
|
251 #define extent_face(e) extent_normal_field (e, face)
|
647
|
252 #define extent_begin_glyph_layout(e) ((enum glyph_layout) extent_normal_field (e, begin_glyph_layout))
|
|
253 #define extent_end_glyph_layout(e) ((enum glyph_layout) extent_normal_field (e, end_glyph_layout))
|
428
|
254 #define extent_start_open_p(e) extent_normal_field (e, start_open)
|
|
255 #define extent_end_open_p(e) extent_normal_field (e, end_open)
|
|
256 #define extent_unique_p(e) extent_normal_field (e, unique)
|
|
257 #define extent_duplicable_p(e) extent_normal_field (e, duplicable)
|
|
258 #define extent_detachable_p(e) extent_normal_field (e, detachable)
|
|
259 #define extent_internal_p(e) extent_normal_field (e, internal)
|
|
260 #define extent_in_red_event_p(e) extent_normal_field (e, in_red_event)
|
|
261
|
647
|
262 #define set_extent_face(e, val) \
|
|
263 set_extent_normal_field (e, face, val)
|
|
264 #define set_extent_begin_glyph_layout(e, val) \
|
|
265 set_extent_normal_field (e, begin_glyph_layout, val)
|
|
266 #define set_extent_end_glyph_layout(e, val) \
|
|
267 set_extent_normal_field (e, end_glyph_layout, val)
|
|
268 #define set_extent_start_open_p(e, val) \
|
|
269 set_extent_normal_field (e, start_open, val)
|
|
270 #define set_extent_end_open_p(e, val) \
|
|
271 set_extent_normal_field (e, end_open, val)
|
|
272 #define set_extent_unique_p(e, val) \
|
|
273 set_extent_normal_field (e, unique, val)
|
|
274 #define set_extent_duplicable_p(e, val) \
|
|
275 set_extent_normal_field (e, duplicable, val)
|
|
276 #define set_extent_detachable_p(e, val) \
|
|
277 set_extent_normal_field (e, detachable, val)
|
|
278 #define set_extent_internal_p(e, val) \
|
|
279 set_extent_normal_field (e, internal, val)
|
|
280 #define set_extent_in_red_event_p(e, val) \
|
|
281 set_extent_normal_field (e, in_red_event, val)
|
|
282
|
442
|
283 INLINE_HEADER Lisp_Object * extent_no_chase_plist_addr (EXTENT e);
|
|
284 INLINE_HEADER Lisp_Object *
|
428
|
285 extent_no_chase_plist_addr (EXTENT e)
|
|
286 {
|
|
287 return e->flags.has_aux ? &XCDR (e->plist) : &e->plist;
|
|
288 }
|
|
289
|
|
290 #define extent_no_chase_plist(e) (*extent_no_chase_plist_addr (e))
|
|
291
|
|
292 #define extent_plist_addr(e) extent_no_chase_plist_addr (extent_ancestor (e))
|
|
293 #define extent_plist_slot(e) extent_no_chase_plist (extent_ancestor (e))
|
|
294
|
|
295 /* flags for map_extents() and friends */
|
|
296 #define ME_END_CLOSED (1 << 0)
|
|
297 #define ME_START_OPEN (1 << 1)
|
|
298 #define ME_ALL_EXTENTS_CLOSED (1 << 2)
|
|
299 #define ME_ALL_EXTENTS_OPEN (2 << 2)
|
|
300 #define ME_ALL_EXTENTS_CLOSED_OPEN (3 << 2)
|
|
301 #define ME_ALL_EXTENTS_OPEN_CLOSED (4 << 2)
|
|
302 #define ME_ALL_EXTENTS_MASK (7 << 2)
|
|
303 #define ME_START_IN_REGION (1 << 5)
|
|
304 #define ME_END_IN_REGION (2 << 5)
|
|
305 #define ME_START_AND_END_IN_REGION (3 << 5)
|
|
306 #define ME_START_OR_END_IN_REGION (4 << 5)
|
|
307 #define ME_IN_REGION_MASK (7 << 5)
|
|
308 #define ME_NEGATE_IN_REGION (1 << 8)
|
|
309 /* the following flags are internal-only */
|
|
310 #define ME_INCLUDE_INTERNAL (1 << 9)
|
|
311 #define ME_MIGHT_THROW (1 << 10)
|
|
312 #define ME_MIGHT_MODIFY_TEXT (1 << 11)
|
|
313 #define ME_MIGHT_MODIFY_EXTENTS (1 << 12)
|
|
314 #define ME_MIGHT_MOVE_SOE (1 << 13)
|
|
315 #define ME_MIGHT_CALL_ELISP (ME_MIGHT_THROW | ME_MIGHT_MODIFY_TEXT | \
|
|
316 ME_MIGHT_MODIFY_EXTENTS | ME_MIGHT_MOVE_SOE)
|
|
317
|
|
318
|
|
319 #define EXTENT_LIVE_P(e) (!EQ (extent_object (e), Qt))
|
|
320
|
|
321 #define CHECK_LIVE_EXTENT(x) do { \
|
|
322 CHECK_EXTENT (x); \
|
|
323 if (!EXTENT_LIVE_P (XEXTENT (x))) \
|
|
324 dead_wrong_type_argument (Qextent_live_p, (x)); \
|
|
325 } while (0)
|
|
326 #define CONCHECK_LIVE_EXTENT(x) do { \
|
|
327 CONCHECK_EXTENT (x); \
|
|
328 if (!EXTENT_LIVE_P (XEXTENT (x))) \
|
|
329 x = wrong_type_argument (Qextent_live_p, (x)); \
|
|
330 } while (0)
|
|
331
|
|
332 EXFUN (Fdetach_extent, 1);
|
|
333 EXFUN (Fextent_end_position, 1);
|
|
334 EXFUN (Fextent_object, 1);
|
|
335 EXFUN (Fextent_start_position, 1);
|
|
336 EXFUN (Fmake_extent, 3);
|
|
337 EXFUN (Fprevious_single_property_change, 4);
|
|
338 EXFUN (Fset_extent_endpoints, 4);
|
460
|
339 EXFUN (Fnext_extent_change, 2);
|
|
340 EXFUN (Fprevious_extent_change, 2);
|
428
|
341 EXFUN (Fset_extent_parent, 2);
|
460
|
342 EXFUN (Fget_char_property, 4);
|
428
|
343
|
|
344 extern int inside_undo;
|
442
|
345 extern int in_modeline_generation;
|
428
|
346
|
|
347 struct extent_fragment *extent_fragment_new (Lisp_Object buffer_or_string,
|
|
348 struct frame *frm);
|
|
349 face_index extent_fragment_update (struct window *w,
|
|
350 struct extent_fragment *ef,
|
665
|
351 /* Note this is in Bytebposs */
|
|
352 Bytebpos pos);
|
428
|
353 void extent_fragment_delete (struct extent_fragment *ef);
|
|
354
|
|
355
|
|
356 #ifdef emacs /* things other than emacs want the structs */
|
|
357
|
|
358 /* from alloc.c */
|
|
359 struct extent *allocate_extent (void);
|
|
360
|
|
361 /* from extents.c */
|
|
362 EXTENT extent_ancestor_1 (EXTENT e);
|
|
363
|
|
364 /* extent_ancestor() chases all the parent links until there aren't any
|
|
365 more. extent_ancestor_1() does the same thing but it a function;
|
|
366 the following optimizes the most common case. */
|
442
|
367 INLINE_HEADER EXTENT extent_ancestor (EXTENT e);
|
|
368 INLINE_HEADER EXTENT
|
428
|
369 extent_ancestor (EXTENT e)
|
|
370 {
|
|
371 return e->flags.has_parent ? extent_ancestor_1 (e) : e;
|
|
372 }
|
|
373
|
|
374 void allocate_extent_auxiliary (EXTENT ext);
|
|
375 void init_buffer_extents (struct buffer *b);
|
|
376 void uninit_buffer_extents (struct buffer *b);
|
|
377 typedef int (*map_extents_fun) (EXTENT extent, void *arg);
|
665
|
378 void map_extents (Charbpos from, Charbpos to, map_extents_fun fn,
|
428
|
379 void *arg, Lisp_Object obj, EXTENT after,
|
|
380 unsigned int flags);
|
|
381
|
665
|
382 /* Note the following five functions are NOT in Charbpos's */
|
|
383 void adjust_extents (Lisp_Object object, Membpos from,
|
|
384 Membpos to, int amount);
|
|
385 void adjust_extents_for_deletion (Lisp_Object object, Bytebpos from,
|
|
386 Bytebpos to, int gapsize,
|
428
|
387 int numdel, int movegapsize);
|
665
|
388 void verify_extent_modification (Lisp_Object object, Bytebpos from,
|
|
389 Bytebpos to,
|
428
|
390 Lisp_Object inhibit_read_only_value);
|
|
391 void process_extents_for_insertion (Lisp_Object object,
|
665
|
392 Bytebpos opoint, Bytecount length);
|
|
393 void process_extents_for_deletion (Lisp_Object object, Bytebpos from,
|
|
394 Bytebpos to, int destroy_them);
|
|
395 void report_extent_modification (Lisp_Object, Charbpos, Charbpos, int);
|
428
|
396
|
|
397 void set_extent_glyph (EXTENT extent, Lisp_Object glyph, int endp,
|
|
398 glyph_layout layout);
|
|
399
|
|
400 void add_string_extents (Lisp_Object string, struct buffer *buf,
|
665
|
401 Bytebpos opoint, Bytecount length);
|
428
|
402 void splice_in_string_extents (Lisp_Object string, struct buffer *buf,
|
665
|
403 Bytebpos opoint, Bytecount length,
|
428
|
404 Bytecount pos);
|
|
405 void copy_string_extents (Lisp_Object new_string,
|
|
406 Lisp_Object old_string,
|
|
407 Bytecount new_pos, Bytecount old_pos,
|
|
408 Bytecount length);
|
|
409
|
|
410 void detach_all_extents (Lisp_Object object);
|
665
|
411 void set_extent_endpoints (EXTENT extent, Bytebpos s, Bytebpos e,
|
428
|
412 Lisp_Object object);
|
|
413
|
|
414 #ifdef ERROR_CHECK_EXTENTS
|
|
415 void sledgehammer_extent_check (Lisp_Object obj);
|
|
416 #endif
|
|
417
|
|
418 #ifdef MEMORY_USAGE_STATS
|
|
419 int compute_buffer_extent_usage (struct buffer *b,
|
|
420 struct overhead_stats *ovstats);
|
|
421 #endif
|
|
422
|
|
423 #endif /* emacs */
|
|
424
|
440
|
425 #endif /* INCLUDED_extents_h_ */
|