Mercurial > emacs
annotate src/intervals.c @ 5362:d1fa597d923d
(XTflush): FIx typo in last change.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 26 Dec 1993 09:06:44 +0000 |
parents | 63a865489a1e |
children | 95882472f2da |
rev | line source |
---|---|
1157 | 1 /* Code for doing intervals. |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
2 Copyright (C) 1993 Free Software Foundation, Inc. |
1157 | 3 |
4 This file is part of GNU Emacs. | |
5 | |
6 GNU Emacs is free software; you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
8 the Free Software Foundation; either version 2, or (at your option) |
1157 | 9 any later version. |
10 | |
11 GNU Emacs is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GNU Emacs; see the file COPYING. If not, write to | |
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
19 | |
20 | |
21 /* NOTES: | |
22 | |
23 Have to ensure that we can't put symbol nil on a plist, or some | |
24 functions may work incorrectly. | |
25 | |
26 An idea: Have the owner of the tree keep count of splits and/or | |
27 insertion lengths (in intervals), and balance after every N. | |
28 | |
29 Need to call *_left_hook when buffer is killed. | |
30 | |
31 Scan for zero-length, or 0-length to see notes about handling | |
32 zero length interval-markers. | |
33 | |
34 There are comments around about freeing intervals. It might be | |
35 faster to explicitly free them (put them on the free list) than | |
36 to GC them. | |
37 | |
38 */ | |
39 | |
40 | |
4696
1fc792473491
Include <config.h> instead of "config.h".
Roland McGrath <roland@gnu.org>
parents:
4638
diff
changeset
|
41 #include <config.h> |
1157 | 42 #include "lisp.h" |
43 #include "intervals.h" | |
44 #include "buffer.h" | |
4962 | 45 #include "puresize.h" |
1157 | 46 |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
47 /* The rest of the file is within this conditional. */ |
1301
5a27062b8b7f
* intervals.c: Conditionalize all functions on
Joseph Arceneaux <jla@gnu.org>
parents:
1288
diff
changeset
|
48 #ifdef USE_TEXT_PROPERTIES |
5a27062b8b7f
* intervals.c: Conditionalize all functions on
Joseph Arceneaux <jla@gnu.org>
parents:
1288
diff
changeset
|
49 |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
50 /* Factor for weight-balancing interval trees. */ |
1157 | 51 Lisp_Object interval_balance_threshold; |
5173
d48ba25b35bf
(merge_properties_sticky): Declared.
Richard M. Stallman <rms@gnu.org>
parents:
5169
diff
changeset
|
52 |
d48ba25b35bf
(merge_properties_sticky): Declared.
Richard M. Stallman <rms@gnu.org>
parents:
5169
diff
changeset
|
53 Lisp_Object merge_properties_sticky (); |
1157 | 54 |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
55 /* Utility functions for intervals. */ |
1157 | 56 |
57 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
58 /* Create the root interval of some object, a buffer or string. */ |
1157 | 59 |
60 INTERVAL | |
61 create_root_interval (parent) | |
62 Lisp_Object parent; | |
63 { | |
4962 | 64 INTERVAL new; |
65 | |
66 CHECK_IMPURE (parent); | |
67 | |
68 new = make_interval (); | |
1157 | 69 |
70 if (XTYPE (parent) == Lisp_Buffer) | |
71 { | |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
72 new->total_length = (BUF_Z (XBUFFER (parent)) |
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
73 - BUF_BEG (XBUFFER (parent))); |
1157 | 74 XBUFFER (parent)->intervals = new; |
75 } | |
76 else if (XTYPE (parent) == Lisp_String) | |
77 { | |
78 new->total_length = XSTRING (parent)->size; | |
79 XSTRING (parent)->intervals = new; | |
80 } | |
81 | |
82 new->parent = (INTERVAL) parent; | |
83 new->position = 1; | |
84 | |
85 return new; | |
86 } | |
87 | |
88 /* Make the interval TARGET have exactly the properties of SOURCE */ | |
89 | |
90 void | |
91 copy_properties (source, target) | |
92 register INTERVAL source, target; | |
93 { | |
94 if (DEFAULT_INTERVAL_P (source) && DEFAULT_INTERVAL_P (target)) | |
95 return; | |
96 | |
97 COPY_INTERVAL_CACHE (source, target); | |
98 target->plist = Fcopy_sequence (source->plist); | |
99 } | |
100 | |
101 /* Merge the properties of interval SOURCE into the properties | |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
102 of interval TARGET. That is to say, each property in SOURCE |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
103 is added to TARGET if TARGET has no such property as yet. */ |
1157 | 104 |
105 static void | |
106 merge_properties (source, target) | |
107 register INTERVAL source, target; | |
108 { | |
109 register Lisp_Object o, sym, val; | |
110 | |
111 if (DEFAULT_INTERVAL_P (source) && DEFAULT_INTERVAL_P (target)) | |
112 return; | |
113 | |
114 MERGE_INTERVAL_CACHE (source, target); | |
115 | |
116 o = source->plist; | |
117 while (! EQ (o, Qnil)) | |
118 { | |
119 sym = Fcar (o); | |
120 val = Fmemq (sym, target->plist); | |
121 | |
122 if (NILP (val)) | |
123 { | |
124 o = Fcdr (o); | |
125 val = Fcar (o); | |
126 target->plist = Fcons (sym, Fcons (val, target->plist)); | |
127 o = Fcdr (o); | |
128 } | |
129 else | |
130 o = Fcdr (Fcdr (o)); | |
131 } | |
132 } | |
133 | |
134 /* Return 1 if the two intervals have the same properties, | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
135 0 otherwise. */ |
1157 | 136 |
137 int | |
138 intervals_equal (i0, i1) | |
139 INTERVAL i0, i1; | |
140 { | |
141 register Lisp_Object i0_cdr, i0_sym, i1_val; | |
142 register i1_len; | |
143 | |
144 if (DEFAULT_INTERVAL_P (i0) && DEFAULT_INTERVAL_P (i1)) | |
145 return 1; | |
146 | |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
147 if (DEFAULT_INTERVAL_P (i0) || DEFAULT_INTERVAL_P (i1)) |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
148 return 0; |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
149 |
1157 | 150 i1_len = XFASTINT (Flength (i1->plist)); |
151 if (i1_len & 0x1) /* Paranoia -- plists are always even */ | |
152 abort (); | |
153 i1_len /= 2; | |
154 i0_cdr = i0->plist; | |
155 while (!NILP (i0_cdr)) | |
156 { | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
157 /* Lengths of the two plists were unequal. */ |
1157 | 158 if (i1_len == 0) |
159 return 0; | |
160 | |
161 i0_sym = Fcar (i0_cdr); | |
162 i1_val = Fmemq (i0_sym, i1->plist); | |
163 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
164 /* i0 has something i1 doesn't. */ |
1157 | 165 if (EQ (i1_val, Qnil)) |
166 return 0; | |
167 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
168 /* i0 and i1 both have sym, but it has different values in each. */ |
1157 | 169 i0_cdr = Fcdr (i0_cdr); |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
170 if (! EQ (Fcar (Fcdr (i1_val)), Fcar (i0_cdr))) |
1157 | 171 return 0; |
172 | |
173 i0_cdr = Fcdr (i0_cdr); | |
174 i1_len--; | |
175 } | |
176 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
177 /* Lengths of the two plists were unequal. */ |
1157 | 178 if (i1_len > 0) |
179 return 0; | |
180 | |
181 return 1; | |
182 } | |
183 | |
184 static int icount; | |
185 static int idepth; | |
186 static int zero_length; | |
187 | |
188 /* Traverse an interval tree TREE, performing FUNCTION on each node. | |
1958
8bc716df45e3
(traverse_intervals): New arg ARG.
Richard M. Stallman <rms@gnu.org>
parents:
1412
diff
changeset
|
189 Pass FUNCTION two args: an interval, and ARG. */ |
1157 | 190 |
191 void | |
1958
8bc716df45e3
(traverse_intervals): New arg ARG.
Richard M. Stallman <rms@gnu.org>
parents:
1412
diff
changeset
|
192 traverse_intervals (tree, position, depth, function, arg) |
1157 | 193 INTERVAL tree; |
1412
6097878fbd46
* intervals.c (traverse_intervals): New parameter `depth'.
Joseph Arceneaux <jla@gnu.org>
parents:
1316
diff
changeset
|
194 int position, depth; |
1157 | 195 void (* function) (); |
1958
8bc716df45e3
(traverse_intervals): New arg ARG.
Richard M. Stallman <rms@gnu.org>
parents:
1412
diff
changeset
|
196 Lisp_Object arg; |
1157 | 197 { |
198 if (NULL_INTERVAL_P (tree)) | |
199 return; | |
200 | |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
201 traverse_intervals (tree->left, position, depth + 1, function, arg); |
1157 | 202 position += LEFT_TOTAL_LENGTH (tree); |
203 tree->position = position; | |
1958
8bc716df45e3
(traverse_intervals): New arg ARG.
Richard M. Stallman <rms@gnu.org>
parents:
1412
diff
changeset
|
204 (*function) (tree, arg); |
1157 | 205 position += LENGTH (tree); |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
206 traverse_intervals (tree->right, position, depth + 1, function, arg); |
1157 | 207 } |
208 | |
209 #if 0 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
210 /* These functions are temporary, for debugging purposes only. */ |
1157 | 211 |
212 INTERVAL search_interval, found_interval; | |
213 | |
214 void | |
215 check_for_interval (i) | |
216 register INTERVAL i; | |
217 { | |
218 if (i == search_interval) | |
219 { | |
220 found_interval = i; | |
221 icount++; | |
222 } | |
223 } | |
224 | |
225 INTERVAL | |
226 search_for_interval (i, tree) | |
227 register INTERVAL i, tree; | |
228 { | |
229 icount = 0; | |
230 search_interval = i; | |
231 found_interval = NULL_INTERVAL; | |
1958
8bc716df45e3
(traverse_intervals): New arg ARG.
Richard M. Stallman <rms@gnu.org>
parents:
1412
diff
changeset
|
232 traverse_intervals (tree, 1, 0, &check_for_interval, Qnil); |
1157 | 233 return found_interval; |
234 } | |
235 | |
236 static void | |
237 inc_interval_count (i) | |
238 INTERVAL i; | |
239 { | |
240 icount++; | |
241 if (LENGTH (i) == 0) | |
242 zero_length++; | |
243 if (depth > idepth) | |
244 idepth = depth; | |
245 } | |
246 | |
247 int | |
248 count_intervals (i) | |
249 register INTERVAL i; | |
250 { | |
251 icount = 0; | |
252 idepth = 0; | |
253 zero_length = 0; | |
1958
8bc716df45e3
(traverse_intervals): New arg ARG.
Richard M. Stallman <rms@gnu.org>
parents:
1412
diff
changeset
|
254 traverse_intervals (i, 1, 0, &inc_interval_count, Qnil); |
1157 | 255 |
256 return icount; | |
257 } | |
258 | |
259 static INTERVAL | |
260 root_interval (interval) | |
261 INTERVAL interval; | |
262 { | |
263 register INTERVAL i = interval; | |
264 | |
265 while (! ROOT_INTERVAL_P (i)) | |
266 i = i->parent; | |
267 | |
268 return i; | |
269 } | |
270 #endif | |
271 | |
272 /* Assuming that a left child exists, perform the following operation: | |
273 | |
274 A B | |
275 / \ / \ | |
276 B => A | |
277 / \ / \ | |
278 c c | |
279 */ | |
280 | |
281 static INTERVAL | |
282 rotate_right (interval) | |
283 INTERVAL interval; | |
284 { | |
285 INTERVAL i; | |
286 INTERVAL B = interval->left; | |
287 int len = LENGTH (interval); | |
288 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
289 /* Deal with any Parent of A; make it point to B. */ |
1157 | 290 if (! ROOT_INTERVAL_P (interval)) |
291 if (AM_LEFT_CHILD (interval)) | |
292 interval->parent->left = interval->left; | |
293 else | |
294 interval->parent->right = interval->left; | |
295 interval->left->parent = interval->parent; | |
296 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
297 /* B gets the same length as A, since it get A's position in the tree. */ |
1157 | 298 interval->left->total_length = interval->total_length; |
299 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
300 /* B becomes the parent of A. */ |
1157 | 301 i = interval->left->right; |
302 interval->left->right = interval; | |
303 interval->parent = interval->left; | |
304 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
305 /* A gets c as left child. */ |
1157 | 306 interval->left = i; |
307 if (! NULL_INTERVAL_P (i)) | |
308 i->parent = interval; | |
309 interval->total_length = (len + LEFT_TOTAL_LENGTH (interval) | |
310 + RIGHT_TOTAL_LENGTH (interval)); | |
311 | |
312 return B; | |
313 } | |
314 | |
315 /* Assuming that a right child exists, perform the following operation: | |
316 | |
317 A B | |
318 / \ / \ | |
319 B => A | |
320 / \ / \ | |
321 c c | |
322 */ | |
323 | |
324 static INTERVAL | |
325 rotate_left (interval) | |
326 INTERVAL interval; | |
327 { | |
328 INTERVAL i; | |
329 INTERVAL B = interval->right; | |
330 int len = LENGTH (interval); | |
331 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
332 /* Deal with the parent of A. */ |
1157 | 333 if (! ROOT_INTERVAL_P (interval)) |
334 if (AM_LEFT_CHILD (interval)) | |
335 interval->parent->left = interval->right; | |
336 else | |
337 interval->parent->right = interval->right; | |
338 interval->right->parent = interval->parent; | |
339 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
340 /* B must have the same total length of A. */ |
1157 | 341 interval->right->total_length = interval->total_length; |
342 | |
343 /* Make B the parent of A */ | |
344 i = interval->right->left; | |
345 interval->right->left = interval; | |
346 interval->parent = interval->right; | |
347 | |
348 /* Make A point to c */ | |
349 interval->right = i; | |
350 if (! NULL_INTERVAL_P (i)) | |
351 i->parent = interval; | |
352 interval->total_length = (len + LEFT_TOTAL_LENGTH (interval) | |
353 + RIGHT_TOTAL_LENGTH (interval)); | |
354 | |
355 return B; | |
356 } | |
357 | |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
358 /* Split INTERVAL into two pieces, starting the second piece at |
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
359 character position OFFSET (counting from 0), relative to INTERVAL. |
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
360 INTERVAL becomes the left-hand piece, and the right-hand piece |
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
361 (second, lexicographically) is returned. |
1164 | 362 |
363 The size and position fields of the two intervals are set based upon | |
364 those of the original interval. The property list of the new interval | |
365 is reset, thus it is up to the caller to do the right thing with the | |
366 result. | |
1157 | 367 |
368 Note that this does not change the position of INTERVAL; if it is a root, | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
369 it is still a root after this operation. */ |
1157 | 370 |
371 INTERVAL | |
1164 | 372 split_interval_right (interval, offset) |
1157 | 373 INTERVAL interval; |
1164 | 374 int offset; |
1157 | 375 { |
376 INTERVAL new = make_interval (); | |
377 int position = interval->position; | |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
378 int new_length = LENGTH (interval) - offset; |
1157 | 379 |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
380 new->position = position + offset; |
1157 | 381 new->parent = interval; |
382 | |
383 if (LEAF_INTERVAL_P (interval) || NULL_RIGHT_CHILD (interval)) | |
384 { | |
385 interval->right = new; | |
386 new->total_length = new_length; | |
387 | |
388 return new; | |
389 } | |
390 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
391 /* Insert the new node between INTERVAL and its right child. */ |
1157 | 392 new->right = interval->right; |
393 interval->right->parent = new; | |
394 interval->right = new; | |
395 | |
396 new->total_length = new_length + new->right->total_length; | |
397 | |
398 return new; | |
399 } | |
400 | |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
401 /* Split INTERVAL into two pieces, starting the second piece at |
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
402 character position OFFSET (counting from 0), relative to INTERVAL. |
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
403 INTERVAL becomes the right-hand piece, and the left-hand piece |
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
404 (first, lexicographically) is returned. |
1157 | 405 |
1164 | 406 The size and position fields of the two intervals are set based upon |
407 those of the original interval. The property list of the new interval | |
408 is reset, thus it is up to the caller to do the right thing with the | |
409 result. | |
410 | |
411 Note that this does not change the position of INTERVAL; if it is a root, | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
412 it is still a root after this operation. */ |
1157 | 413 |
414 INTERVAL | |
1164 | 415 split_interval_left (interval, offset) |
1157 | 416 INTERVAL interval; |
1164 | 417 int offset; |
1157 | 418 { |
419 INTERVAL new = make_interval (); | |
420 int position = interval->position; | |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
421 int new_length = offset; |
1157 | 422 |
423 new->position = interval->position; | |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
424 interval->position = interval->position + offset; |
1157 | 425 new->parent = interval; |
426 | |
427 if (NULL_LEFT_CHILD (interval)) | |
428 { | |
429 interval->left = new; | |
430 new->total_length = new_length; | |
431 | |
432 return new; | |
433 } | |
434 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
435 /* Insert the new node between INTERVAL and its left child. */ |
1157 | 436 new->left = interval->left; |
437 new->left->parent = new; | |
438 interval->left = new; | |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
439 new->total_length = new_length + LEFT_TOTAL_LENGTH (new); |
1157 | 440 |
441 return new; | |
442 } | |
443 | |
1164 | 444 /* Find the interval containing text position POSITION in the text |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
445 represented by the interval tree TREE. POSITION is a buffer |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
446 position; the earliest position is 1. If POSITION is at the end of |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
447 the buffer, return the interval containing the last character. |
1157 | 448 |
1164 | 449 The `position' field, which is a cache of an interval's position, |
450 is updated in the interval found. Other functions (e.g., next_interval) | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
451 will update this cache based on the result of find_interval. */ |
1164 | 452 |
453 INLINE INTERVAL | |
1157 | 454 find_interval (tree, position) |
455 register INTERVAL tree; | |
456 register int position; | |
457 { | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
458 /* The distance from the left edge of the subtree at TREE |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
459 to POSITION. */ |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
460 register int relative_position = position - BEG; |
1157 | 461 |
462 if (NULL_INTERVAL_P (tree)) | |
463 return NULL_INTERVAL; | |
464 | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
465 if (relative_position > TOTAL_LENGTH (tree)) |
1157 | 466 abort (); /* Paranoia */ |
467 | |
468 while (1) | |
469 { | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
470 if (relative_position < LEFT_TOTAL_LENGTH (tree)) |
1157 | 471 { |
472 tree = tree->left; | |
473 } | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
474 else if (! NULL_RIGHT_CHILD (tree) |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
475 && relative_position >= (TOTAL_LENGTH (tree) |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
476 - RIGHT_TOTAL_LENGTH (tree))) |
1157 | 477 { |
478 relative_position -= (TOTAL_LENGTH (tree) | |
479 - RIGHT_TOTAL_LENGTH (tree)); | |
480 tree = tree->right; | |
481 } | |
482 else | |
483 { | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
484 tree->position = |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
485 (position - relative_position /* the left edge of *tree */ |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
486 + LEFT_TOTAL_LENGTH (tree)); /* the left edge of this interval */ |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
487 |
1157 | 488 return tree; |
489 } | |
490 } | |
491 } | |
492 | |
493 /* Find the succeeding interval (lexicographically) to INTERVAL. | |
1164 | 494 Sets the `position' field based on that of INTERVAL (see |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
495 find_interval). */ |
1157 | 496 |
497 INTERVAL | |
498 next_interval (interval) | |
499 register INTERVAL interval; | |
500 { | |
501 register INTERVAL i = interval; | |
502 register int next_position; | |
503 | |
504 if (NULL_INTERVAL_P (i)) | |
505 return NULL_INTERVAL; | |
506 next_position = interval->position + LENGTH (interval); | |
507 | |
508 if (! NULL_RIGHT_CHILD (i)) | |
509 { | |
510 i = i->right; | |
511 while (! NULL_LEFT_CHILD (i)) | |
512 i = i->left; | |
513 | |
514 i->position = next_position; | |
515 return i; | |
516 } | |
517 | |
518 while (! NULL_PARENT (i)) | |
519 { | |
520 if (AM_LEFT_CHILD (i)) | |
521 { | |
522 i = i->parent; | |
523 i->position = next_position; | |
524 return i; | |
525 } | |
526 | |
527 i = i->parent; | |
528 } | |
529 | |
530 return NULL_INTERVAL; | |
531 } | |
532 | |
533 /* Find the preceding interval (lexicographically) to INTERVAL. | |
1164 | 534 Sets the `position' field based on that of INTERVAL (see |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
535 find_interval). */ |
1157 | 536 |
537 INTERVAL | |
538 previous_interval (interval) | |
539 register INTERVAL interval; | |
540 { | |
541 register INTERVAL i; | |
542 register position_of_previous; | |
543 | |
544 if (NULL_INTERVAL_P (interval)) | |
545 return NULL_INTERVAL; | |
546 | |
547 if (! NULL_LEFT_CHILD (interval)) | |
548 { | |
549 i = interval->left; | |
550 while (! NULL_RIGHT_CHILD (i)) | |
551 i = i->right; | |
552 | |
553 i->position = interval->position - LENGTH (i); | |
554 return i; | |
555 } | |
556 | |
557 i = interval; | |
558 while (! NULL_PARENT (i)) | |
559 { | |
560 if (AM_RIGHT_CHILD (i)) | |
561 { | |
562 i = i->parent; | |
563 | |
564 i->position = interval->position - LENGTH (i); | |
565 return i; | |
566 } | |
567 i = i->parent; | |
568 } | |
569 | |
570 return NULL_INTERVAL; | |
571 } | |
572 | |
1164 | 573 #if 0 |
1157 | 574 /* Traverse a path down the interval tree TREE to the interval |
575 containing POSITION, adjusting all nodes on the path for | |
576 an addition of LENGTH characters. Insertion between two intervals | |
577 (i.e., point == i->position, where i is second interval) means | |
578 text goes into second interval. | |
579 | |
580 Modifications are needed to handle the hungry bits -- after simply | |
581 finding the interval at position (don't add length going down), | |
582 if it's the beginning of the interval, get the previous interval | |
583 and check the hugry bits of both. Then add the length going back up | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
584 to the root. */ |
1157 | 585 |
586 static INTERVAL | |
587 adjust_intervals_for_insertion (tree, position, length) | |
588 INTERVAL tree; | |
589 int position, length; | |
590 { | |
591 register int relative_position; | |
592 register INTERVAL this; | |
593 | |
594 if (TOTAL_LENGTH (tree) == 0) /* Paranoia */ | |
595 abort (); | |
596 | |
597 /* If inserting at point-max of a buffer, that position | |
598 will be out of range */ | |
599 if (position > TOTAL_LENGTH (tree)) | |
600 position = TOTAL_LENGTH (tree); | |
601 relative_position = position; | |
602 this = tree; | |
603 | |
604 while (1) | |
605 { | |
606 if (relative_position <= LEFT_TOTAL_LENGTH (this)) | |
607 { | |
608 this->total_length += length; | |
609 this = this->left; | |
610 } | |
611 else if (relative_position > (TOTAL_LENGTH (this) | |
612 - RIGHT_TOTAL_LENGTH (this))) | |
613 { | |
614 relative_position -= (TOTAL_LENGTH (this) | |
615 - RIGHT_TOTAL_LENGTH (this)); | |
616 this->total_length += length; | |
617 this = this->right; | |
618 } | |
619 else | |
620 { | |
621 /* If we are to use zero-length intervals as buffer pointers, | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
622 then this code will have to change. */ |
1157 | 623 this->total_length += length; |
624 this->position = LEFT_TOTAL_LENGTH (this) | |
625 + position - relative_position + 1; | |
626 return tree; | |
627 } | |
628 } | |
629 } | |
1164 | 630 #endif |
631 | |
632 /* Effect an adjustment corresponding to the addition of LENGTH characters | |
633 of text. Do this by finding the interval containing POSITION in the | |
634 interval tree TREE, and then adjusting all of it's ancestors by adding | |
635 LENGTH to them. | |
636 | |
637 If POSITION is the first character of an interval, meaning that point | |
638 is actually between the two intervals, make the new text belong to | |
639 the interval which is "sticky". | |
640 | |
1189 | 641 If both intervals are "sticky", then make them belong to the left-most |
1164 | 642 interval. Another possibility would be to create a new interval for |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
643 this text, and make it have the merged properties of both ends. */ |
1164 | 644 |
645 static INTERVAL | |
646 adjust_intervals_for_insertion (tree, position, length) | |
647 INTERVAL tree; | |
648 int position, length; | |
649 { | |
650 register INTERVAL i; | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
651 register INTERVAL temp; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
652 int eobp = 0; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
653 |
1164 | 654 if (TOTAL_LENGTH (tree) == 0) /* Paranoia */ |
655 abort (); | |
656 | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
657 /* If inserting at point-max of a buffer, that position will be out |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
658 of range. Remember that buffer positions are 1-based. */ |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
659 if (position >= BEG + TOTAL_LENGTH (tree)){ |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
660 position = BEG + TOTAL_LENGTH (tree); |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
661 eobp = 1; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
662 } |
1164 | 663 |
664 i = find_interval (tree, position); | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
665 |
4638
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
666 /* If in middle of an interval which is not sticky either way, |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
667 we must not just give its properties to the insertion. |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
668 So split this interval at the insertion point. */ |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
669 if (! (position == i->position || eobp) |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
670 && END_NONSTICKY_P (i) |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
671 && ! FRONT_STICKY_P (i)) |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
672 { |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
673 temp = split_interval_right (i, position - i->position); |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
674 copy_properties (i, temp); |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
675 i = temp; |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
676 } |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
677 |
1164 | 678 /* If we are positioned between intervals, check the stickiness of |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
679 both of them. We have to do this too, if we are at BEG or Z. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
680 if (position == i->position || eobp) |
1164 | 681 { |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
682 register INTERVAL prev; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
683 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
684 if (position == BEG) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
685 prev = 0; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
686 else if (eobp) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
687 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
688 prev = i; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
689 i = 0; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
690 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
691 else |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
692 prev = previous_interval (i); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
693 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
694 /* Even if we are positioned between intervals, we default |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
695 to the left one if it exists. We extend it now and split |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
696 off a part later, if stickyness demands it. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
697 for (temp = prev ? prev : i; ! NULL_INTERVAL_P (temp); temp = temp->parent) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
698 temp->total_length += length; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
699 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
700 /* If at least one interval has sticky properties, |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
701 we check the stickyness property by property. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
702 if (END_NONSTICKY_P (prev) || FRONT_STICKY_P (i)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
703 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
704 Lisp_Object pleft = NULL_INTERVAL_P (prev) ? Qnil : prev->plist; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
705 Lisp_Object pright = NULL_INTERVAL_P (i) ? Qnil : i->plist; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
706 struct interval newi; |
1164 | 707 |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
708 newi.plist = merge_properties_sticky (pleft, pright); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
709 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
710 if(! prev) /* i.e. position == BEG */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
711 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
712 if (! intervals_equal (i, &newi)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
713 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
714 i = split_interval_left (i, length); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
715 i->plist = newi.plist; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
716 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
717 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
718 else if (! intervals_equal (prev, &newi)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
719 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
720 prev = split_interval_right (prev, |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
721 position - prev->position); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
722 prev->plist = newi.plist; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
723 if (! NULL_INTERVAL_P (i) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
724 && intervals_equal (prev, i)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
725 merge_interval_right (prev); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
726 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
727 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
728 /* We will need to update the cache here later. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
729 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
730 else if (! prev && ! NILP (i->plist)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
731 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
732 /* Just split off a new interval at the left. |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
733 Since I wasn't front-sticky, the empty plist is ok. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
734 i = split_interval_left (i, length); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
735 } |
1164 | 736 } |
737 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
738 /* Otherwise just extend the interval. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
739 else |
1164 | 740 { |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
741 for (temp = i; ! NULL_INTERVAL_P (temp); temp = temp->parent) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
742 temp->total_length += length; |
1164 | 743 } |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
744 |
1164 | 745 return tree; |
746 } | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
747 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
748 Lisp_Object |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
749 merge_properties_sticky (pleft, pright) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
750 Lisp_Object pleft, pright; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
751 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
752 register Lisp_Object props = Qnil, front = Qnil, rear = Qnil; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
753 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
754 Lisp_Object lfront = textget (pleft, Qfront_sticky); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
755 Lisp_Object lrear = textget (pleft, Qrear_nonsticky); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
756 Lisp_Object rfront = textget (pright, Qfront_sticky); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
757 Lisp_Object rrear = textget (pright, Qrear_nonsticky); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
758 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
759 register Lisp_Object tail1, tail2, sym; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
760 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
761 /* Go through each element of PLEFT. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
762 for (tail1 = pleft; ! NILP (tail1); tail1 = Fcdr (Fcdr (tail1))) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
763 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
764 sym = Fcar (tail1); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
765 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
766 /* Sticky properties get special treatment. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
767 if (EQ (sym, Qrear_nonsticky) || EQ (sym, Qfront_sticky)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
768 continue; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
769 |
4638
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
770 if (CONSP (lrear) ? NILP (Fmemq (sym, lrear)) : NILP (lrear)) |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
771 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
772 /* rear-sticky is dominant, we needn't search in PRIGHT. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
773 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
774 props = Fcons (sym, Fcons (Fcar (Fcdr (tail1)), props)); |
4638
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
775 if ((CONSP (lfront) || NILP (lfront)) |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
776 && ! NILP (Fmemq (sym, lfront))) |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
777 front = Fcons (sym, front); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
778 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
779 else |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
780 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
781 /* Go through PRIGHT, looking for sym. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
782 for (tail2 = pright; ! NILP (tail2); tail2 = Fcdr (Fcdr (tail2))) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
783 if (EQ (sym, Fcar (tail2))) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
784 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
785 |
4638
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
786 if (CONSP (rfront) |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
787 ? ! NILP (Fmemq (sym, rfront)) : ! NILP (rfront)) |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
788 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
789 /* Nonsticky at the left and sticky at the right, |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
790 so take the right one. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
791 props = Fcons (sym, Fcons (Fcar (Fcdr (tail2)), props)); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
792 front = Fcons (sym, front); |
4638
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
793 if ((CONSP (rrear) || NILP (rrear)) |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
794 && ! NILP (Fmemq (sym, rrear))) |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
795 rear = Fcons (sym, rear); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
796 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
797 break; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
798 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
799 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
800 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
801 /* Now let's see what to keep from PRIGHT. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
802 for (tail2 = pright; ! NILP (tail2); tail2 = Fcdr (Fcdr (tail2))) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
803 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
804 sym = Fcar (tail2); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
805 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
806 /* Sticky properties get special treatment. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
807 if (EQ (sym, Qrear_nonsticky) || EQ (sym, Qfront_sticky)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
808 continue; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
809 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
810 /* If it ain't sticky, we don't take it. */ |
4638
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
811 if (CONSP (rfront) |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
812 ? NILP (Fmemq (sym, rfront)) : NILP (rfront)) |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
813 continue; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
814 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
815 /* If sym is in PLEFT we already got it. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
816 for (tail1 = pleft; ! NILP (tail1); tail1 = Fcdr (Fcdr (tail1))) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
817 if (EQ (sym, Fcar (tail1))) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
818 break; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
819 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
820 if (NILP (tail1)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
821 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
822 props = Fcons (sym, Fcons (Fcar (Fcdr (tail2)), props)); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
823 front = Fcons (sym, front); |
4638
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
824 if ((CONSP (rrear) || NILP (rrear)) |
3872f91770fc
(adjust_intervals_for_insertion): If inserting in middle
Richard M. Stallman <rms@gnu.org>
parents:
4383
diff
changeset
|
825 && ! NILP (Fmemq (sym, rrear))) |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
826 rear = Fcons (sym, rear); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
827 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
828 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
829 if (! NILP (front)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
830 props = Fcons (Qfront_sticky, Fcons (front, props)); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
831 if (! NILP (rear)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
832 props = Fcons (Qrear_nonsticky, Fcons (rear, props)); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
833 return props; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
834 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
835 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
836 |
1157 | 837 |
1164 | 838 /* Delete an node I from its interval tree by merging its subtrees |
839 into one subtree which is then returned. Caller is responsible for | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
840 storing the resulting subtree into its parent. */ |
1157 | 841 |
842 static INTERVAL | |
843 delete_node (i) | |
844 register INTERVAL i; | |
845 { | |
846 register INTERVAL migrate, this; | |
847 register int migrate_amt; | |
848 | |
849 if (NULL_INTERVAL_P (i->left)) | |
850 return i->right; | |
851 if (NULL_INTERVAL_P (i->right)) | |
852 return i->left; | |
853 | |
854 migrate = i->left; | |
855 migrate_amt = i->left->total_length; | |
856 this = i->right; | |
857 this->total_length += migrate_amt; | |
858 while (! NULL_INTERVAL_P (this->left)) | |
859 { | |
860 this = this->left; | |
861 this->total_length += migrate_amt; | |
862 } | |
863 this->left = migrate; | |
864 migrate->parent = this; | |
865 | |
866 return i->right; | |
867 } | |
868 | |
869 /* Delete interval I from its tree by calling `delete_node' | |
870 and properly connecting the resultant subtree. | |
871 | |
872 I is presumed to be empty; that is, no adjustments are made | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
873 for the length of I. */ |
1157 | 874 |
875 void | |
876 delete_interval (i) | |
877 register INTERVAL i; | |
878 { | |
879 register INTERVAL parent; | |
880 int amt = LENGTH (i); | |
881 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
882 if (amt > 0) /* Only used on zero-length intervals now. */ |
1157 | 883 abort (); |
884 | |
885 if (ROOT_INTERVAL_P (i)) | |
886 { | |
887 Lisp_Object owner = (Lisp_Object) i->parent; | |
888 parent = delete_node (i); | |
889 if (! NULL_INTERVAL_P (parent)) | |
890 parent->parent = (INTERVAL) owner; | |
891 | |
892 if (XTYPE (owner) == Lisp_Buffer) | |
893 XBUFFER (owner)->intervals = parent; | |
894 else if (XTYPE (owner) == Lisp_String) | |
895 XSTRING (owner)->intervals = parent; | |
896 else | |
897 abort (); | |
898 | |
899 return; | |
900 } | |
901 | |
902 parent = i->parent; | |
903 if (AM_LEFT_CHILD (i)) | |
904 { | |
905 parent->left = delete_node (i); | |
906 if (! NULL_INTERVAL_P (parent->left)) | |
907 parent->left->parent = parent; | |
908 } | |
909 else | |
910 { | |
911 parent->right = delete_node (i); | |
912 if (! NULL_INTERVAL_P (parent->right)) | |
913 parent->right->parent = parent; | |
914 } | |
915 } | |
916 | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
917 /* Find the interval in TREE corresponding to the relative position |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
918 FROM and delete as much as possible of AMOUNT from that interval. |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
919 Return the amount actually deleted, and if the interval was |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
920 zeroed-out, delete that interval node from the tree. |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
921 |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
922 Note that FROM is actually origin zero, aka relative to the |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
923 leftmost edge of tree. This is appropriate since we call ourselves |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
924 recursively on subtrees. |
1157 | 925 |
1189 | 926 Do this by recursing down TREE to the interval in question, and |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
927 deleting the appropriate amount of text. */ |
1157 | 928 |
929 static int | |
930 interval_deletion_adjustment (tree, from, amount) | |
931 register INTERVAL tree; | |
932 register int from, amount; | |
933 { | |
934 register int relative_position = from; | |
935 | |
936 if (NULL_INTERVAL_P (tree)) | |
937 return 0; | |
938 | |
939 /* Left branch */ | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
940 if (relative_position < LEFT_TOTAL_LENGTH (tree)) |
1157 | 941 { |
942 int subtract = interval_deletion_adjustment (tree->left, | |
943 relative_position, | |
944 amount); | |
945 tree->total_length -= subtract; | |
946 return subtract; | |
947 } | |
948 /* Right branch */ | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
949 else if (relative_position >= (TOTAL_LENGTH (tree) |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
950 - RIGHT_TOTAL_LENGTH (tree))) |
1157 | 951 { |
952 int subtract; | |
953 | |
954 relative_position -= (tree->total_length | |
955 - RIGHT_TOTAL_LENGTH (tree)); | |
956 subtract = interval_deletion_adjustment (tree->right, | |
957 relative_position, | |
958 amount); | |
959 tree->total_length -= subtract; | |
960 return subtract; | |
961 } | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
962 /* Here -- this node. */ |
1157 | 963 else |
964 { | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
965 /* How much can we delete from this interval? */ |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
966 int my_amount = ((tree->total_length |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
967 - RIGHT_TOTAL_LENGTH (tree)) |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
968 - relative_position); |
1157 | 969 |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
970 if (amount > my_amount) |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
971 amount = my_amount; |
1157 | 972 |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
973 tree->total_length -= amount; |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
974 if (LENGTH (tree) == 0) |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
975 delete_interval (tree); |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
976 |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
977 return amount; |
1157 | 978 } |
979 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
980 /* Never reach here. */ |
1157 | 981 } |
982 | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
983 /* Effect the adjustments necessary to the interval tree of BUFFER to |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
984 correspond to the deletion of LENGTH characters from that buffer |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
985 text. The deletion is effected at position START (which is a |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
986 buffer position, i.e. origin 1). */ |
1189 | 987 |
1157 | 988 static void |
989 adjust_intervals_for_deletion (buffer, start, length) | |
990 struct buffer *buffer; | |
991 int start, length; | |
992 { | |
993 register int left_to_delete = length; | |
994 register INTERVAL tree = buffer->intervals; | |
995 register int deleted; | |
996 | |
997 if (NULL_INTERVAL_P (tree)) | |
998 return; | |
999 | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
1000 if (start > BEG + TOTAL_LENGTH (tree) |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
1001 || start + length > BEG + TOTAL_LENGTH (tree)) |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
1002 abort (); |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
1003 |
1157 | 1004 if (length == TOTAL_LENGTH (tree)) |
1005 { | |
1006 buffer->intervals = NULL_INTERVAL; | |
1007 return; | |
1008 } | |
1009 | |
1010 if (ONLY_INTERVAL_P (tree)) | |
1011 { | |
1012 tree->total_length -= length; | |
1013 return; | |
1014 } | |
1015 | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
1016 if (start > BEG + TOTAL_LENGTH (tree)) |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
1017 start = BEG + TOTAL_LENGTH (tree); |
1157 | 1018 while (left_to_delete > 0) |
1019 { | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
1020 left_to_delete -= interval_deletion_adjustment (tree, start - 1, |
1157 | 1021 left_to_delete); |
1022 tree = buffer->intervals; | |
1023 if (left_to_delete == tree->total_length) | |
1024 { | |
1025 buffer->intervals = NULL_INTERVAL; | |
1026 return; | |
1027 } | |
1028 } | |
1029 } | |
1030 | |
3591
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
3490
diff
changeset
|
1031 /* Make the adjustments necessary to the interval tree of BUFFER to |
1189 | 1032 represent an addition or deletion of LENGTH characters starting |
1033 at position START. Addition or deletion is indicated by the sign | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1034 of LENGTH. */ |
1157 | 1035 |
1036 INLINE void | |
1037 offset_intervals (buffer, start, length) | |
1038 struct buffer *buffer; | |
1039 int start, length; | |
1040 { | |
1041 if (NULL_INTERVAL_P (buffer->intervals) || length == 0) | |
1042 return; | |
1043 | |
1044 if (length > 0) | |
1045 adjust_intervals_for_insertion (buffer->intervals, start, length); | |
1046 else | |
1047 adjust_intervals_for_deletion (buffer, start, -length); | |
1048 } | |
1211 | 1049 |
1050 /* Merge interval I with its lexicographic successor. The resulting | |
1051 interval is returned, and has the properties of the original | |
1052 successor. The properties of I are lost. I is removed from the | |
1053 interval tree. | |
1157 | 1054 |
1211 | 1055 IMPORTANT: |
1056 The caller must verify that this is not the last (rightmost) | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1057 interval. */ |
1211 | 1058 |
1059 INTERVAL | |
1060 merge_interval_right (i) | |
1061 register INTERVAL i; | |
1062 { | |
1063 register int absorb = LENGTH (i); | |
1064 register INTERVAL successor; | |
1065 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1066 /* Zero out this interval. */ |
1211 | 1067 i->total_length -= absorb; |
1068 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1069 /* Find the succeeding interval. */ |
1211 | 1070 if (! NULL_RIGHT_CHILD (i)) /* It's below us. Add absorb |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1071 as we descend. */ |
1211 | 1072 { |
1073 successor = i->right; | |
1074 while (! NULL_LEFT_CHILD (successor)) | |
1075 { | |
1076 successor->total_length += absorb; | |
1077 successor = successor->left; | |
1078 } | |
1079 | |
1080 successor->total_length += absorb; | |
1081 delete_interval (i); | |
1082 return successor; | |
1083 } | |
1084 | |
1085 successor = i; | |
1086 while (! NULL_PARENT (successor)) /* It's above us. Subtract as | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1087 we ascend. */ |
1211 | 1088 { |
1089 if (AM_LEFT_CHILD (successor)) | |
1090 { | |
1091 successor = successor->parent; | |
1092 delete_interval (i); | |
1093 return successor; | |
1094 } | |
1095 | |
1096 successor = successor->parent; | |
1097 successor->total_length -= absorb; | |
1098 } | |
1099 | |
1100 /* This must be the rightmost or last interval and cannot | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1101 be merged right. The caller should have known. */ |
1211 | 1102 abort (); |
1103 } | |
1104 | |
1105 /* Merge interval I with its lexicographic predecessor. The resulting | |
1106 interval is returned, and has the properties of the original predecessor. | |
1107 The properties of I are lost. Interval node I is removed from the tree. | |
1108 | |
1109 IMPORTANT: | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1110 The caller must verify that this is not the first (leftmost) interval. */ |
1211 | 1111 |
1112 INTERVAL | |
1113 merge_interval_left (i) | |
1114 register INTERVAL i; | |
1115 { | |
1116 register int absorb = LENGTH (i); | |
1117 register INTERVAL predecessor; | |
1118 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1119 /* Zero out this interval. */ |
1211 | 1120 i->total_length -= absorb; |
1121 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1122 /* Find the preceding interval. */ |
1211 | 1123 if (! NULL_LEFT_CHILD (i)) /* It's below us. Go down, |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1124 adding ABSORB as we go. */ |
1211 | 1125 { |
1126 predecessor = i->left; | |
1127 while (! NULL_RIGHT_CHILD (predecessor)) | |
1128 { | |
1129 predecessor->total_length += absorb; | |
1130 predecessor = predecessor->right; | |
1131 } | |
1132 | |
1133 predecessor->total_length += absorb; | |
1134 delete_interval (i); | |
1135 return predecessor; | |
1136 } | |
1137 | |
1138 predecessor = i; | |
1139 while (! NULL_PARENT (predecessor)) /* It's above us. Go up, | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1140 subtracting ABSORB. */ |
1211 | 1141 { |
1142 if (AM_RIGHT_CHILD (predecessor)) | |
1143 { | |
1144 predecessor = predecessor->parent; | |
1145 delete_interval (i); | |
1146 return predecessor; | |
1147 } | |
1148 | |
1149 predecessor = predecessor->parent; | |
1150 predecessor->total_length -= absorb; | |
1151 } | |
1152 | |
1153 /* This must be the leftmost or first interval and cannot | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1154 be merged left. The caller should have known. */ |
1211 | 1155 abort (); |
1156 } | |
1157 | |
1189 | 1158 /* Make an exact copy of interval tree SOURCE which descends from |
1159 PARENT. This is done by recursing through SOURCE, copying | |
1160 the current interval and its properties, and then adjusting | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1161 the pointers of the copy. */ |
1189 | 1162 |
1157 | 1163 static INTERVAL |
1164 reproduce_tree (source, parent) | |
1165 INTERVAL source, parent; | |
1166 { | |
1167 register INTERVAL t = make_interval (); | |
1168 | |
1169 bcopy (source, t, INTERVAL_SIZE); | |
1170 copy_properties (source, t); | |
1171 t->parent = parent; | |
1172 if (! NULL_LEFT_CHILD (source)) | |
1173 t->left = reproduce_tree (source->left, t); | |
1174 if (! NULL_RIGHT_CHILD (source)) | |
1175 t->right = reproduce_tree (source->right, t); | |
1176 | |
1177 return t; | |
1178 } | |
1179 | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
1180 #if 0 |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
1181 /* Nobody calls this. Perhaps it's a vestige of an earlier design. */ |
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
1182 |
1189 | 1183 /* Make a new interval of length LENGTH starting at START in the |
1184 group of intervals INTERVALS, which is actually an interval tree. | |
1185 Returns the new interval. | |
1186 | |
1187 Generate an error if the new positions would overlap an existing | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1188 interval. */ |
1189 | 1189 |
1157 | 1190 static INTERVAL |
1191 make_new_interval (intervals, start, length) | |
1192 INTERVAL intervals; | |
1193 int start, length; | |
1194 { | |
1195 INTERVAL slot; | |
1196 | |
1197 slot = find_interval (intervals, start); | |
1198 if (start + length > slot->position + LENGTH (slot)) | |
1199 error ("Interval would overlap"); | |
1200 | |
1201 if (start == slot->position && length == LENGTH (slot)) | |
1202 return slot; | |
1203 | |
1204 if (slot->position == start) | |
1205 { | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1206 /* New right node. */ |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
1207 split_interval_right (slot, length); |
1157 | 1208 return slot; |
1209 } | |
1210 | |
1211 if (slot->position + LENGTH (slot) == start + length) | |
1212 { | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1213 /* New left node. */ |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
1214 split_interval_left (slot, LENGTH (slot) - length); |
1157 | 1215 return slot; |
1216 } | |
1217 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1218 /* Convert interval SLOT into three intervals. */ |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
1219 split_interval_left (slot, start - slot->position); |
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
1220 split_interval_right (slot, length); |
1157 | 1221 return slot; |
1222 } | |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
1223 #endif |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1224 |
1211 | 1225 /* Insert the intervals of SOURCE into BUFFER at POSITION. |
5169
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1226 LENGTH is the length of the text in SOURCE. |
1157 | 1227 |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
1228 This is used in insdel.c when inserting Lisp_Strings into the |
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
1229 buffer. The text corresponding to SOURCE is already in the buffer |
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
1230 when this is called. The intervals of new tree are a copy of those |
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
1231 belonging to the string being inserted; intervals are never |
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
1232 shared. |
1157 | 1233 |
5169
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1234 If the inserted text had no intervals associated, and we don't |
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1235 want to inherit the surrounding text's properties, this function |
1157 | 1236 simply returns -- offset_intervals should handle placing the |
1164 | 1237 text in the correct interval, depending on the sticky bits. |
1157 | 1238 |
1239 If the inserted text had properties (intervals), then there are two | |
1240 cases -- either insertion happened in the middle of some interval, | |
1241 or between two intervals. | |
1242 | |
1243 If the text goes into the middle of an interval, then new | |
1244 intervals are created in the middle with only the properties of | |
1245 the new text, *unless* the macro MERGE_INSERTIONS is true, in | |
1246 which case the new text has the union of its properties and those | |
1247 of the text into which it was inserted. | |
1248 | |
1249 If the text goes between two intervals, then if neither interval | |
1164 | 1250 had its appropriate sticky property set (front_sticky, rear_sticky), |
1251 the new text has only its properties. If one of the sticky properties | |
1157 | 1252 is set, then the new text "sticks" to that region and its properties |
3591
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
3490
diff
changeset
|
1253 depend on merging as above. If both the preceding and succeeding |
1164 | 1254 intervals to the new text are "sticky", then the new text retains |
1255 only its properties, as if neither sticky property were set. Perhaps | |
1157 | 1256 we should consider merging all three sets of properties onto the new |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1257 text... */ |
1157 | 1258 |
1259 void | |
5169
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1260 graft_intervals_into_buffer (source, position, length, buffer, inherit) |
1211 | 1261 INTERVAL source; |
5169
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1262 int position, length; |
1211 | 1263 struct buffer *buffer; |
4718
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1264 int inherit; |
1157 | 1265 { |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1266 register INTERVAL under, over, this, prev; |
1211 | 1267 register INTERVAL tree = buffer->intervals; |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1268 int middle; |
1157 | 1269 |
1270 /* If the new text has no properties, it becomes part of whatever | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1271 interval it was inserted into. */ |
1211 | 1272 if (NULL_INTERVAL_P (source)) |
5169
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1273 { |
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1274 Lisp_Object buf; |
5250
63a865489a1e
(graft_intervals_into_buffer): If SOURCE is null
Richard M. Stallman <rms@gnu.org>
parents:
5173
diff
changeset
|
1275 if (!inherit && ! NULL_INTERVAL_P (tree)) |
5169
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1276 { |
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1277 XSET (buf, Lisp_Buffer, buffer); |
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1278 Fset_text_properties (make_number (position), |
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1279 make_number (position + length), |
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1280 Qnil, buf); |
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1281 } |
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1282 return; |
d040c1a8ccbe
(graft_intervals_into_buffer): New arg LENGTH.
Richard M. Stallman <rms@gnu.org>
parents:
4962
diff
changeset
|
1283 } |
1157 | 1284 |
1285 if (NULL_INTERVAL_P (tree)) | |
1286 { | |
1287 /* The inserted text constitutes the whole buffer, so | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1288 simply copy over the interval structure. */ |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
1289 if ((BUF_Z (buffer) - BUF_BEG (buffer)) == TOTAL_LENGTH (source)) |
1157 | 1290 { |
4223
b044f6d3c4cb
(graft_intervals_into_buffer): When TREE is null,
Richard M. Stallman <rms@gnu.org>
parents:
4135
diff
changeset
|
1291 Lisp_Object buf; |
b044f6d3c4cb
(graft_intervals_into_buffer): When TREE is null,
Richard M. Stallman <rms@gnu.org>
parents:
4135
diff
changeset
|
1292 XSET (buf, Lisp_Buffer, buffer); |
b044f6d3c4cb
(graft_intervals_into_buffer): When TREE is null,
Richard M. Stallman <rms@gnu.org>
parents:
4135
diff
changeset
|
1293 buffer->intervals = reproduce_tree (source, buf); |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1294 /* Explicitly free the old tree here. */ |
1157 | 1295 |
1296 return; | |
1297 } | |
1298 | |
1299 /* Create an interval tree in which to place a copy | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1300 of the intervals of the inserted string. */ |
1157 | 1301 { |
1307 | 1302 Lisp_Object buf; |
1303 XSET (buf, Lisp_Buffer, buffer); | |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1304 tree = create_root_interval (buf); |
1157 | 1305 } |
1306 } | |
4718
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1307 else if (TOTAL_LENGTH (tree) == TOTAL_LENGTH (source)) |
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1308 /* If the buffer contains only the new string, but |
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1309 there was already some interval tree there, then it may be |
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1310 some zero length intervals. Eventually, do something clever |
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1311 about inserting properly. For now, just waste the old intervals. */ |
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1312 { |
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1313 buffer->intervals = reproduce_tree (source, tree->parent); |
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1314 /* Explicitly free the old tree here. */ |
1157 | 1315 |
4718
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1316 return; |
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1317 } |
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1318 /* Paranoia -- the text has already been added, so this buffer |
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1319 should be of non-zero length. */ |
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1320 else if (TOTAL_LENGTH (tree) == 0) |
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1321 abort (); |
1157 | 1322 |
1323 this = under = find_interval (tree, position); | |
1324 if (NULL_INTERVAL_P (under)) /* Paranoia */ | |
1325 abort (); | |
1211 | 1326 over = find_interval (source, 1); |
1157 | 1327 |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1328 /* Here for insertion in the middle of an interval. |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1329 Split off an equivalent interval to the right, |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1330 then don't bother with it any more. */ |
1157 | 1331 |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1332 if (position > under->position) |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1333 { |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1334 INTERVAL end_unchanged |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
1335 = split_interval_left (this, position - under->position); |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1336 copy_properties (under, end_unchanged); |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1337 under->position = position; |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1338 prev = 0; |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1339 middle = 1; |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1340 } |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1341 else |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1342 { |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1343 prev = previous_interval (under); |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1344 if (prev && !END_NONSTICKY_P (prev)) |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1345 prev = 0; |
1157 | 1346 } |
1347 | |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1348 /* Insertion is now at beginning of UNDER. */ |
1157 | 1349 |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1350 /* The inserted text "sticks" to the interval `under', |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1351 which means it gets those properties. |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1352 The properties of under are the result of |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1353 adjust_intervals_for_insertion, so stickyness has |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1354 already been taken care of. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1355 |
1157 | 1356 while (! NULL_INTERVAL_P (over)) |
1357 { | |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
1358 if (LENGTH (over) + 1 < LENGTH (under)) |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1359 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1360 this = split_interval_left (under, LENGTH (over)); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1361 copy_properties (under, this); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1362 } |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1363 else |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1364 this = under; |
1157 | 1365 copy_properties (over, this); |
4718
a05b833e61c4
(graft_intervals_into_buffer): New arg INHERIT.
Richard M. Stallman <rms@gnu.org>
parents:
4696
diff
changeset
|
1366 if (inherit) |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1367 merge_properties (over, this); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1368 else |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1369 copy_properties (over, this); |
1157 | 1370 over = next_interval (over); |
1371 } | |
1372 | |
1211 | 1373 buffer->intervals = balance_intervals (buffer->intervals); |
1157 | 1374 return; |
1375 } | |
1376 | |
2090
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1377 /* Get the value of property PROP from PLIST, |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1378 which is the plist of an interval. |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1379 We check for direct properties and for categories with property PROP. */ |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1380 |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1381 Lisp_Object |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1382 textget (plist, prop) |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1383 Lisp_Object plist; |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1384 register Lisp_Object prop; |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1385 { |
2090
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1386 register Lisp_Object tail, fallback; |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1387 fallback = Qnil; |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1388 |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1389 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail))) |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1390 { |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1391 register Lisp_Object tem; |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1392 tem = Fcar (tail); |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1393 if (EQ (prop, tem)) |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1394 return Fcar (Fcdr (tail)); |
2090
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1395 if (EQ (tem, Qcategory)) |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1396 fallback = Fget (Fcar (Fcdr (tail)), prop); |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1397 } |
2090
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1398 |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1399 return fallback; |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1400 } |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1401 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1402 /* Get the value of property PROP from PLIST, |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1403 which is the plist of an interval. |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1404 We check for direct properties only! */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1405 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1406 Lisp_Object |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1407 textget_direct (plist, prop) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1408 Lisp_Object plist; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1409 register Lisp_Object prop; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1410 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1411 register Lisp_Object tail; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1412 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1413 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail))) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1414 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1415 if (EQ (prop, Fcar (tail))) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1416 return Fcar (Fcdr (tail)); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1417 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1418 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1419 return Qnil; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1420 } |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1421 |
2090
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1422 /* Set point in BUFFER to POSITION. If the target position is |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1423 before an invisible character which is not displayed with a special glyph, |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1424 move back to an ok place to display. */ |
1157 | 1425 |
1426 void | |
1427 set_point (position, buffer) | |
1428 register int position; | |
1429 register struct buffer *buffer; | |
1430 { | |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1431 register INTERVAL to, from, toprev, fromprev, target; |
1157 | 1432 int buffer_point; |
1433 register Lisp_Object obj; | |
1434 int backwards = (position < BUF_PT (buffer)) ? 1 : 0; | |
1211 | 1435 int old_position = buffer->text.pt; |
1157 | 1436 |
1437 if (position == buffer->text.pt) | |
1438 return; | |
1439 | |
2779
857bb0f59668
* intervals.c (set_point): Check for point out of bounds before
Jim Blandy <jimb@redhat.com>
parents:
2090
diff
changeset
|
1440 /* Check this now, before checking if the buffer has any intervals. |
857bb0f59668
* intervals.c (set_point): Check for point out of bounds before
Jim Blandy <jimb@redhat.com>
parents:
2090
diff
changeset
|
1441 That way, we can catch conditions which break this sanity check |
857bb0f59668
* intervals.c (set_point): Check for point out of bounds before
Jim Blandy <jimb@redhat.com>
parents:
2090
diff
changeset
|
1442 whether or not there are intervals in the buffer. */ |
857bb0f59668
* intervals.c (set_point): Check for point out of bounds before
Jim Blandy <jimb@redhat.com>
parents:
2090
diff
changeset
|
1443 if (position > BUF_Z (buffer) || position < BUF_BEG (buffer)) |
857bb0f59668
* intervals.c (set_point): Check for point out of bounds before
Jim Blandy <jimb@redhat.com>
parents:
2090
diff
changeset
|
1444 abort (); |
857bb0f59668
* intervals.c (set_point): Check for point out of bounds before
Jim Blandy <jimb@redhat.com>
parents:
2090
diff
changeset
|
1445 |
1157 | 1446 if (NULL_INTERVAL_P (buffer->intervals)) |
1447 { | |
1448 buffer->text.pt = position; | |
1449 return; | |
1450 } | |
1451 | |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1452 /* Set TO to the interval containing the char after POSITION, |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1453 and TOPREV to the interval containing the char before POSITION. |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1454 Either one may be null. They may be equal. */ |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
1455 to = find_interval (buffer->intervals, position); |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1456 if (position == BUF_BEGV (buffer)) |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1457 toprev = 0; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1458 else if (to->position == position) |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1459 toprev = previous_interval (to); |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1460 else |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1461 toprev = to; |
1211 | 1462 |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1463 buffer_point = (BUF_PT (buffer) == BUF_ZV (buffer) |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1464 ? BUF_ZV (buffer) - 1 |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1465 : BUF_PT (buffer)); |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1466 |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1467 /* Set FROM to the interval containing the char after PT, |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1468 and FROMPREV to the interval containing the char before PT. |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1469 Either one may be null. They may be equal. */ |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1470 /* We could cache this and save time. */ |
1157 | 1471 from = find_interval (buffer->intervals, buffer_point); |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1472 if (buffer_point == BUF_BEGV (buffer)) |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1473 fromprev = 0; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1474 else if (from->position == BUF_PT (buffer)) |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1475 fromprev = previous_interval (from); |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1476 else if (buffer_point != BUF_PT (buffer)) |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1477 fromprev = from, from = 0; |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1478 else |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1479 fromprev = from; |
1157 | 1480 |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1481 /* Moving within an interval. */ |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1482 if (to == from && toprev == fromprev && INTERVAL_VISIBLE_P (to)) |
1157 | 1483 { |
1484 buffer->text.pt = position; | |
1485 return; | |
1486 } | |
1487 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1488 /* If the new position is before an invisible character |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1489 that has an `invisible' property of value `hidden', |
2090
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1490 move forward over all such. */ |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1491 while (! NULL_INTERVAL_P (to) |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1492 && EQ (textget (to->plist, Qinvisible), Qhidden) |
2090
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1493 && ! DISPLAY_INVISIBLE_GLYPH (to)) |
1157 | 1494 { |
2090
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1495 toprev = to; |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1496 to = next_interval (to); |
3734
5ada670e1fd8
(set_point): When moving over invis chars,
Richard M. Stallman <rms@gnu.org>
parents:
3591
diff
changeset
|
1497 if (NULL_INTERVAL_P (to)) |
5ada670e1fd8
(set_point): When moving over invis chars,
Richard M. Stallman <rms@gnu.org>
parents:
3591
diff
changeset
|
1498 position = BUF_ZV (buffer); |
5ada670e1fd8
(set_point): When moving over invis chars,
Richard M. Stallman <rms@gnu.org>
parents:
3591
diff
changeset
|
1499 else |
5ada670e1fd8
(set_point): When moving over invis chars,
Richard M. Stallman <rms@gnu.org>
parents:
3591
diff
changeset
|
1500 position = to->position; |
1157 | 1501 } |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1502 |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1503 buffer->text.pt = position; |
1157 | 1504 |
1288 | 1505 /* We run point-left and point-entered hooks here, iff the |
1506 two intervals are not equivalent. These hooks take | |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1507 (old_point, new_point) as arguments. */ |
4243
23fe7f6c9ae4
(set_point): Test Vinhibit_point_motion_hooks.
Richard M. Stallman <rms@gnu.org>
parents:
4223
diff
changeset
|
1508 if (NILP (Vinhibit_point_motion_hooks) |
23fe7f6c9ae4
(set_point): Test Vinhibit_point_motion_hooks.
Richard M. Stallman <rms@gnu.org>
parents:
4223
diff
changeset
|
1509 && (! intervals_equal (from, to) |
23fe7f6c9ae4
(set_point): Test Vinhibit_point_motion_hooks.
Richard M. Stallman <rms@gnu.org>
parents:
4223
diff
changeset
|
1510 || ! intervals_equal (fromprev, toprev))) |
1211 | 1511 { |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1512 Lisp_Object leave_after, leave_before, enter_after, enter_before; |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1513 |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1514 if (fromprev) |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1515 leave_after = textget (fromprev->plist, Qpoint_left); |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1516 else |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1517 leave_after = Qnil; |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1518 if (from) |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1519 leave_before = textget (from->plist, Qpoint_left); |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1520 else |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1521 leave_before = Qnil; |
1211 | 1522 |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1523 if (toprev) |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1524 enter_after = textget (toprev->plist, Qpoint_entered); |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1525 else |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1526 enter_after = Qnil; |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1527 if (to) |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1528 enter_before = textget (to->plist, Qpoint_entered); |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1529 else |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1530 enter_before = Qnil; |
1211 | 1531 |
1964
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1532 if (! EQ (leave_before, enter_before) && !NILP (leave_before)) |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1533 call2 (leave_before, old_position, position); |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1534 if (! EQ (leave_after, enter_after) && !NILP (leave_after)) |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1535 call2 (leave_after, old_position, position); |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1536 |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1537 if (! EQ (enter_before, leave_before) && !NILP (enter_before)) |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1538 call2 (enter_before, old_position, position); |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1539 if (! EQ (enter_after, leave_after) && !NILP (enter_after)) |
e6c49ff3a53c
(intervals_equal): Handle one arg null and other not.
Richard M. Stallman <rms@gnu.org>
parents:
1958
diff
changeset
|
1540 call2 (enter_after, old_position, position); |
1211 | 1541 } |
1157 | 1542 } |
1543 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1544 /* Set point temporarily, without checking any text properties. */ |
1157 | 1545 |
1211 | 1546 INLINE void |
1547 temp_set_point (position, buffer) | |
1548 int position; | |
1549 struct buffer *buffer; | |
1550 { | |
1551 buffer->text.pt = position; | |
1552 } | |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1553 |
2090
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1554 /* Return the proper local map for position POSITION in BUFFER. |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1555 Use the map specified by the local-map property, if any. |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1556 Otherwise, use BUFFER's local map. */ |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1557 |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1558 Lisp_Object |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1559 get_local_map (position, buffer) |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1560 register int position; |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1561 register struct buffer *buffer; |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1562 { |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1563 register INTERVAL interval; |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1564 Lisp_Object prop, tem; |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1565 |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1566 if (NULL_INTERVAL_P (buffer->intervals)) |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1567 return current_buffer->keymap; |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1568 |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1569 /* Perhaps we should just change `position' to the limit. */ |
2090
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1570 if (position > BUF_Z (buffer) || position < BUF_BEG (buffer)) |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1571 abort (); |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1572 |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1573 interval = find_interval (buffer->intervals, position); |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1574 prop = textget (interval->plist, Qlocal_map); |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1575 if (NILP (prop)) |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1576 return current_buffer->keymap; |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1577 |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1578 /* Use the local map only if it is valid. */ |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1579 tem = Fkeymapp (prop); |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1580 if (!NILP (tem)) |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1581 return prop; |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1582 |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1583 return current_buffer->keymap; |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1584 } |
c7e1308a7184
(set_point): Check invisibility of following character, not previous character.
Richard M. Stallman <rms@gnu.org>
parents:
2052
diff
changeset
|
1585 |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1586 /* Call the modification hook functions in LIST, each with START and END. */ |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1587 |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1588 static void |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1589 call_mod_hooks (list, start, end) |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1590 Lisp_Object list, start, end; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1591 { |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1592 struct gcpro gcpro1; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1593 GCPRO1 (list); |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1594 while (!NILP (list)) |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1595 { |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1596 call2 (Fcar (list), start, end); |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1597 list = Fcdr (list); |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1598 } |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1599 UNGCPRO; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1600 } |
1211 | 1601 |
1602 /* Check for read-only intervals and signal an error if we find one. | |
1603 Then check for any modification hooks in the range START up to | |
1604 (but not including) TO. Create a list of all these hooks in | |
1605 lexicographic order, eliminating consecutive extra copies of the | |
1606 same hook. Then call those hooks in order, with START and END - 1 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1607 as arguments. */ |
1157 | 1608 |
1609 void | |
1610 verify_interval_modification (buf, start, end) | |
1611 struct buffer *buf; | |
1612 int start, end; | |
1613 { | |
1614 register INTERVAL intervals = buf->intervals; | |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1615 register INTERVAL i, prev; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1616 Lisp_Object hooks; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1617 register Lisp_Object prev_mod_hooks; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1618 Lisp_Object mod_hooks; |
1211 | 1619 struct gcpro gcpro1; |
1157 | 1620 |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1621 hooks = Qnil; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1622 prev_mod_hooks = Qnil; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1623 mod_hooks = Qnil; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1624 |
1157 | 1625 if (NULL_INTERVAL_P (intervals)) |
1626 return; | |
1627 | |
1628 if (start > end) | |
1629 { | |
1630 int temp = start; | |
1631 start = end; | |
1632 end = temp; | |
1633 } | |
1634 | |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1635 /* For an insert operation, check the two chars around the position. */ |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1636 if (start == end) |
1157 | 1637 { |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1638 INTERVAL prev; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1639 Lisp_Object before, after; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1640 |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1641 /* Set I to the interval containing the char after START, |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1642 and PREV to the interval containing the char before START. |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1643 Either one may be null. They may be equal. */ |
4005
da8962f65741
* intervals.c (find_interval): Doc fixes, computation of
Jim Blandy <jimb@redhat.com>
parents:
3998
diff
changeset
|
1644 i = find_interval (intervals, start); |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1645 |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1646 if (start == BUF_BEGV (buf)) |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1647 prev = 0; |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1648 else if (i->position == start) |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1649 prev = previous_interval (i); |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1650 else if (i->position < start) |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1651 prev = i; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1652 if (start == BUF_ZV (buf)) |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1653 i = 0; |
1157 | 1654 |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1655 /* If Vinhibit_read_only is set and is not a list, we can |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1656 skip the read_only checks. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1657 if (NILP (Vinhibit_read_only) || CONSP (Vinhibit_read_only)) |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1658 { |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1659 /* If I and PREV differ we need to check for the read-only |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1660 property together with its stickyness. If either I or |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1661 PREV are 0, this check is all we need. |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1662 We have to take special care, since read-only may be |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1663 indirectly defined via the category property. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1664 if (i != prev) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1665 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1666 if (! NULL_INTERVAL_P (i)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1667 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1668 after = textget (i->plist, Qread_only); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1669 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1670 /* If interval I is read-only and read-only is |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1671 front-sticky, inhibit insertion. |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1672 Check for read-only as well as category. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1673 if (! NILP (after) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1674 && NILP (Fmemq (after, Vinhibit_read_only)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1675 && (! NILP (Fmemq (Qread_only, |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1676 textget (i->plist, Qfront_sticky))) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1677 || (NILP (textget_direct (i->plist, Qread_only)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1678 && ! NILP (Fmemq (Qcategory, |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1679 textget (i->plist, |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1680 Qfront_sticky)))))) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1681 error ("Attempt to insert within read-only text"); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1682 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1683 else |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1684 after = Qnil; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1685 if (! NULL_INTERVAL_P (prev)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1686 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1687 before = textget (prev->plist, Qread_only); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1688 |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1689 /* If interval PREV is read-only and read-only isn't |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1690 rear-nonsticky, inhibit insertion. |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1691 Check for read-only as well as category. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1692 if (! NILP (before) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1693 && NILP (Fmemq (before, Vinhibit_read_only)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1694 && NILP (Fmemq (Qread_only, |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1695 textget (prev->plist, Qrear_nonsticky))) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1696 && (! NILP (textget_direct (prev->plist,Qread_only)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1697 || NILP (Fmemq (Qcategory, |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1698 textget (prev->plist, |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1699 Qrear_nonsticky))))) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1700 error ("Attempt to insert within read-only text"); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1701 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1702 else |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1703 before = Qnil; |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1704 } |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1705 else if (! NULL_INTERVAL_P (i)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1706 before = after = textget (i->plist, Qread_only); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1707 if (! NULL_INTERVAL_P (i) && ! NULL_INTERVAL_P (prev)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1708 { |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1709 /* If I and PREV differ, neither of them has a sticky |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1710 read-only property. It only remains to check, whether |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1711 they have a common read-only property. */ |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1712 if (! NILP (before) && EQ (before, after)) |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1713 error ("Attempt to insert within read-only text"); |
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1714 } |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1715 } |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1716 |
4066
bb9478383bde
(verify_interval_modification):
Richard M. Stallman <rms@gnu.org>
parents:
4005
diff
changeset
|
1717 /* Run both insert hooks (just once if they're the same). */ |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1718 if (!NULL_INTERVAL_P (prev)) |
4080
8200d631e3f3
(verify_interval_modification): Use Qinsert_in_front_hooks and
Richard M. Stallman <rms@gnu.org>
parents:
4066
diff
changeset
|
1719 prev_mod_hooks = textget (prev->plist, Qinsert_behind_hooks); |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1720 if (!NULL_INTERVAL_P (i)) |
4080
8200d631e3f3
(verify_interval_modification): Use Qinsert_in_front_hooks and
Richard M. Stallman <rms@gnu.org>
parents:
4066
diff
changeset
|
1721 mod_hooks = textget (i->plist, Qinsert_in_front_hooks); |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1722 GCPRO1 (mod_hooks); |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1723 if (! NILP (prev_mod_hooks)) |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1724 call_mod_hooks (prev_mod_hooks, make_number (start), |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1725 make_number (end)); |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1726 UNGCPRO; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1727 if (! NILP (mod_hooks) && ! EQ (mod_hooks, prev_mod_hooks)) |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1728 call_mod_hooks (mod_hooks, make_number (start), make_number (end)); |
1157 | 1729 } |
1730 else | |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1731 { |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1732 /* Loop over intervals on or next to START...END, |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1733 collecting their hooks. */ |
1157 | 1734 |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1735 i = find_interval (intervals, start); |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1736 do |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1737 { |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1738 if (! INTERVAL_WRITABLE_P (i)) |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1739 error ("Attempt to modify read-only text"); |
1211 | 1740 |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1741 mod_hooks = textget (i->plist, Qmodification_hooks); |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1742 if (! NILP (mod_hooks) && ! EQ (mod_hooks, prev_mod_hooks)) |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1743 { |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1744 hooks = Fcons (mod_hooks, hooks); |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1745 prev_mod_hooks = mod_hooks; |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1746 } |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1747 |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1748 i = next_interval (i); |
1211 | 1749 } |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1750 /* Keep going thru the interval containing the char before END. */ |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1751 while (! NULL_INTERVAL_P (i) && i->position < end); |
1157 | 1752 |
2052
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1753 GCPRO1 (hooks); |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1754 hooks = Fnreverse (hooks); |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1755 while (! EQ (hooks, Qnil)) |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1756 { |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1757 call_mod_hooks (Fcar (hooks), make_number (start), |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1758 make_number (end)); |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1759 hooks = Fcdr (hooks); |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1760 } |
48c83a34c005
(verify_interval_modification): Handle insertions
Richard M. Stallman <rms@gnu.org>
parents:
1964
diff
changeset
|
1761 UNGCPRO; |
1211 | 1762 } |
1157 | 1763 } |
1764 | |
1765 /* Balance an interval node if the amount of text in its left and right | |
1766 subtrees differs by more than the percentage specified by | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1767 `interval-balance-threshold'. */ |
1157 | 1768 |
1769 static INTERVAL | |
1770 balance_an_interval (i) | |
1771 INTERVAL i; | |
1772 { | |
1773 register int total_children_size = (LEFT_TOTAL_LENGTH (i) | |
1774 + RIGHT_TOTAL_LENGTH (i)); | |
1775 register int threshold = (XFASTINT (interval_balance_threshold) | |
1776 * (total_children_size / 100)); | |
1777 | |
3490
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1778 /* Balance within each side. */ |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1779 balance_intervals (i->left); |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1780 balance_intervals (i->right); |
1157 | 1781 |
1782 if (LEFT_TOTAL_LENGTH (i) > RIGHT_TOTAL_LENGTH (i) | |
1783 && (LEFT_TOTAL_LENGTH (i) - RIGHT_TOTAL_LENGTH (i)) > threshold) | |
3490
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1784 { |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1785 i = rotate_right (i); |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1786 /* If that made it unbalanced the other way, take it back. */ |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1787 if (RIGHT_TOTAL_LENGTH (i) > LEFT_TOTAL_LENGTH (i) |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1788 && (RIGHT_TOTAL_LENGTH (i) - LEFT_TOTAL_LENGTH (i)) > threshold) |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1789 return rotate_left (i); |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1790 return i; |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1791 } |
1157 | 1792 |
3490
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1793 if (RIGHT_TOTAL_LENGTH (i) > LEFT_TOTAL_LENGTH (i) |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1794 && (RIGHT_TOTAL_LENGTH (i) - LEFT_TOTAL_LENGTH (i)) > threshold) |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1795 { |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1796 i = rotate_left (i); |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1797 if (LEFT_TOTAL_LENGTH (i) > RIGHT_TOTAL_LENGTH (i) |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1798 && (LEFT_TOTAL_LENGTH (i) - RIGHT_TOTAL_LENGTH (i)) > threshold) |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1799 return rotate_right (i); |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1800 return i; |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1801 } |
1157 | 1802 |
1803 return i; | |
1804 } | |
1805 | |
1806 /* Balance the interval tree TREE. Balancing is by weight | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1807 (the amount of text). */ |
1157 | 1808 |
1809 INTERVAL | |
1810 balance_intervals (tree) | |
1811 register INTERVAL tree; | |
1812 { | |
1813 register INTERVAL new_tree; | |
1814 | |
1815 if (NULL_INTERVAL_P (tree)) | |
1816 return NULL_INTERVAL; | |
1817 | |
1818 new_tree = tree; | |
1819 do | |
1820 { | |
1821 tree = new_tree; | |
1822 new_tree = balance_an_interval (new_tree); | |
1823 } | |
1824 while (new_tree != tree); | |
1825 | |
1826 return new_tree; | |
1827 } | |
1828 | |
1211 | 1829 /* Produce an interval tree reflecting the intervals in |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1830 TREE from START to START + LENGTH. */ |
1157 | 1831 |
1316
f09c5c6563b8
* intervals.c: `copy_intervals()' no longer static.
Joseph Arceneaux <jla@gnu.org>
parents:
1307
diff
changeset
|
1832 INTERVAL |
1157 | 1833 copy_intervals (tree, start, length) |
1834 INTERVAL tree; | |
1835 int start, length; | |
1836 { | |
1837 register INTERVAL i, new, t; | |
3490
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1838 register int got, prevlen; |
1157 | 1839 |
1840 if (NULL_INTERVAL_P (tree) || length <= 0) | |
1841 return NULL_INTERVAL; | |
1842 | |
1843 i = find_interval (tree, start); | |
1844 if (NULL_INTERVAL_P (i) || LENGTH (i) == 0) | |
1845 abort (); | |
1846 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1847 /* If there is only one interval and it's the default, return nil. */ |
1157 | 1848 if ((start - i->position + 1 + length) < LENGTH (i) |
1849 && DEFAULT_INTERVAL_P (i)) | |
1850 return NULL_INTERVAL; | |
1851 | |
1852 new = make_interval (); | |
1853 new->position = 1; | |
1854 got = (LENGTH (i) - (start - i->position)); | |
1211 | 1855 new->total_length = length; |
1157 | 1856 copy_properties (i, new); |
1857 | |
1858 t = new; | |
3490
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1859 prevlen = got; |
1157 | 1860 while (got < length) |
1861 { | |
1862 i = next_interval (i); | |
4135
84ea8ebc9858
* intervals.c (split_interval_left, split_interval_right): Change
Jim Blandy <jimb@redhat.com>
parents:
4080
diff
changeset
|
1863 t = split_interval_right (t, prevlen); |
1157 | 1864 copy_properties (i, t); |
3490
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1865 prevlen = LENGTH (i); |
07b454ddc666
(copy_intervals): Don't adjust total_length at the end.
Richard M. Stallman <rms@gnu.org>
parents:
3333
diff
changeset
|
1866 got += prevlen; |
1157 | 1867 } |
1868 | |
1869 return balance_intervals (new); | |
1870 } | |
1871 | |
4383
d4a36c1669e6
(adjust_intervals_for_insertion): Handle insertion
Richard M. Stallman <rms@gnu.org>
parents:
4243
diff
changeset
|
1872 /* Give STRING the properties of BUFFER from POSITION to LENGTH. */ |
1157 | 1873 |
1288 | 1874 INLINE void |
1157 | 1875 copy_intervals_to_string (string, buffer, position, length) |
1876 Lisp_Object string, buffer; | |
1877 int position, length; | |
1878 { | |
1879 INTERVAL interval_copy = copy_intervals (XBUFFER (buffer)->intervals, | |
1880 position, length); | |
1881 if (NULL_INTERVAL_P (interval_copy)) | |
1882 return; | |
1883 | |
1884 interval_copy->parent = (INTERVAL) string; | |
1885 XSTRING (string)->intervals = interval_copy; | |
1886 } | |
1301
5a27062b8b7f
* intervals.c: Conditionalize all functions on
Joseph Arceneaux <jla@gnu.org>
parents:
1288
diff
changeset
|
1887 |
5a27062b8b7f
* intervals.c: Conditionalize all functions on
Joseph Arceneaux <jla@gnu.org>
parents:
1288
diff
changeset
|
1888 #endif /* USE_TEXT_PROPERTIES */ |