+2014-01-01 Eli Zaretskii <eliz@gnu.org>
+
+ * 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 <rudalics@gmx.at>
* window.c (grow_mini_window): Fix last change.
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;
}
}
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
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;
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);
/* 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);
/* 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;
}
}
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
/* 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
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. */
(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. */
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;
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,
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;
}
}
{
struct region_cache *newline_cache;
int direction;
+ struct buffer *cache_buffer;
if (count > 0)
{
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;
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;
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. */
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;
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. */
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);
}
}