diff options
| author | Eli Zaretskii | 2014-01-01 19:44:48 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2014-01-01 19:44:48 +0200 |
| commit | c10e9ece08ab58bf0d49fd1554879c379f810748 (patch) | |
| tree | ce6e03c34ad81de47541c19272b617c64e8a5413 /src | |
| parent | 6bc383b1a4ebf46451085a1629a0e9433f2051cf (diff) | |
| download | emacs-c10e9ece08ab58bf0d49fd1554879c379f810748.tar.gz emacs-c10e9ece08ab58bf0d49fd1554879c379f810748.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 22 | ||||
| -rw-r--r-- | src/bidi.c | 44 | ||||
| -rw-r--r-- | src/fileio.c | 6 | ||||
| -rw-r--r-- | src/indent.c | 68 | ||||
| -rw-r--r-- | src/insdel.c | 4 | ||||
| -rw-r--r-- | src/search.c | 60 | ||||
| -rw-r--r-- | src/xdisp.c | 12 |
7 files changed, 164 insertions, 52 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 6ed13a11fe5..e41ccd168c6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,25 @@ | |||
| 1 | 2014-01-01 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * search.c (newline_cache_on_off, find_newline): In indirect | ||
| 4 | buffers, use the newline cache of the base buffer. | ||
| 5 | |||
| 6 | * insdel.c (invalidate_buffer_caches): If BUF is an indirect | ||
| 7 | buffer, invalidate the caches of its base buffer. (Bug#16265) | ||
| 8 | |||
| 9 | * indent.c (width_run_cache_on_off, compute_motion): In indirect | ||
| 10 | buffers, use the width-run cache of the base buffer. | ||
| 11 | |||
| 12 | * xdisp.c (redisplay_window): When the window displays an indirect | ||
| 13 | buffer, and the character widths in the display table have | ||
| 14 | changed, invalidate the width-run cache of the corresponding base | ||
| 15 | buffer. | ||
| 16 | |||
| 17 | * fileio.c (Finsert_file_contents): When invalidating the newline | ||
| 18 | cache, consider the case of inserting into indirect buffer. | ||
| 19 | |||
| 20 | * bidi.c (bidi_paragraph_cache_on_off, bidi_find_paragraph_start): | ||
| 21 | In indirect buffers, use the paragraph cache of the base buffer. | ||
| 22 | |||
| 1 | 2013-12-31 Martin Rudalics <rudalics@gmx.at> | 23 | 2013-12-31 Martin Rudalics <rudalics@gmx.at> |
| 2 | 24 | ||
| 3 | * window.c (grow_mini_window): Fix last change. | 25 | * window.c (grow_mini_window): Fix last change. |
diff --git a/src/bidi.c b/src/bidi.c index 18bbd030785..b96cc24bbd1 100644 --- a/src/bidi.c +++ b/src/bidi.c | |||
| @@ -1100,20 +1100,44 @@ bidi_at_paragraph_end (ptrdiff_t charpos, ptrdiff_t bytepos) | |||
| 1100 | static struct region_cache * | 1100 | static struct region_cache * |
| 1101 | bidi_paragraph_cache_on_off (void) | 1101 | bidi_paragraph_cache_on_off (void) |
| 1102 | { | 1102 | { |
| 1103 | struct buffer *cache_buffer = current_buffer; | ||
| 1104 | bool indirect_p = false; | ||
| 1105 | |||
| 1106 | /* For indirect buffers, make sure to use the cache of their base | ||
| 1107 | buffer. */ | ||
| 1108 | if (cache_buffer->base_buffer) | ||
| 1109 | { | ||
| 1110 | cache_buffer = cache_buffer->base_buffer; | ||
| 1111 | indirect_p = true; | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | /* Don't turn on or off the cache in the base buffer, if the value | ||
| 1115 | of cache-long-scans of the base buffer is inconsistent with that. | ||
| 1116 | This is because doing so will just make the cache pure overhead, | ||
| 1117 | since if we turn it on via indirect buffer, it will be | ||
| 1118 | immediately turned off by its base buffer. */ | ||
| 1103 | if (NILP (BVAR (current_buffer, cache_long_scans))) | 1119 | if (NILP (BVAR (current_buffer, cache_long_scans))) |
| 1104 | { | 1120 | { |
| 1105 | if (current_buffer->bidi_paragraph_cache) | 1121 | if (!indirect_p |
| 1122 | || NILP (BVAR (cache_buffer, cache_long_scans))) | ||
| 1106 | { | 1123 | { |
| 1107 | free_region_cache (current_buffer->bidi_paragraph_cache); | 1124 | if (cache_buffer->bidi_paragraph_cache) |
| 1108 | current_buffer->bidi_paragraph_cache = 0; | 1125 | { |
| 1126 | free_region_cache (cache_buffer->bidi_paragraph_cache); | ||
| 1127 | cache_buffer->bidi_paragraph_cache = 0; | ||
| 1128 | } | ||
| 1109 | } | 1129 | } |
| 1110 | return NULL; | 1130 | return NULL; |
| 1111 | } | 1131 | } |
| 1112 | else | 1132 | else |
| 1113 | { | 1133 | { |
| 1114 | if (!current_buffer->bidi_paragraph_cache) | 1134 | if (!indirect_p |
| 1115 | current_buffer->bidi_paragraph_cache = new_region_cache (); | 1135 | || !NILP (BVAR (cache_buffer, cache_long_scans))) |
| 1116 | return current_buffer->bidi_paragraph_cache; | 1136 | { |
| 1137 | if (!cache_buffer->bidi_paragraph_cache) | ||
| 1138 | cache_buffer->bidi_paragraph_cache = new_region_cache (); | ||
| 1139 | } | ||
| 1140 | return cache_buffer->bidi_paragraph_cache; | ||
| 1117 | } | 1141 | } |
| 1118 | } | 1142 | } |
| 1119 | 1143 | ||
| @@ -1134,6 +1158,10 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte) | |||
| 1134 | ptrdiff_t limit = ZV, limit_byte = ZV_BYTE; | 1158 | ptrdiff_t limit = ZV, limit_byte = ZV_BYTE; |
| 1135 | struct region_cache *bpc = bidi_paragraph_cache_on_off (); | 1159 | struct region_cache *bpc = bidi_paragraph_cache_on_off (); |
| 1136 | ptrdiff_t n = 0, oldpos = pos, next; | 1160 | ptrdiff_t n = 0, oldpos = pos, next; |
| 1161 | struct buffer *cache_buffer = current_buffer; | ||
| 1162 | |||
| 1163 | if (cache_buffer->base_buffer) | ||
| 1164 | cache_buffer = cache_buffer->base_buffer; | ||
| 1137 | 1165 | ||
| 1138 | while (pos_byte > BEGV_BYTE | 1166 | while (pos_byte > BEGV_BYTE |
| 1139 | && n++ < MAX_PARAGRAPH_SEARCH | 1167 | && n++ < MAX_PARAGRAPH_SEARCH |
| @@ -1144,7 +1172,7 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte) | |||
| 1144 | of the text over which we scan back includes | 1172 | of the text over which we scan back includes |
| 1145 | paragraph_start_re? */ | 1173 | paragraph_start_re? */ |
| 1146 | DEC_BOTH (pos, pos_byte); | 1174 | DEC_BOTH (pos, pos_byte); |
| 1147 | if (bpc && region_cache_backward (current_buffer, bpc, pos, &next)) | 1175 | if (bpc && region_cache_backward (cache_buffer, bpc, pos, &next)) |
| 1148 | { | 1176 | { |
| 1149 | pos = next, pos_byte = CHAR_TO_BYTE (pos); | 1177 | pos = next, pos_byte = CHAR_TO_BYTE (pos); |
| 1150 | break; | 1178 | break; |
| @@ -1155,7 +1183,7 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t pos_byte) | |||
| 1155 | if (n >= MAX_PARAGRAPH_SEARCH) | 1183 | if (n >= MAX_PARAGRAPH_SEARCH) |
| 1156 | pos = BEGV, pos_byte = BEGV_BYTE; | 1184 | pos = BEGV, pos_byte = BEGV_BYTE; |
| 1157 | if (bpc) | 1185 | if (bpc) |
| 1158 | know_region_cache (current_buffer, bpc, pos, oldpos); | 1186 | know_region_cache (cache_buffer, bpc, pos, oldpos); |
| 1159 | /* Positions returned by the region cache are not limited to | 1187 | /* Positions returned by the region cache are not limited to |
| 1160 | BEGV..ZV range, so we limit them here. */ | 1188 | BEGV..ZV range, so we limit them here. */ |
| 1161 | pos_byte = clip_to_bounds (BEGV_BYTE, pos_byte, ZV_BYTE); | 1189 | pos_byte = clip_to_bounds (BEGV_BYTE, pos_byte, ZV_BYTE); |
diff --git a/src/fileio.c b/src/fileio.c index 904a8d24dd8..5d8f3cb64f5 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -4496,7 +4496,11 @@ by calling `format-decode', which see. */) | |||
| 4496 | /* We made a lot of deletions and insertions above, so invalidate | 4496 | /* We made a lot of deletions and insertions above, so invalidate |
| 4497 | the newline cache for the entire region of the inserted | 4497 | the newline cache for the entire region of the inserted |
| 4498 | characters. */ | 4498 | characters. */ |
| 4499 | if (current_buffer->newline_cache) | 4499 | if (current_buffer->base_buffer && current_buffer->base_buffer->newline_cache) |
| 4500 | invalidate_region_cache (current_buffer->base_buffer, | ||
| 4501 | current_buffer->base_buffer->newline_cache, | ||
| 4502 | PT - BEG, Z - PT - inserted); | ||
| 4503 | else if (current_buffer->newline_cache) | ||
| 4500 | invalidate_region_cache (current_buffer, | 4504 | invalidate_region_cache (current_buffer, |
| 4501 | current_buffer->newline_cache, | 4505 | current_buffer->newline_cache, |
| 4502 | PT - BEG, Z - PT - inserted); | 4506 | PT - BEG, Z - PT - inserted); |
diff --git a/src/indent.c b/src/indent.c index 0c345d6c670..e86add54142 100644 --- a/src/indent.c +++ b/src/indent.c | |||
| @@ -144,30 +144,51 @@ recompute_width_table (struct buffer *buf, struct Lisp_Char_Table *disptab) | |||
| 144 | /* Allocate or free the width run cache, as requested by the | 144 | /* Allocate or free the width run cache, as requested by the |
| 145 | current state of current_buffer's cache_long_scans variable. */ | 145 | current state of current_buffer's cache_long_scans variable. */ |
| 146 | 146 | ||
| 147 | static void | 147 | static struct region_cache * |
| 148 | width_run_cache_on_off (void) | 148 | width_run_cache_on_off (void) |
| 149 | { | 149 | { |
| 150 | struct buffer *cache_buffer = current_buffer; | ||
| 151 | bool indirect_p = false; | ||
| 152 | |||
| 153 | if (cache_buffer->base_buffer) | ||
| 154 | { | ||
| 155 | cache_buffer = cache_buffer->base_buffer; | ||
| 156 | indirect_p = true; | ||
| 157 | } | ||
| 158 | |||
| 150 | if (NILP (BVAR (current_buffer, cache_long_scans)) | 159 | if (NILP (BVAR (current_buffer, cache_long_scans)) |
| 151 | /* And, for the moment, this feature doesn't work on multibyte | 160 | /* And, for the moment, this feature doesn't work on multibyte |
| 152 | characters. */ | 161 | characters. */ |
| 153 | || !NILP (BVAR (current_buffer, enable_multibyte_characters))) | 162 | || !NILP (BVAR (current_buffer, enable_multibyte_characters))) |
| 154 | { | 163 | { |
| 155 | /* It should be off. */ | 164 | if (!indirect_p |
| 156 | if (current_buffer->width_run_cache) | 165 | || NILP (BVAR (cache_buffer, cache_long_scans)) |
| 157 | { | 166 | || !NILP (BVAR (cache_buffer, enable_multibyte_characters))) |
| 158 | free_region_cache (current_buffer->width_run_cache); | 167 | { |
| 159 | current_buffer->width_run_cache = 0; | 168 | /* It should be off. */ |
| 160 | bset_width_table (current_buffer, Qnil); | 169 | if (cache_buffer->width_run_cache) |
| 170 | { | ||
| 171 | free_region_cache (cache_buffer->width_run_cache); | ||
| 172 | cache_buffer->width_run_cache = 0; | ||
| 173 | bset_width_table (current_buffer, Qnil); | ||
| 174 | } | ||
| 161 | } | 175 | } |
| 176 | return NULL; | ||
| 162 | } | 177 | } |
| 163 | else | 178 | else |
| 164 | { | 179 | { |
| 165 | /* It should be on. */ | 180 | if (!indirect_p |
| 166 | if (current_buffer->width_run_cache == 0) | 181 | || (!NILP (BVAR (cache_buffer, cache_long_scans)) |
| 167 | { | 182 | && NILP (BVAR (cache_buffer, enable_multibyte_characters)))) |
| 168 | current_buffer->width_run_cache = new_region_cache (); | 183 | { |
| 169 | recompute_width_table (current_buffer, buffer_display_table ()); | 184 | /* It should be on. */ |
| 170 | } | 185 | if (cache_buffer->width_run_cache == 0) |
| 186 | { | ||
| 187 | cache_buffer->width_run_cache = new_region_cache (); | ||
| 188 | recompute_width_table (current_buffer, buffer_display_table ()); | ||
| 189 | } | ||
| 190 | } | ||
| 191 | return cache_buffer->width_run_cache; | ||
| 171 | } | 192 | } |
| 172 | } | 193 | } |
| 173 | 194 | ||
| @@ -1128,12 +1149,16 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, | |||
| 1128 | EMACS_INT contin_hpos; /* HPOS of last column of continued line. */ | 1149 | EMACS_INT contin_hpos; /* HPOS of last column of continued line. */ |
| 1129 | int prev_tab_offset; /* Previous tab offset. */ | 1150 | int prev_tab_offset; /* Previous tab offset. */ |
| 1130 | int continuation_glyph_width; | 1151 | int continuation_glyph_width; |
| 1152 | struct buffer *cache_buffer = current_buffer; | ||
| 1153 | struct region_cache *width_cache; | ||
| 1131 | 1154 | ||
| 1132 | struct composition_it cmp_it; | 1155 | struct composition_it cmp_it; |
| 1133 | 1156 | ||
| 1134 | XSETWINDOW (window, win); | 1157 | XSETWINDOW (window, win); |
| 1135 | 1158 | ||
| 1136 | width_run_cache_on_off (); | 1159 | if (cache_buffer->base_buffer) |
| 1160 | cache_buffer = cache_buffer->base_buffer; | ||
| 1161 | width_cache = width_run_cache_on_off (); | ||
| 1137 | if (dp == buffer_display_table ()) | 1162 | if (dp == buffer_display_table ()) |
| 1138 | width_table = (VECTORP (BVAR (current_buffer, width_table)) | 1163 | width_table = (VECTORP (BVAR (current_buffer, width_table)) |
| 1139 | ? XVECTOR (BVAR (current_buffer, width_table))->contents | 1164 | ? XVECTOR (BVAR (current_buffer, width_table))->contents |
| @@ -1404,13 +1429,11 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, | |||
| 1404 | 1429 | ||
| 1405 | /* Consult the width run cache to see if we can avoid inspecting | 1430 | /* Consult the width run cache to see if we can avoid inspecting |
| 1406 | the text character-by-character. */ | 1431 | the text character-by-character. */ |
| 1407 | if (current_buffer->width_run_cache && pos >= next_width_run) | 1432 | if (width_cache && pos >= next_width_run) |
| 1408 | { | 1433 | { |
| 1409 | ptrdiff_t run_end; | 1434 | ptrdiff_t run_end; |
| 1410 | int common_width | 1435 | int common_width |
| 1411 | = region_cache_forward (current_buffer, | 1436 | = region_cache_forward (cache_buffer, width_cache, pos, &run_end); |
| 1412 | current_buffer->width_run_cache, | ||
| 1413 | pos, &run_end); | ||
| 1414 | 1437 | ||
| 1415 | /* A width of zero means the character's width varies (like | 1438 | /* A width of zero means the character's width varies (like |
| 1416 | a tab), is meaningless (like a newline), or we just don't | 1439 | a tab), is meaningless (like a newline), or we just don't |
| @@ -1486,7 +1509,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, | |||
| 1486 | pos++, pos_byte++; | 1509 | pos++, pos_byte++; |
| 1487 | 1510 | ||
| 1488 | /* Perhaps add some info to the width_run_cache. */ | 1511 | /* Perhaps add some info to the width_run_cache. */ |
| 1489 | if (current_buffer->width_run_cache) | 1512 | if (width_cache) |
| 1490 | { | 1513 | { |
| 1491 | /* Is this character part of the current run? If so, extend | 1514 | /* Is this character part of the current run? If so, extend |
| 1492 | the run. */ | 1515 | the run. */ |
| @@ -1502,8 +1525,7 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, | |||
| 1502 | (Currently, we only cache runs of width == 1). */ | 1525 | (Currently, we only cache runs of width == 1). */ |
| 1503 | if (width_run_start < width_run_end | 1526 | if (width_run_start < width_run_end |
| 1504 | && width_run_width == 1) | 1527 | && width_run_width == 1) |
| 1505 | know_region_cache (current_buffer, | 1528 | know_region_cache (cache_buffer, width_cache, |
| 1506 | current_buffer->width_run_cache, | ||
| 1507 | width_run_start, width_run_end); | 1529 | width_run_start, width_run_end); |
| 1508 | 1530 | ||
| 1509 | /* Start recording a new width run. */ | 1531 | /* Start recording a new width run. */ |
| @@ -1639,10 +1661,10 @@ compute_motion (ptrdiff_t from, ptrdiff_t frombyte, EMACS_INT fromvpos, | |||
| 1639 | after_loop: | 1661 | after_loop: |
| 1640 | 1662 | ||
| 1641 | /* Remember any final width run in the cache. */ | 1663 | /* Remember any final width run in the cache. */ |
| 1642 | if (current_buffer->width_run_cache | 1664 | if (width_cache |
| 1643 | && width_run_width == 1 | 1665 | && width_run_width == 1 |
| 1644 | && width_run_start < width_run_end) | 1666 | && width_run_start < width_run_end) |
| 1645 | know_region_cache (current_buffer, current_buffer->width_run_cache, | 1667 | know_region_cache (cache_buffer, width_cache, |
| 1646 | width_run_start, width_run_end); | 1668 | width_run_start, width_run_end); |
| 1647 | 1669 | ||
| 1648 | val_compute_motion.bufpos = pos; | 1670 | val_compute_motion.bufpos = pos; |
diff --git a/src/insdel.c b/src/insdel.c index dec8e074ec2..1c9bafd6004 100644 --- a/src/insdel.c +++ b/src/insdel.c | |||
| @@ -1878,6 +1878,10 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, | |||
| 1878 | void | 1878 | void |
| 1879 | invalidate_buffer_caches (struct buffer *buf, ptrdiff_t start, ptrdiff_t end) | 1879 | invalidate_buffer_caches (struct buffer *buf, ptrdiff_t start, ptrdiff_t end) |
| 1880 | { | 1880 | { |
| 1881 | /* Indirect buffers usually have their caches set to NULL, but we | ||
| 1882 | need to consider the caches of their base buffer. */ | ||
| 1883 | if (buf->base_buffer) | ||
| 1884 | buf = buf->base_buffer; | ||
| 1881 | if (buf->newline_cache) | 1885 | if (buf->newline_cache) |
| 1882 | invalidate_region_cache (buf, | 1886 | invalidate_region_cache (buf, |
| 1883 | buf->newline_cache, | 1887 | buf->newline_cache, |
diff --git a/src/search.c b/src/search.c index aaaa31f24f3..40ab5db495a 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -602,23 +602,47 @@ fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 602 | Otherwise, make sure it's off. | 602 | Otherwise, make sure it's off. |
| 603 | This is our cheezy way of associating an action with the change of | 603 | This is our cheezy way of associating an action with the change of |
| 604 | state of a buffer-local variable. */ | 604 | state of a buffer-local variable. */ |
| 605 | static void | 605 | static struct region_cache * |
| 606 | newline_cache_on_off (struct buffer *buf) | 606 | newline_cache_on_off (struct buffer *buf) |
| 607 | { | 607 | { |
| 608 | struct buffer *base_buf = buf; | ||
| 609 | bool indirect_p = false; | ||
| 610 | |||
| 611 | if (buf->base_buffer) | ||
| 612 | { | ||
| 613 | base_buf = buf->base_buffer; | ||
| 614 | indirect_p = true; | ||
| 615 | } | ||
| 616 | |||
| 617 | /* Don't turn on or off the cache in the base buffer, if the value | ||
| 618 | of cache-long-scans of the base buffer is inconsistent with that. | ||
| 619 | This is because doing so will just make the cache pure overhead, | ||
| 620 | since if we turn it on via indirect buffer, it will be | ||
| 621 | immediately turned off by its base buffer. */ | ||
| 608 | if (NILP (BVAR (buf, cache_long_scans))) | 622 | if (NILP (BVAR (buf, cache_long_scans))) |
| 609 | { | 623 | { |
| 610 | /* It should be off. */ | 624 | if (!indirect_p |
| 611 | if (buf->newline_cache) | 625 | || NILP (BVAR (base_buf, cache_long_scans))) |
| 612 | { | 626 | { |
| 613 | free_region_cache (buf->newline_cache); | 627 | /* It should be off. */ |
| 614 | buf->newline_cache = 0; | 628 | if (base_buf->newline_cache) |
| 615 | } | 629 | { |
| 630 | free_region_cache (base_buf->newline_cache); | ||
| 631 | base_buf->newline_cache = 0; | ||
| 632 | } | ||
| 633 | } | ||
| 634 | return NULL; | ||
| 616 | } | 635 | } |
| 617 | else | 636 | else |
| 618 | { | 637 | { |
| 619 | /* It should be on. */ | 638 | if (!indirect_p |
| 620 | if (buf->newline_cache == 0) | 639 | || !NILP (BVAR (base_buf, cache_long_scans))) |
| 621 | buf->newline_cache = new_region_cache (); | 640 | { |
| 641 | /* It should be on. */ | ||
| 642 | if (base_buf->newline_cache == 0) | ||
| 643 | base_buf->newline_cache = new_region_cache (); | ||
| 644 | } | ||
| 645 | return base_buf->newline_cache; | ||
| 622 | } | 646 | } |
| 623 | } | 647 | } |
| 624 | 648 | ||
| @@ -653,6 +677,7 @@ find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end, | |||
| 653 | { | 677 | { |
| 654 | struct region_cache *newline_cache; | 678 | struct region_cache *newline_cache; |
| 655 | int direction; | 679 | int direction; |
| 680 | struct buffer *cache_buffer; | ||
| 656 | 681 | ||
| 657 | if (count > 0) | 682 | if (count > 0) |
| 658 | { | 683 | { |
| @@ -669,8 +694,11 @@ find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end, | |||
| 669 | if (end_byte == -1) | 694 | if (end_byte == -1) |
| 670 | end_byte = CHAR_TO_BYTE (end); | 695 | end_byte = CHAR_TO_BYTE (end); |
| 671 | 696 | ||
| 672 | newline_cache_on_off (current_buffer); | 697 | newline_cache = newline_cache_on_off (current_buffer); |
| 673 | newline_cache = current_buffer->newline_cache; | 698 | if (current_buffer->base_buffer) |
| 699 | cache_buffer = current_buffer->base_buffer; | ||
| 700 | else | ||
| 701 | cache_buffer = current_buffer; | ||
| 674 | 702 | ||
| 675 | if (shortage != 0) | 703 | if (shortage != 0) |
| 676 | *shortage = 0; | 704 | *shortage = 0; |
| @@ -694,7 +722,7 @@ find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end, | |||
| 694 | ptrdiff_t next_change; | 722 | ptrdiff_t next_change; |
| 695 | immediate_quit = 0; | 723 | immediate_quit = 0; |
| 696 | while (region_cache_forward | 724 | while (region_cache_forward |
| 697 | (current_buffer, newline_cache, start, &next_change)) | 725 | (cache_buffer, newline_cache, start, &next_change)) |
| 698 | start = next_change; | 726 | start = next_change; |
| 699 | immediate_quit = allow_quit; | 727 | immediate_quit = allow_quit; |
| 700 | 728 | ||
| @@ -738,7 +766,7 @@ find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end, | |||
| 738 | this line's region is free of them. */ | 766 | this line's region is free of them. */ |
| 739 | if (newline_cache) | 767 | if (newline_cache) |
| 740 | { | 768 | { |
| 741 | know_region_cache (current_buffer, newline_cache, | 769 | know_region_cache (cache_buffer, newline_cache, |
| 742 | BYTE_TO_CHAR (lim_byte + cursor), | 770 | BYTE_TO_CHAR (lim_byte + cursor), |
| 743 | BYTE_TO_CHAR (lim_byte + next)); | 771 | BYTE_TO_CHAR (lim_byte + next)); |
| 744 | /* know_region_cache can relocate buffer text. */ | 772 | /* know_region_cache can relocate buffer text. */ |
| @@ -774,7 +802,7 @@ find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end, | |||
| 774 | ptrdiff_t next_change; | 802 | ptrdiff_t next_change; |
| 775 | immediate_quit = 0; | 803 | immediate_quit = 0; |
| 776 | while (region_cache_backward | 804 | while (region_cache_backward |
| 777 | (current_buffer, newline_cache, start, &next_change)) | 805 | (cache_buffer, newline_cache, start, &next_change)) |
| 778 | start = next_change; | 806 | start = next_change; |
| 779 | immediate_quit = allow_quit; | 807 | immediate_quit = allow_quit; |
| 780 | 808 | ||
| @@ -814,7 +842,7 @@ find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end, | |||
| 814 | this line's region is free of them. */ | 842 | this line's region is free of them. */ |
| 815 | if (newline_cache) | 843 | if (newline_cache) |
| 816 | { | 844 | { |
| 817 | know_region_cache (current_buffer, newline_cache, | 845 | know_region_cache (cache_buffer, newline_cache, |
| 818 | BYTE_TO_CHAR (ceiling_byte + prev + 1), | 846 | BYTE_TO_CHAR (ceiling_byte + prev + 1), |
| 819 | BYTE_TO_CHAR (ceiling_byte + cursor)); | 847 | BYTE_TO_CHAR (ceiling_byte + cursor)); |
| 820 | /* know_region_cache can relocate buffer text. */ | 848 | /* know_region_cache can relocate buffer text. */ |
diff --git a/src/xdisp.c b/src/xdisp.c index 8e2ac437ca3..035edc0ff55 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -15767,16 +15767,20 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) | |||
| 15767 | this may be a bit late to catch such changes, but the rest of | 15767 | this may be a bit late to catch such changes, but the rest of |
| 15768 | redisplay goes (non-fatally) haywire when the display table is | 15768 | redisplay goes (non-fatally) haywire when the display table is |
| 15769 | changed, so why should we worry about doing any better? */ | 15769 | changed, so why should we worry about doing any better? */ |
| 15770 | if (current_buffer->width_run_cache) | 15770 | if (current_buffer->width_run_cache |
| 15771 | || (current_buffer->base_buffer | ||
| 15772 | && current_buffer->base_buffer->width_run_cache)) | ||
| 15771 | { | 15773 | { |
| 15772 | struct Lisp_Char_Table *disptab = buffer_display_table (); | 15774 | struct Lisp_Char_Table *disptab = buffer_display_table (); |
| 15773 | 15775 | ||
| 15774 | if (! disptab_matches_widthtab | 15776 | if (! disptab_matches_widthtab |
| 15775 | (disptab, XVECTOR (BVAR (current_buffer, width_table)))) | 15777 | (disptab, XVECTOR (BVAR (current_buffer, width_table)))) |
| 15776 | { | 15778 | { |
| 15777 | invalidate_region_cache (current_buffer, | 15779 | struct buffer *buf = current_buffer; |
| 15778 | current_buffer->width_run_cache, | 15780 | |
| 15779 | BEG, Z); | 15781 | if (buf->base_buffer) |
| 15782 | buf = buf->base_buffer; | ||
| 15783 | invalidate_region_cache (buf, buf->width_run_cache, BEG, Z); | ||
| 15780 | recompute_width_table (current_buffer, disptab); | 15784 | recompute_width_table (current_buffer, disptab); |
| 15781 | } | 15785 | } |
| 15782 | } | 15786 | } |