aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmitry Antipov2013-08-06 09:30:18 +0400
committerDmitry Antipov2013-08-06 09:30:18 +0400
commit00012b86257f33dd4e08e79b814f4a7ad6010713 (patch)
tree1f01b7ccab453278d5e697ae2bf3dd34cd119a48 /src
parent307764cc3a2afd363cae0a36a6d18dfa68788cb4 (diff)
downloademacs-00012b86257f33dd4e08e79b814f4a7ad6010713.tar.gz
emacs-00012b86257f33dd4e08e79b814f4a7ad6010713.zip
Invalidate region caches only if buffer text is going to be changed.
* lisp.h (modify_region_1): Remove 3rd arg and rename to... (modify_text): ...new prototype. (prepare_to_modify_buffer_1): New prototype. * textprop.c (modify_region): Rename to... (modify_text_properties): ...new function. (add_text_properties_1, set_text_properties, Fremove_text_properties) (Fremove_list_of_text_properties): Adjust users. * insdel.c (modify_region_1): Remove 3rd arg and reimplement as... (modify_text): ...new function. (prepare_to_modify_buffer): Reimplement mostly as a wrapper for... (prepare_to_modify_buffer_1): ...new function. * casefiddle.c (casify_region): * editfns.c (Fsubst_char_in_region, Ftranslate_region_internal) (Ftranspose_regions): Use modify_text.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog18
-rw-r--r--src/casefiddle.c2
-rw-r--r--src/editfns.c14
-rw-r--r--src/insdel.c32
-rw-r--r--src/lisp.h3
-rw-r--r--src/textprop.c41
6 files changed, 72 insertions, 38 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 35b5c1cfe5c..7b7d9b56cb5 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,21 @@
12013-08-06 Dmitry Antipov <dmantipov@yandex.ru>
2
3 Invalidate region caches only if buffer text is going to be changed.
4 * lisp.h (modify_region_1): Remove 3rd arg and rename to...
5 (modify_text): ...new prototype.
6 (prepare_to_modify_buffer_1): New prototype.
7 * textprop.c (modify_region): Rename to...
8 (modify_text_properties): ...new function.
9 (add_text_properties_1, set_text_properties, Fremove_text_properties)
10 (Fremove_list_of_text_properties): Adjust users.
11 * insdel.c (modify_region_1): Remove 3rd arg and reimplement as...
12 (modify_text): ...new function.
13 (prepare_to_modify_buffer): Reimplement mostly as a wrapper for...
14 (prepare_to_modify_buffer_1): ...new function.
15 * casefiddle.c (casify_region):
16 * editfns.c (Fsubst_char_in_region, Ftranslate_region_internal)
17 (Ftranspose_regions): Use modify_text.
18
12013-08-05 Stefan Monnier <monnier@iro.umontreal.ca> 192013-08-05 Stefan Monnier <monnier@iro.umontreal.ca>
2 20
3 * lisp.mk (lisp): Add nadvice.elc. 21 * lisp.mk (lisp): Add nadvice.elc.
diff --git a/src/casefiddle.c b/src/casefiddle.c
index 7f5b99752fa..5a40790f87f 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -214,7 +214,7 @@ casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e)
214 validate_region (&b, &e); 214 validate_region (&b, &e);
215 start = XFASTINT (b); 215 start = XFASTINT (b);
216 end = XFASTINT (e); 216 end = XFASTINT (e);
217 modify_region_1 (start, end, false); 217 modify_text (start, end);
218 record_change (start, end - start); 218 record_change (start, end - start);
219 start_byte = CHAR_TO_BYTE (start); 219 start_byte = CHAR_TO_BYTE (start);
220 220
diff --git a/src/editfns.c b/src/editfns.c
index 50bde90788d..90346a88eb2 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -2928,7 +2928,7 @@ Both characters must have the same length of multi-byte form. */)
2928 else if (!changed) 2928 else if (!changed)
2929 { 2929 {
2930 changed = -1; 2930 changed = -1;
2931 modify_region_1 (pos, XINT (end), false); 2931 modify_text (pos, XINT (end));
2932 2932
2933 if (! NILP (noundo)) 2933 if (! NILP (noundo))
2934 { 2934 {
@@ -3104,7 +3104,7 @@ It returns the number of characters changed. */)
3104 pos = XINT (start); 3104 pos = XINT (start);
3105 pos_byte = CHAR_TO_BYTE (pos); 3105 pos_byte = CHAR_TO_BYTE (pos);
3106 end_pos = XINT (end); 3106 end_pos = XINT (end);
3107 modify_region_1 (pos, end_pos, false); 3107 modify_text (pos, end_pos);
3108 3108
3109 cnt = 0; 3109 cnt = 0;
3110 for (; pos < end_pos; ) 3110 for (; pos < end_pos; )
@@ -4615,7 +4615,7 @@ Transposing beyond buffer boundaries is an error. */)
4615 4615
4616 if (end1 == start2) /* adjacent regions */ 4616 if (end1 == start2) /* adjacent regions */
4617 { 4617 {
4618 modify_region_1 (start1, end2, false); 4618 modify_text (start1, end2);
4619 record_change (start1, len1 + len2); 4619 record_change (start1, len1 + len2);
4620 4620
4621 tmp_interval1 = copy_intervals (cur_intv, start1, len1); 4621 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
@@ -4674,8 +4674,8 @@ Transposing beyond buffer boundaries is an error. */)
4674 { 4674 {
4675 USE_SAFE_ALLOCA; 4675 USE_SAFE_ALLOCA;
4676 4676
4677 modify_region_1 (start1, end1, false); 4677 modify_text (start1, end1);
4678 modify_region_1 (start2, end2, false); 4678 modify_text (start2, end2);
4679 record_change (start1, len1); 4679 record_change (start1, len1);
4680 record_change (start2, len2); 4680 record_change (start2, len2);
4681 tmp_interval1 = copy_intervals (cur_intv, start1, len1); 4681 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
@@ -4708,7 +4708,7 @@ Transposing beyond buffer boundaries is an error. */)
4708 { 4708 {
4709 USE_SAFE_ALLOCA; 4709 USE_SAFE_ALLOCA;
4710 4710
4711 modify_region_1 (start1, end2, false); 4711 modify_text (start1, end2);
4712 record_change (start1, (end2 - start1)); 4712 record_change (start1, (end2 - start1));
4713 tmp_interval1 = copy_intervals (cur_intv, start1, len1); 4713 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
4714 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); 4714 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
@@ -4741,7 +4741,7 @@ Transposing beyond buffer boundaries is an error. */)
4741 USE_SAFE_ALLOCA; 4741 USE_SAFE_ALLOCA;
4742 4742
4743 record_change (start1, (end2 - start1)); 4743 record_change (start1, (end2 - start1));
4744 modify_region_1 (start1, end2, false); 4744 modify_text (start1, end2);
4745 4745
4746 tmp_interval1 = copy_intervals (cur_intv, start1, len1); 4746 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
4747 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); 4747 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
diff --git a/src/insdel.c b/src/insdel.c
index 58c3e15c233..ac64299a997 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -1756,27 +1756,22 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte,
1756 return deletion; 1756 return deletion;
1757} 1757}
1758 1758
1759/* Call this if you're about to change the region of current buffer 1759/* Call this if you're about to change the text of current buffer
1760 from character positions START to END. This checks the read-only 1760 from character positions START to END. This checks the read-only
1761 properties of the region, calls the necessary modification hooks, 1761 properties of the region, calls the necessary modification hooks,
1762 and warns the next redisplay that it should pay attention to that 1762 and warns the next redisplay that it should pay attention to that
1763 area. 1763 area. */
1764
1765 If PRESERVE_CHARS_MODIFF, do not update CHARS_MODIFF.
1766 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
1767 1764
1768void 1765void
1769modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff) 1766modify_text (ptrdiff_t start, ptrdiff_t end)
1770{ 1767{
1771 prepare_to_modify_buffer (start, end, NULL); 1768 prepare_to_modify_buffer (start, end, NULL);
1772 1769
1773 BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end); 1770 BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end);
1774
1775 if (MODIFF <= SAVE_MODIFF) 1771 if (MODIFF <= SAVE_MODIFF)
1776 record_first_change (); 1772 record_first_change ();
1777 MODIFF++; 1773 MODIFF++;
1778 if (! preserve_chars_modiff) 1774 CHARS_MODIFF = MODIFF;
1779 CHARS_MODIFF = MODIFF;
1780 1775
1781 bset_point_before_scroll (current_buffer, Qnil); 1776 bset_point_before_scroll (current_buffer, Qnil);
1782} 1777}
@@ -1792,8 +1787,8 @@ modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff)
1792 by holding its value temporarily in a marker. */ 1787 by holding its value temporarily in a marker. */
1793 1788
1794void 1789void
1795prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, 1790prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end,
1796 ptrdiff_t *preserve_ptr) 1791 ptrdiff_t *preserve_ptr)
1797{ 1792{
1798 struct buffer *base_buffer; 1793 struct buffer *base_buffer;
1799 1794
@@ -1864,6 +1859,17 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
1864 } 1859 }
1865 1860
1866 signal_before_change (start, end, preserve_ptr); 1861 signal_before_change (start, end, preserve_ptr);
1862 Vdeactivate_mark = Qt;
1863}
1864
1865/* Like above, but called when we know that the buffer text
1866 will be modified and region caches should be invalidated. */
1867
1868void
1869prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
1870 ptrdiff_t *preserve_ptr)
1871{
1872 prepare_to_modify_buffer_1 (start, end, preserve_ptr);
1867 1873
1868 if (current_buffer->newline_cache) 1874 if (current_buffer->newline_cache)
1869 invalidate_region_cache (current_buffer, 1875 invalidate_region_cache (current_buffer,
@@ -1873,10 +1879,8 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
1873 invalidate_region_cache (current_buffer, 1879 invalidate_region_cache (current_buffer,
1874 current_buffer->width_run_cache, 1880 current_buffer->width_run_cache,
1875 start - BEG, Z - end); 1881 start - BEG, Z - end);
1876
1877 Vdeactivate_mark = Qt;
1878} 1882}
1879 1883
1880/* These macros work with an argument named `preserve_ptr' 1884/* These macros work with an argument named `preserve_ptr'
1881 and a local variable named `preserve_marker'. */ 1885 and a local variable named `preserve_marker'. */
1882 1886
diff --git a/src/lisp.h b/src/lisp.h
index 085acb54348..8ca6d05a821 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3370,8 +3370,9 @@ extern void del_range_byte (ptrdiff_t, ptrdiff_t, bool);
3370extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); 3370extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool);
3371extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, 3371extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t,
3372 ptrdiff_t, ptrdiff_t, bool); 3372 ptrdiff_t, ptrdiff_t, bool);
3373extern void modify_region_1 (ptrdiff_t, ptrdiff_t, bool); 3373extern void modify_text (ptrdiff_t, ptrdiff_t);
3374extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); 3374extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *);
3375extern void prepare_to_modify_buffer_1 (ptrdiff_t, ptrdiff_t, ptrdiff_t *);
3375extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); 3376extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t);
3376extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, 3377extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t,
3377 ptrdiff_t, ptrdiff_t); 3378 ptrdiff_t, ptrdiff_t);
diff --git a/src/textprop.c b/src/textprop.c
index 282ae11d4ac..b804f345047 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -93,15 +93,25 @@ text_read_only (Lisp_Object propval)
93 xsignal0 (Qtext_read_only); 93 xsignal0 (Qtext_read_only);
94} 94}
95 95
96/* Prepare to modify the region of BUFFER from START to END. */ 96/* Prepare to modify the text properties of BUFFER from START to END. */
97 97
98static void 98static void
99modify_region (Lisp_Object buffer, Lisp_Object start, Lisp_Object end) 99modify_text_properties (Lisp_Object buffer, Lisp_Object start, Lisp_Object end)
100{ 100{
101 ptrdiff_t b = XINT (start), e = XINT (end);
101 struct buffer *buf = XBUFFER (buffer), *old = current_buffer; 102 struct buffer *buf = XBUFFER (buffer), *old = current_buffer;
102 103
103 set_buffer_internal (buf); 104 set_buffer_internal (buf);
104 modify_region_1 (XINT (start), XINT (end), true); 105
106 prepare_to_modify_buffer_1 (b, e, NULL);
107
108 BUF_COMPUTE_UNCHANGED (buf, b - 1, e);
109 if (MODIFF <= SAVE_MODIFF)
110 record_first_change ();
111 MODIFF++;
112
113 bset_point_before_scroll (current_buffer, Qnil);
114
105 set_buffer_internal (old); 115 set_buffer_internal (old);
106} 116}
107 117
@@ -1213,9 +1223,9 @@ add_text_properties_1 (Lisp_Object start, Lisp_Object end,
1213 ptrdiff_t prev_total_length = TOTAL_LENGTH (i); 1223 ptrdiff_t prev_total_length = TOTAL_LENGTH (i);
1214 ptrdiff_t prev_pos = i->position; 1224 ptrdiff_t prev_pos = i->position;
1215 1225
1216 modify_region (object, start, end); 1226 modify_text_properties (object, start, end);
1217 /* If someone called us recursively as a side effect of 1227 /* If someone called us recursively as a side effect of
1218 modify_region, and changed the intervals behind our back 1228 modify_text_properties, and changed the intervals behind our back
1219 (could happen if lock_file, called by prepare_to_modify_buffer, 1229 (could happen if lock_file, called by prepare_to_modify_buffer,
1220 triggers redisplay, and that calls add-text-properties again 1230 triggers redisplay, and that calls add-text-properties again
1221 in the same buffer), we cannot continue with I, because its 1231 in the same buffer), we cannot continue with I, because its
@@ -1357,7 +1367,8 @@ into it. */)
1357 otherwise. */ 1367 otherwise. */
1358 1368
1359Lisp_Object 1369Lisp_Object
1360set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object object, Lisp_Object coherent_change_p) 1370set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties,
1371 Lisp_Object object, Lisp_Object coherent_change_p)
1361{ 1372{
1362 register INTERVAL i; 1373 register INTERVAL i;
1363 Lisp_Object ostart, oend; 1374 Lisp_Object ostart, oend;
@@ -1403,7 +1414,7 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties,
1403 } 1414 }
1404 1415
1405 if (BUFFERP (object) && !NILP (coherent_change_p)) 1416 if (BUFFERP (object) && !NILP (coherent_change_p))
1406 modify_region (object, start, end); 1417 modify_text_properties (object, start, end);
1407 1418
1408 set_text_properties_1 (start, end, properties, object, i); 1419 set_text_properties_1 (start, end, properties, object, i);
1409 1420
@@ -1558,9 +1569,9 @@ Use `set-text-properties' if you want to remove all text properties. */)
1558 ptrdiff_t prev_total_length = TOTAL_LENGTH (i); 1569 ptrdiff_t prev_total_length = TOTAL_LENGTH (i);
1559 ptrdiff_t prev_pos = i->position; 1570 ptrdiff_t prev_pos = i->position;
1560 1571
1561 modify_region (object, start, end); 1572 modify_text_properties (object, start, end);
1562 /* If someone called us recursively as a side effect of 1573 /* If someone called us recursively as a side effect of
1563 modify_region, and changed the intervals behind our back 1574 modify_text_properties, and changed the intervals behind our back
1564 (could happen if lock_file, called by prepare_to_modify_buffer, 1575 (could happen if lock_file, called by prepare_to_modify_buffer,
1565 triggers redisplay, and that calls add-text-properties again 1576 triggers redisplay, and that calls add-text-properties again
1566 in the same buffer), we cannot continue with I, because its 1577 in the same buffer), we cannot continue with I, because its
@@ -1667,9 +1678,9 @@ Return t if any property was actually removed, nil otherwise. */)
1667 1678
1668 /* We are at the beginning of an interval, with len to scan. 1679 /* We are at the beginning of an interval, with len to scan.
1669 The flag `modified' records if changes have been made. 1680 The flag `modified' records if changes have been made.
1670 When object is a buffer, we must call modify_region before changes are 1681 When object is a buffer, we must call modify_text_properties
1671 made and signal_after_change when we are done. 1682 before changes are made and signal_after_change when we are done.
1672 We call modify_region before calling remove_properties if modified == 0, 1683 We call modify_text_properties before calling remove_properties if modified == 0,
1673 and we call signal_after_change before returning if modified != 0. */ 1684 and we call signal_after_change before returning if modified != 0. */
1674 for (;;) 1685 for (;;)
1675 { 1686 {
@@ -1693,7 +1704,7 @@ Return t if any property was actually removed, nil otherwise. */)
1693 else if (LENGTH (i) == len) 1704 else if (LENGTH (i) == len)
1694 { 1705 {
1695 if (!modified && BUFFERP (object)) 1706 if (!modified && BUFFERP (object))
1696 modify_region (object, start, end); 1707 modify_text_properties (object, start, end);
1697 remove_properties (Qnil, properties, i, object); 1708 remove_properties (Qnil, properties, i, object);
1698 if (BUFFERP (object)) 1709 if (BUFFERP (object))
1699 signal_after_change (XINT (start), XINT (end) - XINT (start), 1710 signal_after_change (XINT (start), XINT (end) - XINT (start),
@@ -1706,7 +1717,7 @@ Return t if any property was actually removed, nil otherwise. */)
1706 i = split_interval_left (i, len); 1717 i = split_interval_left (i, len);
1707 copy_properties (unchanged, i); 1718 copy_properties (unchanged, i);
1708 if (!modified && BUFFERP (object)) 1719 if (!modified && BUFFERP (object))
1709 modify_region (object, start, end); 1720 modify_text_properties (object, start, end);
1710 remove_properties (Qnil, properties, i, object); 1721 remove_properties (Qnil, properties, i, object);
1711 if (BUFFERP (object)) 1722 if (BUFFERP (object))
1712 signal_after_change (XINT (start), XINT (end) - XINT (start), 1723 signal_after_change (XINT (start), XINT (end) - XINT (start),
@@ -1717,7 +1728,7 @@ Return t if any property was actually removed, nil otherwise. */)
1717 if (interval_has_some_properties_list (properties, i)) 1728 if (interval_has_some_properties_list (properties, i))
1718 { 1729 {
1719 if (!modified && BUFFERP (object)) 1730 if (!modified && BUFFERP (object))
1720 modify_region (object, start, end); 1731 modify_text_properties (object, start, end);
1721 remove_properties (Qnil, properties, i, object); 1732 remove_properties (Qnil, properties, i, object);
1722 modified = 1; 1733 modified = 1;
1723 } 1734 }