[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] trunk r115826: Fix bug #16265 with buffer caches when modi
From: |
Eli Zaretskii |
Subject: |
[Emacs-diffs] trunk r115826: Fix bug #16265 with buffer caches when modifying text in indirect buffers. |
Date: |
Wed, 01 Jan 2014 17:46:27 +0000 |
User-agent: |
Bazaar (2.6b2) |
------------------------------------------------------------
revno: 115826
revision-id: address@hidden
parent: address@hidden
fixes bug: http://debbugs.gnu.org/16265
committer: Eli Zaretskii <address@hidden>
branch nick: trunk
timestamp: Wed 2014-01-01 19:44:48 +0200
message:
Fix bug #16265 with buffer caches when modifying text in indirect buffers.
src/search.c (newline_cache_on_off, find_newline): In indirect
buffers, use the newline cache of the base buffer.
src/insdel.c (invalidate_buffer_caches): If BUF is an indirect
buffer, invalidate the caches of its base buffer.
src/indent.c (width_run_cache_on_off, compute_motion): In indirect
buffers, use the width-run cache of the base buffer.
src/xdisp.c (redisplay_window): When the window displays an indirect
buffer, and the character widths in the display table have
changed, invalidate the width-run cache of the corresponding base
buffer.
src/fileio.c (Finsert_file_contents): When invalidating the newline
cache, consider the case of inserting into indirect buffer.
src/bidi.c (bidi_paragraph_cache_on_off, bidi_find_paragraph_start):
In indirect buffers, use the paragraph cache of the base buffer.
modified:
src/ChangeLog changelog-20091113204419-o5vbwnq5f7feedwu-1438
src/bidi.c bidi.c-20091231194348-rm8gzug639w0dpq5-1
src/fileio.c fileio.c-20091113204419-o5vbwnq5f7feedwu-210
src/indent.c indent.c-20091113204419-o5vbwnq5f7feedwu-181
src/insdel.c insdel.c-20091113204419-o5vbwnq5f7feedwu-175
src/search.c search.c-20091113204419-o5vbwnq5f7feedwu-473
src/xdisp.c xdisp.c-20091113204419-o5vbwnq5f7feedwu-240
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog 2014-01-01 07:43:34 +0000
+++ b/src/ChangeLog 2014-01-01 17:44:48 +0000
@@ -1,3 +1,25 @@
+2014-01-01 Eli Zaretskii <address@hidden>
+
+ * search.c (newline_cache_on_off, find_newline): In indirect
+ buffers, use the newline cache of the base buffer.
+
+ * insdel.c (invalidate_buffer_caches): If BUF is an indirect
+ buffer, invalidate the caches of its base buffer. (Bug#16265)
+
+ * indent.c (width_run_cache_on_off, compute_motion): In indirect
+ buffers, use the width-run cache of the base buffer.
+
+ * xdisp.c (redisplay_window): When the window displays an indirect
+ buffer, and the character widths in the display table have
+ changed, invalidate the width-run cache of the corresponding base
+ buffer.
+
+ * fileio.c (Finsert_file_contents): When invalidating the newline
+ cache, consider the case of inserting into indirect buffer.
+
+ * bidi.c (bidi_paragraph_cache_on_off, bidi_find_paragraph_start):
+ In indirect buffers, use the paragraph cache of the base buffer.
+
2013-12-31 Martin Rudalics <address@hidden>
* window.c (grow_mini_window): Fix last change.
=== modified file 'src/bidi.c'
--- a/src/bidi.c 2014-01-01 07:43:34 +0000
+++ b/src/bidi.c 2014-01-01 17:44:48 +0000
@@ -1100,20 +1100,44 @@
static struct region_cache *
bidi_paragraph_cache_on_off (void)
{
+ struct buffer *cache_buffer = current_buffer;
+ bool indirect_p = false;
+
+ /* For indirect buffers, make sure to use the cache of their base
+ buffer. */
+ if (cache_buffer->base_buffer)
+ {
+ cache_buffer = cache_buffer->base_buffer;
+ indirect_p = true;
+ }
+
+ /* Don't turn on or off the cache in the base buffer, if the value
+ of cache-long-scans of the base buffer is inconsistent with that.
+ This is because doing so will just make the cache pure overhead,
+ since if we turn it on via indirect buffer, it will be
+ immediately turned off by its base buffer. */
if (NILP (BVAR (current_buffer, cache_long_scans)))
{
- if (current_buffer->bidi_paragraph_cache)
+ if (!indirect_p
+ || NILP (BVAR (cache_buffer, cache_long_scans)))
{
- free_region_cache (current_buffer->bidi_paragraph_cache);
- current_buffer->bidi_paragraph_cache = 0;
+ if (cache_buffer->bidi_paragraph_cache)
+ {
+ free_region_cache (cache_buffer->bidi_paragraph_cache);
+ cache_buffer->bidi_paragraph_cache = 0;
+ }
}
return NULL;
}
else
{
- if (!current_buffer->bidi_paragraph_cache)
- current_buffer->bidi_paragraph_cache = new_region_cache ();
- return current_buffer->bidi_paragraph_cache;
+ if (!indirect_p
+ || !NILP (BVAR (cache_buffer, cache_long_scans)))
+ {
+ if (!cache_buffer->bidi_paragraph_cache)
+ cache_buffer->bidi_paragraph_cache = new_region_cache ();
+ }
+ return cache_buffer->bidi_paragraph_cache;
}
}
@@ -1134,6 +1158,10 @@
ptrdiff_t limit = ZV, limit_byte = ZV_BYTE;
struct region_cache *bpc = bidi_paragraph_cache_on_off ();
ptrdiff_t n = 0, oldpos = pos, next;
+ struct buffer *cache_buffer = current_buffer;
+
+ if (cache_buffer->base_buffer)
+ cache_buffer = cache_buffer->base_buffer;
while (pos_byte > BEGV_BYTE
&& n++ < MAX_PARAGRAPH_SEARCH
@@ -1144,7 +1172,7 @@
of the text over which we scan back includes
paragraph_start_re? */
DEC_BOTH (pos, pos_byte);
- if (bpc && region_cache_backward (current_buffer, bpc, pos, &next))
+ if (bpc && region_cache_backward (cache_buffer, bpc, pos, &next))
{
pos = next, pos_byte = CHAR_TO_BYTE (pos);
break;
@@ -1155,7 +1183,7 @@
if (n >= MAX_PARAGRAPH_SEARCH)
pos = BEGV, pos_byte = BEGV_BYTE;
if (bpc)
- know_region_cache (current_buffer, bpc, pos, oldpos);
+ know_region_cache (cache_buffer, bpc, pos, oldpos);
/* Positions returned by the region cache are not limited to
BEGV..ZV range, so we limit them here. */
pos_byte = clip_to_bounds (BEGV_BYTE, pos_byte, ZV_BYTE);
=== modified file 'src/fileio.c'
--- a/src/fileio.c 2014-01-01 07:43:34 +0000
+++ b/src/fileio.c 2014-01-01 17:44:48 +0000
@@ -4496,7 +4496,11 @@
/* We made a lot of deletions and insertions above, so invalidate
the newline cache for the entire region of the inserted
characters. */
- if (current_buffer->newline_cache)
+ if (current_buffer->base_buffer &&
current_buffer->base_buffer->newline_cache)
+ invalidate_region_cache (current_buffer->base_buffer,
+ current_buffer->base_buffer->newline_cache,
+ PT - BEG, Z - PT - inserted);
+ else if (current_buffer->newline_cache)
invalidate_region_cache (current_buffer,
current_buffer->newline_cache,
PT - BEG, Z - PT - inserted);
=== modified file 'src/indent.c'
--- a/src/indent.c 2014-01-01 07:43:34 +0000
+++ b/src/indent.c 2014-01-01 17:44:48 +0000
@@ -144,30 +144,51 @@
/* Allocate or free the width run cache, as requested by the
current state of current_buffer's cache_long_scans variable. */
-static void
+static struct region_cache *
width_run_cache_on_off (void)
{
+ struct buffer *cache_buffer = current_buffer;
+ bool indirect_p = false;
+
+ if (cache_buffer->base_buffer)
+ {
+ cache_buffer = cache_buffer->base_buffer;
+ indirect_p = true;
+ }
+
if (NILP (BVAR (current_buffer, cache_long_scans))
/* And, for the moment, this feature doesn't work on multibyte
characters. */
|| !NILP (BVAR (current_buffer, enable_multibyte_characters)))
{
- /* It should be off. */
- if (current_buffer->width_run_cache)
- {
- free_region_cache (current_buffer->width_run_cache);
- current_buffer->width_run_cache = 0;
- bset_width_table (current_buffer, Qnil);
+ if (!indirect_p
+ || NILP (BVAR (cache_buffer, cache_long_scans))
+ || !NILP (BVAR (cache_buffer, enable_multibyte_characters)))
+ {
+ /* It should be off. */
+ if (cache_buffer->width_run_cache)
+ {
+ free_region_cache (cache_buffer->width_run_cache);
+ cache_buffer->width_run_cache = 0;
+ bset_width_table (current_buffer, Qnil);
+ }
}
+ return NULL;
}
else
{
- /* It should be on. */
- if (current_buffer->width_run_cache == 0)
- {
- current_buffer->width_run_cache = new_region_cache ();
- recompute_width_table (current_buffer, buffer_display_table ());
- }
+ if (!indirect_p
+ || (!NILP (BVAR (cache_buffer, cache_long_scans))
+ && NILP (BVAR (cache_buffer, enable_multibyte_characters))))
+ {
+ /* It should be on. */
+ if (cache_buffer->width_run_cache == 0)
+ {
+ cache_buffer->width_run_cache = new_region_cache ();
+ recompute_width_table (current_buffer, buffer_display_table ());
+ }
+ }
+ return cache_buffer->width_run_cache;
}
}
@@ -1128,12 +1149,16 @@
EMACS_INT contin_hpos; /* HPOS of last column of continued line. */
int prev_tab_offset; /* Previous tab offset. */
int continuation_glyph_width;
+ struct buffer *cache_buffer = current_buffer;
+ struct region_cache *width_cache;
struct composition_it cmp_it;
XSETWINDOW (window, win);
- width_run_cache_on_off ();
+ if (cache_buffer->base_buffer)
+ cache_buffer = cache_buffer->base_buffer;
+ width_cache = width_run_cache_on_off ();
if (dp == buffer_display_table ())
width_table = (VECTORP (BVAR (current_buffer, width_table))
? XVECTOR (BVAR (current_buffer, width_table))->contents
@@ -1404,13 +1429,11 @@
/* Consult the width run cache to see if we can avoid inspecting
the text character-by-character. */
- if (current_buffer->width_run_cache && pos >= next_width_run)
+ if (width_cache && pos >= next_width_run)
{
ptrdiff_t run_end;
int common_width
- = region_cache_forward (current_buffer,
- current_buffer->width_run_cache,
- pos, &run_end);
+ = region_cache_forward (cache_buffer, width_cache, pos, &run_end);
/* A width of zero means the character's width varies (like
a tab), is meaningless (like a newline), or we just don't
@@ -1486,7 +1509,7 @@
pos++, pos_byte++;
/* Perhaps add some info to the width_run_cache. */
- if (current_buffer->width_run_cache)
+ if (width_cache)
{
/* Is this character part of the current run? If so, extend
the run. */
@@ -1502,8 +1525,7 @@
(Currently, we only cache runs of width == 1). */
if (width_run_start < width_run_end
&& width_run_width == 1)
- know_region_cache (current_buffer,
- current_buffer->width_run_cache,
+ know_region_cache (cache_buffer, width_cache,
width_run_start, width_run_end);
/* Start recording a new width run. */
@@ -1639,10 +1661,10 @@
after_loop:
/* Remember any final width run in the cache. */
- if (current_buffer->width_run_cache
+ if (width_cache
&& width_run_width == 1
&& width_run_start < width_run_end)
- know_region_cache (current_buffer, current_buffer->width_run_cache,
+ know_region_cache (cache_buffer, width_cache,
width_run_start, width_run_end);
val_compute_motion.bufpos = pos;
=== modified file 'src/insdel.c'
--- a/src/insdel.c 2014-01-01 07:43:34 +0000
+++ b/src/insdel.c 2014-01-01 17:44:48 +0000
@@ -1878,6 +1878,10 @@
void
invalidate_buffer_caches (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
{
+ /* Indirect buffers usually have their caches set to NULL, but we
+ need to consider the caches of their base buffer. */
+ if (buf->base_buffer)
+ buf = buf->base_buffer;
if (buf->newline_cache)
invalidate_region_cache (buf,
buf->newline_cache,
=== modified file 'src/search.c'
--- a/src/search.c 2014-01-01 07:43:34 +0000
+++ b/src/search.c 2014-01-01 17:44:48 +0000
@@ -602,23 +602,47 @@
Otherwise, make sure it's off.
This is our cheezy way of associating an action with the change of
state of a buffer-local variable. */
-static void
+static struct region_cache *
newline_cache_on_off (struct buffer *buf)
{
+ struct buffer *base_buf = buf;
+ bool indirect_p = false;
+
+ if (buf->base_buffer)
+ {
+ base_buf = buf->base_buffer;
+ indirect_p = true;
+ }
+
+ /* Don't turn on or off the cache in the base buffer, if the value
+ of cache-long-scans of the base buffer is inconsistent with that.
+ This is because doing so will just make the cache pure overhead,
+ since if we turn it on via indirect buffer, it will be
+ immediately turned off by its base buffer. */
if (NILP (BVAR (buf, cache_long_scans)))
{
- /* It should be off. */
- if (buf->newline_cache)
- {
- free_region_cache (buf->newline_cache);
- buf->newline_cache = 0;
- }
+ if (!indirect_p
+ || NILP (BVAR (base_buf, cache_long_scans)))
+ {
+ /* It should be off. */
+ if (base_buf->newline_cache)
+ {
+ free_region_cache (base_buf->newline_cache);
+ base_buf->newline_cache = 0;
+ }
+ }
+ return NULL;
}
else
{
- /* It should be on. */
- if (buf->newline_cache == 0)
- buf->newline_cache = new_region_cache ();
+ if (!indirect_p
+ || !NILP (BVAR (base_buf, cache_long_scans)))
+ {
+ /* It should be on. */
+ if (base_buf->newline_cache == 0)
+ base_buf->newline_cache = new_region_cache ();
+ }
+ return base_buf->newline_cache;
}
}
@@ -653,6 +677,7 @@
{
struct region_cache *newline_cache;
int direction;
+ struct buffer *cache_buffer;
if (count > 0)
{
@@ -669,8 +694,11 @@
if (end_byte == -1)
end_byte = CHAR_TO_BYTE (end);
- newline_cache_on_off (current_buffer);
- newline_cache = current_buffer->newline_cache;
+ newline_cache = newline_cache_on_off (current_buffer);
+ if (current_buffer->base_buffer)
+ cache_buffer = current_buffer->base_buffer;
+ else
+ cache_buffer = current_buffer;
if (shortage != 0)
*shortage = 0;
@@ -694,7 +722,7 @@
ptrdiff_t next_change;
immediate_quit = 0;
while (region_cache_forward
- (current_buffer, newline_cache, start, &next_change))
+ (cache_buffer, newline_cache, start, &next_change))
start = next_change;
immediate_quit = allow_quit;
@@ -738,7 +766,7 @@
this line's region is free of them. */
if (newline_cache)
{
- know_region_cache (current_buffer, newline_cache,
+ know_region_cache (cache_buffer, newline_cache,
BYTE_TO_CHAR (lim_byte + cursor),
BYTE_TO_CHAR (lim_byte + next));
/* know_region_cache can relocate buffer text. */
@@ -774,7 +802,7 @@
ptrdiff_t next_change;
immediate_quit = 0;
while (region_cache_backward
- (current_buffer, newline_cache, start, &next_change))
+ (cache_buffer, newline_cache, start, &next_change))
start = next_change;
immediate_quit = allow_quit;
@@ -814,7 +842,7 @@
this line's region is free of them. */
if (newline_cache)
{
- know_region_cache (current_buffer, newline_cache,
+ know_region_cache (cache_buffer, newline_cache,
BYTE_TO_CHAR (ceiling_byte + prev + 1),
BYTE_TO_CHAR (ceiling_byte + cursor));
/* know_region_cache can relocate buffer text. */
=== modified file 'src/xdisp.c'
--- a/src/xdisp.c 2014-01-01 07:43:34 +0000
+++ b/src/xdisp.c 2014-01-01 17:44:48 +0000
@@ -15767,16 +15767,20 @@
this may be a bit late to catch such changes, but the rest of
redisplay goes (non-fatally) haywire when the display table is
changed, so why should we worry about doing any better? */
- if (current_buffer->width_run_cache)
+ if (current_buffer->width_run_cache
+ || (current_buffer->base_buffer
+ && current_buffer->base_buffer->width_run_cache))
{
struct Lisp_Char_Table *disptab = buffer_display_table ();
if (! disptab_matches_widthtab
(disptab, XVECTOR (BVAR (current_buffer, width_table))))
{
- invalidate_region_cache (current_buffer,
- current_buffer->width_run_cache,
- BEG, Z);
+ struct buffer *buf = current_buffer;
+
+ if (buf->base_buffer)
+ buf = buf->base_buffer;
+ invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
recompute_width_table (current_buffer, disptab);
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] trunk r115826: Fix bug #16265 with buffer caches when modifying text in indirect buffers.,
Eli Zaretskii <=