summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Antipov <dmantipov@yandex.ru>2013-08-06 09:30:18 +0400
committerDmitry Antipov <dmantipov@yandex.ru>2013-08-06 09:30:18 +0400
commit00012b86257f33dd4e08e79b814f4a7ad6010713 (patch)
tree1f01b7ccab453278d5e697ae2bf3dd34cd119a48
parent307764cc3a2afd363cae0a36a6d18dfa68788cb4 (diff)
downloademacs-00012b86257f33dd4e08e79b814f4a7ad6010713.tar.gz
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.
-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 @@
+2013-08-06 Dmitry Antipov <dmantipov@yandex.ru>
+
+ 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.
+
2013-08-05 Stefan Monnier <monnier@iro.umontreal.ca>
* 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)
validate_region (&b, &e);
start = XFASTINT (b);
end = XFASTINT (e);
- modify_region_1 (start, end, false);
+ modify_text (start, end);
record_change (start, end - start);
start_byte = CHAR_TO_BYTE (start);
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. */)
else if (!changed)
{
changed = -1;
- modify_region_1 (pos, XINT (end), false);
+ modify_text (pos, XINT (end));
if (! NILP (noundo))
{
@@ -3104,7 +3104,7 @@ It returns the number of characters changed. */)
pos = XINT (start);
pos_byte = CHAR_TO_BYTE (pos);
end_pos = XINT (end);
- modify_region_1 (pos, end_pos, false);
+ modify_text (pos, end_pos);
cnt = 0;
for (; pos < end_pos; )
@@ -4615,7 +4615,7 @@ Transposing beyond buffer boundaries is an error. */)
if (end1 == start2) /* adjacent regions */
{
- modify_region_1 (start1, end2, false);
+ modify_text (start1, end2);
record_change (start1, len1 + len2);
tmp_interval1 = copy_intervals (cur_intv, start1, len1);
@@ -4674,8 +4674,8 @@ Transposing beyond buffer boundaries is an error. */)
{
USE_SAFE_ALLOCA;
- modify_region_1 (start1, end1, false);
- modify_region_1 (start2, end2, false);
+ modify_text (start1, end1);
+ modify_text (start2, end2);
record_change (start1, len1);
record_change (start2, len2);
tmp_interval1 = copy_intervals (cur_intv, start1, len1);
@@ -4708,7 +4708,7 @@ Transposing beyond buffer boundaries is an error. */)
{
USE_SAFE_ALLOCA;
- modify_region_1 (start1, end2, false);
+ modify_text (start1, end2);
record_change (start1, (end2 - start1));
tmp_interval1 = copy_intervals (cur_intv, start1, len1);
tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
@@ -4741,7 +4741,7 @@ Transposing beyond buffer boundaries is an error. */)
USE_SAFE_ALLOCA;
record_change (start1, (end2 - start1));
- modify_region_1 (start1, end2, false);
+ modify_text (start1, end2);
tmp_interval1 = copy_intervals (cur_intv, start1, len1);
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,
return deletion;
}
-/* Call this if you're about to change the region of current buffer
+/* Call this if you're about to change the text of current buffer
from character positions START to END. This checks the read-only
properties of the region, calls the necessary modification hooks,
and warns the next redisplay that it should pay attention to that
- area.
-
- If PRESERVE_CHARS_MODIFF, do not update CHARS_MODIFF.
- Otherwise set CHARS_MODIFF to the new value of MODIFF. */
+ area. */
void
-modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff)
+modify_text (ptrdiff_t start, ptrdiff_t end)
{
prepare_to_modify_buffer (start, end, NULL);
BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end);
-
if (MODIFF <= SAVE_MODIFF)
record_first_change ();
MODIFF++;
- if (! preserve_chars_modiff)
- CHARS_MODIFF = MODIFF;
+ CHARS_MODIFF = MODIFF;
bset_point_before_scroll (current_buffer, Qnil);
}
@@ -1792,8 +1787,8 @@ modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff)
by holding its value temporarily in a marker. */
void
-prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
- ptrdiff_t *preserve_ptr)
+prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end,
+ ptrdiff_t *preserve_ptr)
{
struct buffer *base_buffer;
@@ -1864,6 +1859,17 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
}
signal_before_change (start, end, preserve_ptr);
+ Vdeactivate_mark = Qt;
+}
+
+/* Like above, but called when we know that the buffer text
+ will be modified and region caches should be invalidated. */
+
+void
+prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
+ ptrdiff_t *preserve_ptr)
+{
+ prepare_to_modify_buffer_1 (start, end, preserve_ptr);
if (current_buffer->newline_cache)
invalidate_region_cache (current_buffer,
@@ -1873,10 +1879,8 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
invalidate_region_cache (current_buffer,
current_buffer->width_run_cache,
start - BEG, Z - end);
-
- Vdeactivate_mark = Qt;
}
-
+
/* These macros work with an argument named `preserve_ptr'
and a local variable named `preserve_marker'. */
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);
extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool);
extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t,
ptrdiff_t, ptrdiff_t, bool);
-extern void modify_region_1 (ptrdiff_t, ptrdiff_t, bool);
+extern void modify_text (ptrdiff_t, ptrdiff_t);
extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *);
+extern void prepare_to_modify_buffer_1 (ptrdiff_t, ptrdiff_t, ptrdiff_t *);
extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t);
extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t,
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)
xsignal0 (Qtext_read_only);
}
-/* Prepare to modify the region of BUFFER from START to END. */
+/* Prepare to modify the text properties of BUFFER from START to END. */
static void
-modify_region (Lisp_Object buffer, Lisp_Object start, Lisp_Object end)
+modify_text_properties (Lisp_Object buffer, Lisp_Object start, Lisp_Object end)
{
+ ptrdiff_t b = XINT (start), e = XINT (end);
struct buffer *buf = XBUFFER (buffer), *old = current_buffer;
set_buffer_internal (buf);
- modify_region_1 (XINT (start), XINT (end), true);
+
+ prepare_to_modify_buffer_1 (b, e, NULL);
+
+ BUF_COMPUTE_UNCHANGED (buf, b - 1, e);
+ if (MODIFF <= SAVE_MODIFF)
+ record_first_change ();
+ MODIFF++;
+
+ bset_point_before_scroll (current_buffer, Qnil);
+
set_buffer_internal (old);
}
@@ -1213,9 +1223,9 @@ add_text_properties_1 (Lisp_Object start, Lisp_Object end,
ptrdiff_t prev_total_length = TOTAL_LENGTH (i);
ptrdiff_t prev_pos = i->position;
- modify_region (object, start, end);
+ modify_text_properties (object, start, end);
/* If someone called us recursively as a side effect of
- modify_region, and changed the intervals behind our back
+ modify_text_properties, and changed the intervals behind our back
(could happen if lock_file, called by prepare_to_modify_buffer,
triggers redisplay, and that calls add-text-properties again
in the same buffer), we cannot continue with I, because its
@@ -1357,7 +1367,8 @@ into it. */)
otherwise. */
Lisp_Object
-set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties, Lisp_Object object, Lisp_Object coherent_change_p)
+set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties,
+ Lisp_Object object, Lisp_Object coherent_change_p)
{
register INTERVAL i;
Lisp_Object ostart, oend;
@@ -1403,7 +1414,7 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties,
}
if (BUFFERP (object) && !NILP (coherent_change_p))
- modify_region (object, start, end);
+ modify_text_properties (object, start, end);
set_text_properties_1 (start, end, properties, object, i);
@@ -1558,9 +1569,9 @@ Use `set-text-properties' if you want to remove all text properties. */)
ptrdiff_t prev_total_length = TOTAL_LENGTH (i);
ptrdiff_t prev_pos = i->position;
- modify_region (object, start, end);
+ modify_text_properties (object, start, end);
/* If someone called us recursively as a side effect of
- modify_region, and changed the intervals behind our back
+ modify_text_properties, and changed the intervals behind our back
(could happen if lock_file, called by prepare_to_modify_buffer,
triggers redisplay, and that calls add-text-properties again
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. */)
/* We are at the beginning of an interval, with len to scan.
The flag `modified' records if changes have been made.
- When object is a buffer, we must call modify_region before changes are
- made and signal_after_change when we are done.
- We call modify_region before calling remove_properties if modified == 0,
+ When object is a buffer, we must call modify_text_properties
+ before changes are made and signal_after_change when we are done.
+ We call modify_text_properties before calling remove_properties if modified == 0,
and we call signal_after_change before returning if modified != 0. */
for (;;)
{
@@ -1693,7 +1704,7 @@ Return t if any property was actually removed, nil otherwise. */)
else if (LENGTH (i) == len)
{
if (!modified && BUFFERP (object))
- modify_region (object, start, end);
+ modify_text_properties (object, start, end);
remove_properties (Qnil, properties, i, object);
if (BUFFERP (object))
signal_after_change (XINT (start), XINT (end) - XINT (start),
@@ -1706,7 +1717,7 @@ Return t if any property was actually removed, nil otherwise. */)
i = split_interval_left (i, len);
copy_properties (unchanged, i);
if (!modified && BUFFERP (object))
- modify_region (object, start, end);
+ modify_text_properties (object, start, end);
remove_properties (Qnil, properties, i, object);
if (BUFFERP (object))
signal_after_change (XINT (start), XINT (end) - XINT (start),
@@ -1717,7 +1728,7 @@ Return t if any property was actually removed, nil otherwise. */)
if (interval_has_some_properties_list (properties, i))
{
if (!modified && BUFFERP (object))
- modify_region (object, start, end);
+ modify_text_properties (object, start, end);
remove_properties (Qnil, properties, i, object);
modified = 1;
}