aboutsummaryrefslogtreecommitdiffstats
path: root/src/insdel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/insdel.c')
-rw-r--r--src/insdel.c109
1 files changed, 49 insertions, 60 deletions
diff --git a/src/insdel.c b/src/insdel.c
index 87010cd8251..246ba80f290 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -1,6 +1,6 @@
1/* Buffer insertion/deletion and gap motion for GNU Emacs. 1/* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985-1986, 1993-1995, 1997-2012 2 Copyright (C) 1985-1986, 1993-1995, 1997-2013 Free Software
3 Free Software Foundation, Inc. 3 Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
6 6
@@ -84,21 +84,14 @@ check_markers (void)
84 84
85#endif /* MARKER_DEBUG */ 85#endif /* MARKER_DEBUG */
86 86
87/* Move gap to position CHARPOS.
88 Note that this can quit! */
89
90void
91move_gap (ptrdiff_t charpos)
92{
93 move_gap_both (charpos, charpos_to_bytepos (charpos));
94}
95
96/* Move gap to byte position BYTEPOS, which is also char position CHARPOS. 87/* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
97 Note that this can quit! */ 88 Note that this can quit! */
98 89
99void 90void
100move_gap_both (ptrdiff_t charpos, ptrdiff_t bytepos) 91move_gap_both (ptrdiff_t charpos, ptrdiff_t bytepos)
101{ 92{
93 eassert (charpos == BYTE_TO_CHAR (bytepos)
94 && bytepos == CHAR_TO_BYTE (charpos));
102 if (bytepos < GPT_BYTE) 95 if (bytepos < GPT_BYTE)
103 gap_left (charpos, bytepos, 0); 96 gap_left (charpos, bytepos, 0);
104 else if (bytepos > GPT_BYTE) 97 else if (bytepos > GPT_BYTE)
@@ -388,14 +381,13 @@ make_gap_larger (ptrdiff_t nbytes_added)
388 ptrdiff_t real_gap_loc_byte; 381 ptrdiff_t real_gap_loc_byte;
389 ptrdiff_t old_gap_size; 382 ptrdiff_t old_gap_size;
390 ptrdiff_t current_size = Z_BYTE - BEG_BYTE + GAP_SIZE; 383 ptrdiff_t current_size = Z_BYTE - BEG_BYTE + GAP_SIZE;
391 enum { enough_for_a_while = 2000 };
392 384
393 if (BUF_BYTES_MAX - current_size < nbytes_added) 385 if (BUF_BYTES_MAX - current_size < nbytes_added)
394 buffer_overflow (); 386 buffer_overflow ();
395 387
396 /* If we have to get more space, get enough to last a while; 388 /* If we have to get more space, get enough to last a while;
397 but do not exceed the maximum buffer size. */ 389 but do not exceed the maximum buffer size. */
398 nbytes_added = min (nbytes_added + enough_for_a_while, 390 nbytes_added = min (nbytes_added + GAP_BYTES_DFL,
399 BUF_BYTES_MAX - current_size); 391 BUF_BYTES_MAX - current_size);
400 392
401 enlarge_buffer_text (current_buffer, nbytes_added); 393 enlarge_buffer_text (current_buffer, nbytes_added);
@@ -413,8 +405,7 @@ make_gap_larger (ptrdiff_t nbytes_added)
413 GPT_BYTE = Z_BYTE + GAP_SIZE; 405 GPT_BYTE = Z_BYTE + GAP_SIZE;
414 GAP_SIZE = nbytes_added; 406 GAP_SIZE = nbytes_added;
415 407
416 /* Move the new gap down to be consecutive with the end of the old one. 408 /* Move the new gap down to be consecutive with the end of the old one. */
417 This adjusts the markers properly too. */
418 gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1); 409 gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1);
419 410
420 /* Now combine the two into one large gap. */ 411 /* Now combine the two into one large gap. */
@@ -443,9 +434,9 @@ make_gap_smaller (ptrdiff_t nbytes_removed)
443 ptrdiff_t real_beg_unchanged; 434 ptrdiff_t real_beg_unchanged;
444 ptrdiff_t new_gap_size; 435 ptrdiff_t new_gap_size;
445 436
446 /* Make sure the gap is at least 20 bytes. */ 437 /* Make sure the gap is at least GAP_BYTES_MIN bytes. */
447 if (GAP_SIZE - nbytes_removed < 20) 438 if (GAP_SIZE - nbytes_removed < GAP_BYTES_MIN)
448 nbytes_removed = GAP_SIZE - 20; 439 nbytes_removed = GAP_SIZE - GAP_BYTES_MIN;
449 440
450 /* Prevent quitting in move_gap. */ 441 /* Prevent quitting in move_gap. */
451 tem = Vinhibit_quit; 442 tem = Vinhibit_quit;
@@ -468,8 +459,7 @@ make_gap_smaller (ptrdiff_t nbytes_removed)
468 Z_BYTE += new_gap_size; 459 Z_BYTE += new_gap_size;
469 GAP_SIZE = nbytes_removed; 460 GAP_SIZE = nbytes_removed;
470 461
471 /* Move the unwanted pretend gap to the end of the buffer. This 462 /* Move the unwanted pretend gap to the end of the buffer. */
472 adjusts the markers properly too. */
473 gap_right (Z, Z_BYTE); 463 gap_right (Z, Z_BYTE);
474 464
475 enlarge_buffer_text (current_buffer, -nbytes_removed); 465 enlarge_buffer_text (current_buffer, -nbytes_removed);
@@ -500,7 +490,20 @@ make_gap (ptrdiff_t nbytes_added)
500 make_gap_smaller (-nbytes_added); 490 make_gap_smaller (-nbytes_added);
501#endif 491#endif
502} 492}
503 493
494/* Add NBYTES to B's gap. It's enough to temporarily
495 fake current_buffer and avoid real switch to B. */
496
497void
498make_gap_1 (struct buffer *b, ptrdiff_t nbytes)
499{
500 struct buffer *oldb = current_buffer;
501
502 current_buffer = b;
503 make_gap (nbytes);
504 current_buffer = oldb;
505}
506
504/* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR. 507/* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
505 FROM_MULTIBYTE says whether the incoming text is multibyte. 508 FROM_MULTIBYTE says whether the incoming text is multibyte.
506 TO_MULTIBYTE says whether to store the text as multibyte. 509 TO_MULTIBYTE says whether to store the text as multibyte.
@@ -655,17 +658,6 @@ insert_before_markers_and_inherit (const char *string,
655 } 658 }
656} 659}
657 660
658/* Subroutine used by the insert functions above. */
659
660void
661insert_1 (const char *string, ptrdiff_t nbytes,
662 bool inherit, bool prepare, bool before_markers)
663{
664 insert_1_both (string, chars_in_text ((unsigned char *) string, nbytes),
665 nbytes, inherit, prepare, before_markers);
666}
667
668
669#ifdef BYTE_COMBINING_DEBUG 661#ifdef BYTE_COMBINING_DEBUG
670 662
671/* See if the bytes before POS/POS_BYTE combine with bytes 663/* See if the bytes before POS/POS_BYTE combine with bytes
@@ -985,10 +977,11 @@ insert_from_string_1 (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
985} 977}
986 978
987/* Insert a sequence of NCHARS chars which occupy NBYTES bytes 979/* Insert a sequence of NCHARS chars which occupy NBYTES bytes
988 starting at GPT_ADDR. */ 980 starting at GAP_END_ADDR - NBYTES (if text_at_gap_tail) and at
981 GPT_ADDR (if not text_at_gap_tail). */
989 982
990void 983void
991insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes) 984insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail)
992{ 985{
993 if (NILP (BVAR (current_buffer, enable_multibyte_characters))) 986 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
994 nchars = nbytes; 987 nchars = nbytes;
@@ -997,10 +990,13 @@ insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes)
997 MODIFF++; 990 MODIFF++;
998 991
999 GAP_SIZE -= nbytes; 992 GAP_SIZE -= nbytes;
1000 GPT += nchars; 993 if (! text_at_gap_tail)
994 {
995 GPT += nchars;
996 GPT_BYTE += nbytes;
997 }
1001 ZV += nchars; 998 ZV += nchars;
1002 Z += nchars; 999 Z += nchars;
1003 GPT_BYTE += nbytes;
1004 ZV_BYTE += nbytes; 1000 ZV_BYTE += nbytes;
1005 Z_BYTE += nbytes; 1001 Z_BYTE += nbytes;
1006 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ 1002 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
@@ -1018,7 +1014,7 @@ insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes)
1018 current_buffer, 0); 1014 current_buffer, 0);
1019 } 1015 }
1020 1016
1021 if (GPT - nchars < PT) 1017 if (! text_at_gap_tail && GPT - nchars < PT)
1022 adjust_point (nchars, nbytes); 1018 adjust_point (nchars, nbytes);
1023 1019
1024 check_markers (); 1020 check_markers ();
@@ -1755,9 +1751,9 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte,
1755 1751
1756 return deletion; 1752 return deletion;
1757} 1753}
1758 1754
1759/* Call this if you're about to change the region of BUFFER from 1755/* Call this if you're about to change the region of current buffer
1760 character positions START to END. This checks the read-only 1756 from character positions START to END. This checks the read-only
1761 properties of the region, calls the necessary modification hooks, 1757 properties of the region, calls the necessary modification hooks,
1762 and warns the next redisplay that it should pay attention to that 1758 and warns the next redisplay that it should pay attention to that
1763 area. 1759 area.
@@ -1766,16 +1762,11 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte,
1766 Otherwise set CHARS_MODIFF to the new value of MODIFF. */ 1762 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
1767 1763
1768void 1764void
1769modify_region (struct buffer *buffer, ptrdiff_t start, ptrdiff_t end, 1765modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff)
1770 bool preserve_chars_modiff)
1771{ 1766{
1772 struct buffer *old_buffer = current_buffer;
1773
1774 set_buffer_internal (buffer);
1775
1776 prepare_to_modify_buffer (start, end, NULL); 1767 prepare_to_modify_buffer (start, end, NULL);
1777 1768
1778 BUF_COMPUTE_UNCHANGED (buffer, start - 1, end); 1769 BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end);
1779 1770
1780 if (MODIFF <= SAVE_MODIFF) 1771 if (MODIFF <= SAVE_MODIFF)
1781 record_first_change (); 1772 record_first_change ();
@@ -1783,11 +1774,9 @@ modify_region (struct buffer *buffer, ptrdiff_t start, ptrdiff_t end,
1783 if (! preserve_chars_modiff) 1774 if (! preserve_chars_modiff)
1784 CHARS_MODIFF = MODIFF; 1775 CHARS_MODIFF = MODIFF;
1785 1776
1786 bset_point_before_scroll (buffer, Qnil); 1777 bset_point_before_scroll (current_buffer, Qnil);
1787
1788 set_buffer_internal (old_buffer);
1789} 1778}
1790 1779
1791/* Check that it is okay to modify the buffer between START and END, 1780/* Check that it is okay to modify the buffer between START and END,
1792 which are char positions. 1781 which are char positions.
1793 1782
@@ -1807,9 +1796,10 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
1807 if (!NILP (BVAR (current_buffer, read_only))) 1796 if (!NILP (BVAR (current_buffer, read_only)))
1808 Fbarf_if_buffer_read_only (); 1797 Fbarf_if_buffer_read_only ();
1809 1798
1810 /* Let redisplay consider other windows than selected_window 1799 /* If we're modifying the buffer other than shown in a selected window,
1811 if modifying another buffer. */ 1800 let redisplay consider other windows if this buffer is visible. */
1812 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer) 1801 if (XBUFFER (XWINDOW (selected_window)->contents) != current_buffer
1802 && buffer_window_count (current_buffer))
1813 ++windows_or_buffers_changed; 1803 ++windows_or_buffers_changed;
1814 1804
1815 if (buffer_intervals (current_buffer)) 1805 if (buffer_intervals (current_buffer))
@@ -1861,7 +1851,7 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
1861 : (!NILP (Vselect_active_regions) 1851 : (!NILP (Vselect_active_regions)
1862 && !NILP (Vtransient_mark_mode)))) 1852 && !NILP (Vtransient_mark_mode))))
1863 { 1853 {
1864 ptrdiff_t b = XMARKER (BVAR (current_buffer, mark))->charpos; 1854 ptrdiff_t b = marker_position (BVAR (current_buffer, mark));
1865 ptrdiff_t e = PT; 1855 ptrdiff_t e = PT;
1866 if (b < e) 1856 if (b < e)
1867 Vsaved_region_selection = make_buffer_string (b, e, 0); 1857 Vsaved_region_selection = make_buffer_string (b, e, 0);
@@ -2027,9 +2017,8 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins)
2027 && current_buffer != XBUFFER (combine_after_change_buffer)) 2017 && current_buffer != XBUFFER (combine_after_change_buffer))
2028 Fcombine_after_change_execute (); 2018 Fcombine_after_change_execute ();
2029 2019
2030 elt = Fcons (make_number (charpos - BEG), 2020 elt = list3i (charpos - BEG, Z - (charpos - lendel + lenins),
2031 Fcons (make_number (Z - (charpos - lendel + lenins)), 2021 lenins - lendel);
2032 Fcons (make_number (lenins - lendel), Qnil)));
2033 combine_after_change_list 2022 combine_after_change_list
2034 = Fcons (elt, combine_after_change_list); 2023 = Fcons (elt, combine_after_change_list);
2035 combine_after_change_buffer = Fcurrent_buffer (); 2024 combine_after_change_buffer = Fcurrent_buffer ();
@@ -2087,7 +2076,7 @@ Fcombine_after_change_execute_1 (Lisp_Object val)
2087 2076
2088DEFUN ("combine-after-change-execute", Fcombine_after_change_execute, 2077DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
2089 Scombine_after_change_execute, 0, 0, 0, 2078 Scombine_after_change_execute, 0, 0, 0,
2090 doc: /* This function is for use internally in `combine-after-change-calls'. */) 2079 doc: /* This function is for use internally in the function `combine-after-change-calls'. */)
2091 (void) 2080 (void)
2092{ 2081{
2093 ptrdiff_t count = SPECPDL_INDEX (); 2082 ptrdiff_t count = SPECPDL_INDEX ();
@@ -2179,7 +2168,7 @@ syms_of_insdel (void)
2179 combine_after_change_buffer = Qnil; 2168 combine_after_change_buffer = Qnil;
2180 2169
2181 DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls, 2170 DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls,
2182 doc: /* Used internally by the `combine-after-change-calls' macro. */); 2171 doc: /* Used internally by the function `combine-after-change-calls' macro. */);
2183 Vcombine_after_change_calls = Qnil; 2172 Vcombine_after_change_calls = Qnil;
2184 2173
2185 DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks, 2174 DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks,