1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23: #include <config.h>
24: #include "lisp.h"
25: #include "intervals.h"
26: #include "buffer.h"
27: #include "charset.h"
28: #include "window.h"
29: #include "blockinput.h"
30: #include "region-cache.h"
31:
32: #ifndef NULL
33: #define NULL 0
34: #endif
35:
36: static void insert_from_string_1 P_ ((Lisp_Object, int, int, int, int, int, int));
37: static void insert_from_buffer_1 ();
38: static void gap_left P_ ((int, int, int));
39: static void gap_right P_ ((int, int));
40: static void adjust_markers_gap_motion P_ ((int, int, int));
41: static void adjust_markers_for_insert P_ ((int, int, int, int, int));
42: void adjust_markers_for_delete P_ ((int, int, int, int));
43: static void adjust_markers_for_replace P_ ((int, int, int, int, int, int));
44: static void adjust_point P_ ((int, int));
45:
46: Lisp_Object Fcombine_after_change_execute ();
47:
48:
49:
50: Lisp_Object Vcombine_after_change_calls;
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62: Lisp_Object combine_after_change_list;
63:
64:
65: Lisp_Object combine_after_change_buffer;
66:
67: Lisp_Object Qinhibit_modification_hooks;
68:
69: ^L
70:
71:
72: static int check_markers_debug_flag;
73:
74: #define CHECK_MARKERS() \
75: if (check_markers_debug_flag) \
76: check_markers (); \
77: else
78:
79: void
80: check_markers ()
81: {
82: register struct Lisp_Marker *tail;
83: int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
84:
85: for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
86: {
87: if (tail->buffer->text != current_buffer->text)
88: abort ();
89: if (tail->charpos > Z)
90: abort ();
91: if (tail->bytepos > Z_BYTE)
92: abort ();
93: if (multibyte && ! CHAR_HEAD_P (FETCH_BYTE (tail->bytepos)))
94: abort ();
95: }
96: }
97: ^L
98:
99:
100:
101: void
102: move_gap (charpos)
103: int charpos;
104: {
105: move_gap_both (charpos, charpos_to_bytepos (charpos));
106: }
107:
108:
109:
110:
111: void
112: move_gap_both (charpos, bytepos)
113: int charpos, bytepos;
114: {
115: if (bytepos < GPT_BYTE)
116: gap_left (charpos, bytepos, 0);
117: else if (bytepos > GPT_BYTE)
118: gap_right (charpos, bytepos);
119: }
120:
121:
122:
123:
124:
125:
126: static void
127: gap_left (charpos, bytepos, newgap)
128: register int charpos, bytepos;
129: int newgap;
130: {
131: register unsigned char *to, *from;
132: register int i;
133: int new_s1;
134:
135: if (!newgap)
136: BUF_COMPUTE_UNCHANGED (current_buffer, charpos, GPT);
137:
138: i = GPT_BYTE;
139: to = GAP_END_ADDR;
140: from = GPT_ADDR;
141: new_s1 = GPT_BYTE;
142:
143:
144:
145:
146: while (1)
147: {
148:
149: i = new_s1 - bytepos;
150: if (i == 0)
151: break;
152:
153:
154: if (QUITP)
155: {
156: bytepos = new_s1;
157: charpos = BYTE_TO_CHAR (bytepos);
158: break;
159: }
160:
161: if (i > 32000)
162: i = 32000;
163: #ifdef GAP_USE_BCOPY
164: if (i >= 128
165:
166:
167: && (BCOPY_UPWARD_SAFE
168: || to - from >= 128))
169: {
170:
171:
172: if (!BCOPY_UPWARD_SAFE && i > to - from)
173: i = to - from;
174: new_s1 -= i;
175: from -= i, to -= i;
176: bcopy (from, to, i);
177: }
178: else
179: #endif
180: {
181: new_s1 -= i;
182: while (--i >= 0)
183: *--to = *--from;
184: }
185: }
186:
187:
188:
189:
190: adjust_markers_gap_motion (bytepos, GPT_BYTE, GAP_SIZE);
191: GPT_BYTE = bytepos;
192: GPT = charpos;
193: if (bytepos < charpos)
194: abort ();
195: if (GAP_SIZE > 0) *(GPT_ADDR) = 0;
196: QUIT;
197: }
198:
199:
200:
201:
202:
203: static void
204: gap_right (charpos, bytepos)
205: register int charpos, bytepos;
206: {
207: register unsigned char *to, *from;
208: register int i;
209: int new_s1;
210:
211: BUF_COMPUTE_UNCHANGED (current_buffer, charpos, GPT);
212:
213: i = GPT_BYTE;
214: from = GAP_END_ADDR;
215: to = GPT_ADDR;
216: new_s1 = GPT_BYTE;
217:
218:
219:
220:
221: while (1)
222: {
223:
224: i = bytepos - new_s1;
225: if (i == 0)
226: break;
227:
228:
229: if (QUITP)
230: {
231: bytepos = new_s1;
232: charpos = BYTE_TO_CHAR (bytepos);
233: break;
234: }
235:
236: if (i > 32000)
237: i = 32000;
238: #ifdef GAP_USE_BCOPY
239: if (i >= 128
240:
241:
242: && (BCOPY_DOWNWARD_SAFE
243: || from - to >= 128))
244: {
245:
246:
247: if (!BCOPY_DOWNWARD_SAFE && i > from - to)
248: i = from - to;
249: new_s1 += i;
250: bcopy (from, to, i);
251: from += i, to += i;
252: }
253: else
254: #endif
255: {
256: new_s1 += i;
257: while (--i >= 0)
258: *to++ = *from++;
259: }
260: }
261:
262: adjust_markers_gap_motion (GPT_BYTE + GAP_SIZE, bytepos + GAP_SIZE,
263: - GAP_SIZE);
264: GPT = charpos;
265: GPT_BYTE = bytepos;
266: if (bytepos < charpos)
267: abort ();
268: if (GAP_SIZE > 0) *(GPT_ADDR) = 0;
269: QUIT;
270: }
271: ^L
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286: int adjust_markers_test;
287:
288: static void
289: adjust_markers_gap_motion (from, to, amount)
290: register int from, to, amount;
291: {
292:
293:
294: #if 0
295: Lisp_Object marker;
296: register struct Lisp_Marker *m;
297: register int mpos;
298:
299: marker = BUF_MARKERS (current_buffer);
300:
301: while (!NILP (marker))
302: {
303: m = XMARKER (marker);
304: mpos = m->bytepos;
305: if (amount > 0)
306: {
307: if (mpos > to && mpos < to + amount)
308: {
309: if (adjust_markers_test)
310: abort ();
311: mpos = to + amount;
312: }
313: }
314: else
315: {
316:
317:
318:
319: if (mpos > from + amount && mpos <= from)
320: {
321: if (adjust_markers_test)
322: abort ();
323: mpos = from + amount;
324: }
325: }
326: if (mpos > from && mpos <= to)
327: mpos += amount;
328: m->bufpos = mpos;
329: marker = m->chain;
330: }
331: #endif
332: }
333: ^L
334:
335:
336:
337:
338:
339:
340:
341: void
342: adjust_markers_for_delete (from, from_byte, to, to_byte)
343: register int from, from_byte, to, to_byte;
344: {
345: Lisp_Object marker;
346: register struct Lisp_Marker *m;
347: register int charpos;
348:
349: for (m = BUF_MARKERS (current_buffer); m; m = m->next)
350: {
351: charpos = m->charpos;
352:
353: if (charpos > Z)
354: abort ();
355:
356:
357:
358: if (charpos > to)
359: {
360: m->charpos -= to - from;
361: m->bytepos -= to_byte - from_byte;
362: }
363:
364: else if (charpos > from)
365: {
366: if (! m->insertion_type)
367: {
368:
369:
370: XSETMISC (marker, m);
371: record_marker_adjustment (marker, from - charpos);
372: }
373: else if (charpos < to)
374: {
375:
376:
377: XSETMISC (marker, m);
378: record_marker_adjustment (marker, charpos - to);
379: }
380: m->charpos = from;
381: m->bytepos = from_byte;
382: }
383:
384:
385: else if (charpos == from && m->insertion_type)
386: {
387:
388:
389:
390:
391: XSETMISC (marker, m);
392: record_marker_adjustment (marker, to - from);
393: }
394: }
395: }
396:
397: ^L
398:
399:
400:
401:
402:
403:
404:
405:
406: static void
407: adjust_markers_for_insert (from, from_byte, to, to_byte, before_markers)
408: register int from, from_byte, to, to_byte;
409: int before_markers;
410: {
411: struct Lisp_Marker *m;
412: int adjusted = 0;
413: int nchars = to - from;
414: int nbytes = to_byte - from_byte;
415:
416: for (m = BUF_MARKERS (current_buffer); m; m = m->next)
417: {
418:
419:
420: if (Z == Z_BYTE)
421: {
422: if (m->charpos != m->bytepos)
423: abort ();
424: }
425:
426: if (m->bytepos == from_byte)
427: {
428: if (m->insertion_type || before_markers)
429: {
430: m->bytepos = to_byte;
431: m->charpos = to;
432: if (m->insertion_type)
433: adjusted = 1;
434: }
435: }
436: else if (m->bytepos > from_byte)
437: {
438: m->bytepos += nbytes;
439: m->charpos += nchars;
440: }
441: }
442:
443:
444:
445:
446: if (adjusted)
447: {
448: fix_start_end_in_overlays(from, to);
449: fix_overlays_before (current_buffer, from, to);
450: }
451: }
452:
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463: static void
464: adjust_point (nchars, nbytes)
465: int nchars, nbytes;
466: {
467: BUF_PT (current_buffer) += nchars;
468: BUF_PT_BYTE (current_buffer) += nbytes;
469:
470:
471: if (ZV == ZV_BYTE
472: && PT != PT_BYTE)
473: abort ();
474: }
475: ^L
476:
477:
478:
479:
480:
481: static void
482: adjust_markers_for_replace (from, from_byte, old_chars, old_bytes,
483: new_chars, new_bytes)
484: int from, from_byte, old_chars, old_bytes, new_chars, new_bytes;
485: {
486: register struct Lisp_Marker *m;
487: int prev_to_byte = from_byte + old_bytes;
488: int diff_chars = new_chars - old_chars;
489: int diff_bytes = new_bytes - old_bytes;
490:
491: for (m = BUF_MARKERS (current_buffer); m; m = m->next)
492: {
493: if (m->bytepos >= prev_to_byte)
494: {
495: m->charpos += diff_chars;
496: m->bytepos += diff_bytes;
497: }
498: else if (m->bytepos > from_byte)
499: {
500: m->charpos = from;
501: m->bytepos = from_byte;
502: }
503: }
504:
505: CHECK_MARKERS ();
506: }
507:
508: ^L
509:
510:
511: void
512: make_gap_larger (nbytes_added)
513: int nbytes_added;
514: {
515: Lisp_Object tem;
516: int real_gap_loc;
517: int real_gap_loc_byte;
518: int old_gap_size;
519:
520:
521: nbytes_added += 2000;
522:
523:
524:
525:
526:
527:
528:
529: if (Z_BYTE - BEG_BYTE + GAP_SIZE
530: >= (((EMACS_INT) 1 << (min (VALBITS, BITS_PER_INT) - 1)) - 1
531: - nbytes_added))
532: error ("Buffer exceeds maximum size");
533:
534: enlarge_buffer_text (current_buffer, nbytes_added);
535:
536:
537: tem = Vinhibit_quit;
538: Vinhibit_quit = Qt;
539:
540: real_gap_loc = GPT;
541: real_gap_loc_byte = GPT_BYTE;
542: old_gap_size = GAP_SIZE;
543:
544:
545: GPT = Z + GAP_SIZE;
546: GPT_BYTE = Z_BYTE + GAP_SIZE;
547: GAP_SIZE = nbytes_added;
548:
549:
550:
551: gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1);
552:
553:
554: GAP_SIZE += old_gap_size;
555: GPT = real_gap_loc;
556: GPT_BYTE = real_gap_loc_byte;
557:
558:
559: *(Z_ADDR) = 0;
560:
561: Vinhibit_quit = tem;
562: }
563:
564:
565:
566:
567: void
568: make_gap_smaller (nbytes_removed)
569: int nbytes_removed;
570: {
571: Lisp_Object tem;
572: int real_gap_loc;
573: int real_gap_loc_byte;
574: int real_Z;
575: int real_Z_byte;
576: int real_beg_unchanged;
577: int new_gap_size;
578:
579:
580: if (GAP_SIZE - nbytes_removed < 20)
581: nbytes_removed = GAP_SIZE - 20;
582:
583:
584: tem = Vinhibit_quit;
585: Vinhibit_quit = Qt;
586:
587: real_gap_loc = GPT;
588: real_gap_loc_byte = GPT_BYTE;
589: new_gap_size = GAP_SIZE - nbytes_removed;
590: real_Z = Z;
591: real_Z_byte = Z_BYTE;
592: real_beg_unchanged = BEG_UNCHANGED;
593:
594:
595:
596:
597: bzero (GPT_ADDR, new_gap_size);
598: GPT += new_gap_size;
599: GPT_BYTE += new_gap_size;
600: Z += new_gap_size;
601: Z_BYTE += new_gap_size;
602: GAP_SIZE = nbytes_removed;
603:
604:
605:
606: gap_right (Z, Z_BYTE);
607:
608: enlarge_buffer_text (current_buffer, -nbytes_removed);
609:
610:
611: GAP_SIZE = new_gap_size;
612: GPT = real_gap_loc;
613: GPT_BYTE = real_gap_loc_byte;
614: Z = real_Z;
615: Z_BYTE = real_Z_byte;
616: BEG_UNCHANGED = real_beg_unchanged;
617:
618:
619: *(Z_ADDR) = 0;
620:
621: Vinhibit_quit = tem;
622: }
623:
624: void
625: make_gap (nbytes_added)
626: int nbytes_added;
627: {
628: if (nbytes_added >= 0)
629: make_gap_larger (