diff options
| author | Dmitry Antipov | 2012-12-10 21:34:47 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2012-12-10 21:34:47 +0400 |
| commit | 98a07056558be8c13945a3a99b4801996af685a4 (patch) | |
| tree | 657c931f7e1cb73ef5158beda8a429013e3a23cf /src | |
| parent | 2b8c906403908a5037b52bfecb72b65d0ce0cd1e (diff) | |
| download | emacs-98a07056558be8c13945a3a99b4801996af685a4.tar.gz emacs-98a07056558be8c13945a3a99b4801996af685a4.zip | |
Per-buffer window counters.
* buffer.h (struct buffer): New member window_count.
(buffer_window_count): New function.
* buffer.c (Fget_buffer_create, Fmake_indirect_buffer):
Initialize window_count.
(Fkill_buffer): Verify window_count for the buffer being killed.
(modify_overlay): Do not force redisplay if buffer is not shown
in any window.
(init_buffer_once): Initialize window_count for buffer_defaults
and buffer_local_symbols.
* window.h (buffer_shared): Remove declaration.
(wset_buffer): Convert from inline ...
* window.c (wset_buffer): ... to an ordinary function.
(adjust_window_count): New function.
(make_parent_window): Use it.
* xdisp.c (buffer_shared): Remove.
(redisplay_internal, redisplay_window): Adjust users.
(buffer_shared_and_changed): Use per-buffer window counter.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 21 | ||||
| -rw-r--r-- | src/buffer.c | 39 | ||||
| -rw-r--r-- | src/buffer.h | 19 | ||||
| -rw-r--r-- | src/window.c | 31 | ||||
| -rw-r--r-- | src/window.h | 12 | ||||
| -rw-r--r-- | src/xdisp.c | 29 |
6 files changed, 99 insertions, 52 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 584ee17cc1b..ecaa60697ea 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,24 @@ | |||
| 1 | 2012-12-10 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 2 | |||
| 3 | Per-buffer window counters. | ||
| 4 | * buffer.h (struct buffer): New member window_count. | ||
| 5 | (buffer_window_count): New function. | ||
| 6 | * buffer.c (Fget_buffer_create, Fmake_indirect_buffer): | ||
| 7 | Initialize window_count. | ||
| 8 | (Fkill_buffer): Verify window_count for the buffer being killed. | ||
| 9 | (modify_overlay): Do not force redisplay if buffer is not shown | ||
| 10 | in any window. | ||
| 11 | (init_buffer_once): Initialize window_count for buffer_defaults | ||
| 12 | and buffer_local_symbols. | ||
| 13 | * window.h (buffer_shared): Remove declaration. | ||
| 14 | (wset_buffer): Convert from inline ... | ||
| 15 | * window.c (wset_buffer): ... to an ordinary function. | ||
| 16 | (adjust_window_count): New function. | ||
| 17 | (make_parent_window): Use it. | ||
| 18 | * xdisp.c (buffer_shared): Remove. | ||
| 19 | (redisplay_internal, redisplay_window): Adjust users. | ||
| 20 | (buffer_shared_and_changed): Use per-buffer window counter. | ||
| 21 | |||
| 1 | 2012-12-10 Eli Zaretskii <eliz@gnu.org> | 22 | 2012-12-10 Eli Zaretskii <eliz@gnu.org> |
| 2 | 23 | ||
| 3 | Support for filesystem notifications on MS-Windows. | 24 | Support for filesystem notifications on MS-Windows. |
diff --git a/src/buffer.c b/src/buffer.c index 6e2191dc22f..1194431841a 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -547,6 +547,8 @@ even if it is dead. The return value is never nil. */) | |||
| 547 | b->base_buffer = NULL; | 547 | b->base_buffer = NULL; |
| 548 | /* No one shares the text with us now. */ | 548 | /* No one shares the text with us now. */ |
| 549 | b->indirections = 0; | 549 | b->indirections = 0; |
| 550 | /* No one shows us now. */ | ||
| 551 | b->window_count = 0; | ||
| 550 | 552 | ||
| 551 | BUF_GAP_SIZE (b) = 20; | 553 | BUF_GAP_SIZE (b) = 20; |
| 552 | block_input (); | 554 | block_input (); |
| @@ -794,6 +796,8 @@ CLONE nil means the indirect buffer's state is reset to default values. */) | |||
| 794 | b->indirections = -1; | 796 | b->indirections = -1; |
| 795 | /* Notify base buffer that we share the text now. */ | 797 | /* Notify base buffer that we share the text now. */ |
| 796 | b->base_buffer->indirections++; | 798 | b->base_buffer->indirections++; |
| 799 | /* Always -1 for an indirect buffer. */ | ||
| 800 | b->window_count = -1; | ||
| 797 | 801 | ||
| 798 | b->pt = b->base_buffer->pt; | 802 | b->pt = b->base_buffer->pt; |
| 799 | b->begv = b->base_buffer->begv; | 803 | b->begv = b->base_buffer->begv; |
| @@ -1929,10 +1933,16 @@ cleaning up all windows currently displaying the buffer to be killed. */) | |||
| 1929 | eassert (b->indirections == -1); | 1933 | eassert (b->indirections == -1); |
| 1930 | b->base_buffer->indirections--; | 1934 | b->base_buffer->indirections--; |
| 1931 | eassert (b->base_buffer->indirections >= 0); | 1935 | eassert (b->base_buffer->indirections >= 0); |
| 1936 | /* Make sure that we wasn't confused. */ | ||
| 1937 | eassert (b->window_count == -1); | ||
| 1932 | } | 1938 | } |
| 1933 | else | 1939 | else |
| 1934 | /* No one shares our buffer text, can free it. */ | 1940 | { |
| 1935 | free_buffer_text (b); | 1941 | /* Make sure that no one shows us. */ |
| 1942 | eassert (b->window_count == 0); | ||
| 1943 | /* No one shares our buffer text, can free it. */ | ||
| 1944 | free_buffer_text (b); | ||
| 1945 | } | ||
| 1936 | 1946 | ||
| 1937 | if (b->newline_cache) | 1947 | if (b->newline_cache) |
| 1938 | { | 1948 | { |
| @@ -3880,17 +3890,17 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end) | |||
| 3880 | 3890 | ||
| 3881 | BUF_COMPUTE_UNCHANGED (buf, start, end); | 3891 | BUF_COMPUTE_UNCHANGED (buf, start, end); |
| 3882 | 3892 | ||
| 3883 | /* If this is a buffer not in the selected window, | 3893 | /* If BUF is visible, consider updating the display if ... */ |
| 3884 | we must do other windows. */ | 3894 | if (buffer_window_count (buf) > 0) |
| 3885 | if (buf != XBUFFER (XWINDOW (selected_window)->buffer)) | 3895 | { |
| 3886 | windows_or_buffers_changed = 1; | 3896 | /* ... it's visible in other window than selected, */ |
| 3887 | /* If multiple windows show this buffer, we must do other windows. */ | 3897 | if (buf != XBUFFER (XWINDOW (selected_window)->buffer)) |
| 3888 | else if (buffer_shared > 1) | 3898 | windows_or_buffers_changed = 1; |
| 3889 | windows_or_buffers_changed = 1; | 3899 | /* ... or if we modify an overlay at the end of the buffer |
| 3890 | /* If we modify an overlay at the end of the buffer, we cannot | 3900 | and so we cannot be sure that window end is still valid. */ |
| 3891 | be sure that window end is still valid. */ | 3901 | else if (end >= ZV && start <= ZV) |
| 3892 | else if (end >= ZV && start <= ZV) | 3902 | windows_or_buffers_changed = 1; |
| 3893 | windows_or_buffers_changed = 1; | 3903 | } |
| 3894 | 3904 | ||
| 3895 | ++BUF_OVERLAY_MODIFF (buf); | 3905 | ++BUF_OVERLAY_MODIFF (buf); |
| 3896 | } | 3906 | } |
| @@ -5125,6 +5135,9 @@ init_buffer_once (void) | |||
| 5125 | /* No one will share the text with these buffers, but let's play it safe. */ | 5135 | /* No one will share the text with these buffers, but let's play it safe. */ |
| 5126 | buffer_defaults.indirections = 0; | 5136 | buffer_defaults.indirections = 0; |
| 5127 | buffer_local_symbols.indirections = 0; | 5137 | buffer_local_symbols.indirections = 0; |
| 5138 | /* Likewise no one will display them. */ | ||
| 5139 | buffer_defaults.window_count = 0; | ||
| 5140 | buffer_local_symbols.window_count = 0; | ||
| 5128 | set_buffer_intervals (&buffer_defaults, NULL); | 5141 | set_buffer_intervals (&buffer_defaults, NULL); |
| 5129 | set_buffer_intervals (&buffer_local_symbols, NULL); | 5142 | set_buffer_intervals (&buffer_local_symbols, NULL); |
| 5130 | /* This is not strictly necessary, but let's make them initialized. */ | 5143 | /* This is not strictly necessary, but let's make them initialized. */ |
diff --git a/src/buffer.h b/src/buffer.h index 1129840bd47..d838d3767ef 100644 --- a/src/buffer.h +++ b/src/buffer.h | |||
| @@ -770,11 +770,15 @@ struct buffer | |||
| 770 | In an ordinary buffer, it is 0. */ | 770 | In an ordinary buffer, it is 0. */ |
| 771 | struct buffer *base_buffer; | 771 | struct buffer *base_buffer; |
| 772 | 772 | ||
| 773 | /* In an indirect buffer, this is -1. In an ordinary buffer, | 773 | /* In an indirect buffer, this is -1. In an ordinary buffer, |
| 774 | it's the number of indirect buffers that share our text; | 774 | it's the number of indirect buffers that share our text; |
| 775 | zero means that we're the only owner of this text. */ | 775 | zero means that we're the only owner of this text. */ |
| 776 | int indirections; | 776 | int indirections; |
| 777 | 777 | ||
| 778 | /* Number of windows showing this buffer. Always -1 for | ||
| 779 | an indirect buffer since it counts as its base buffer. */ | ||
| 780 | int window_count; | ||
| 781 | |||
| 778 | /* A non-zero value in slot IDX means that per-buffer variable | 782 | /* A non-zero value in slot IDX means that per-buffer variable |
| 779 | with index IDX has a local value in this buffer. The index IDX | 783 | with index IDX has a local value in this buffer. The index IDX |
| 780 | for a buffer-local variable is stored in that variable's slot | 784 | for a buffer-local variable is stored in that variable's slot |
| @@ -1173,7 +1177,18 @@ BUF_FETCH_MULTIBYTE_CHAR (struct buffer *buf, ptrdiff_t pos) | |||
| 1173 | + pos + BUF_BEG_ADDR (buf) - BEG_BYTE); | 1177 | + pos + BUF_BEG_ADDR (buf) - BEG_BYTE); |
| 1174 | return STRING_CHAR (p); | 1178 | return STRING_CHAR (p); |
| 1175 | } | 1179 | } |
| 1176 | 1180 | ||
| 1181 | /* Return number of windows showing B. */ | ||
| 1182 | |||
| 1183 | BUFFER_INLINE int | ||
| 1184 | buffer_window_count (struct buffer *b) | ||
| 1185 | { | ||
| 1186 | if (b->base_buffer) | ||
| 1187 | b = b->base_buffer; | ||
| 1188 | eassert (b->window_count >= 0); | ||
| 1189 | return b->window_count; | ||
| 1190 | } | ||
| 1191 | |||
| 1177 | /* Overlays */ | 1192 | /* Overlays */ |
| 1178 | 1193 | ||
| 1179 | /* Return the marker that stands for where OV starts in the buffer. */ | 1194 | /* Return the marker that stands for where OV starts in the buffer. */ |
diff --git a/src/window.c b/src/window.c index d7c2e8b236e..9d593b6d36e 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -270,6 +270,35 @@ decode_valid_window (register Lisp_Object window) | |||
| 270 | return w; | 270 | return w; |
| 271 | } | 271 | } |
| 272 | 272 | ||
| 273 | /* Called when W's buffer slot is changed. ARG -1 means that W is about to | ||
| 274 | cease its buffer, and 1 means that W is about to set up the new one. */ | ||
| 275 | |||
| 276 | static void | ||
| 277 | adjust_window_count (struct window *w, int arg) | ||
| 278 | { | ||
| 279 | eassert (eabs (arg) == 1); | ||
| 280 | if (BUFFERP (w->buffer)) | ||
| 281 | { | ||
| 282 | struct buffer *b = XBUFFER (w->buffer); | ||
| 283 | |||
| 284 | if (b->base_buffer) | ||
| 285 | b = b->base_buffer; | ||
| 286 | b->window_count += arg; | ||
| 287 | eassert (b->window_count >= 0); | ||
| 288 | } | ||
| 289 | } | ||
| 290 | |||
| 291 | /* Set W's buffer slot to VAL and recompute number | ||
| 292 | of windows showing VAL if it is a buffer. */ | ||
| 293 | |||
| 294 | void | ||
| 295 | wset_buffer (struct window *w, Lisp_Object val) | ||
| 296 | { | ||
| 297 | adjust_window_count (w, -1); | ||
| 298 | w->buffer = val; | ||
| 299 | adjust_window_count (w, 1); | ||
| 300 | } | ||
| 301 | |||
| 273 | /* Build a frequently used 4-integer (X Y W H) list. */ | 302 | /* Build a frequently used 4-integer (X Y W H) list. */ |
| 274 | 303 | ||
| 275 | static Lisp_Object | 304 | static Lisp_Object |
| @@ -3391,6 +3420,8 @@ make_parent_window (Lisp_Object window, int horflag) | |||
| 3391 | memcpy ((char *) p + sizeof (struct vectorlike_header), | 3420 | memcpy ((char *) p + sizeof (struct vectorlike_header), |
| 3392 | (char *) o + sizeof (struct vectorlike_header), | 3421 | (char *) o + sizeof (struct vectorlike_header), |
| 3393 | word_size * VECSIZE (struct window)); | 3422 | word_size * VECSIZE (struct window)); |
| 3423 | /* P's buffer slot may change from nil to a buffer. */ | ||
| 3424 | adjust_window_count (p, 1); | ||
| 3394 | XSETWINDOW (parent, p); | 3425 | XSETWINDOW (parent, p); |
| 3395 | 3426 | ||
| 3396 | p->sequence_number = ++sequence_number; | 3427 | p->sequence_number = ++sequence_number; |
diff --git a/src/window.h b/src/window.h index 2a12226c0aa..f4f42a25af4 100644 --- a/src/window.h +++ b/src/window.h | |||
| @@ -351,11 +351,6 @@ struct window | |||
| 351 | /* Most code should use these functions to set Lisp fields in struct | 351 | /* Most code should use these functions to set Lisp fields in struct |
| 352 | window. */ | 352 | window. */ |
| 353 | WINDOW_INLINE void | 353 | WINDOW_INLINE void |
| 354 | wset_buffer (struct window *w, Lisp_Object val) | ||
| 355 | { | ||
| 356 | w->buffer = val; | ||
| 357 | } | ||
| 358 | WINDOW_INLINE void | ||
| 359 | wset_frame (struct window *w, Lisp_Object val) | 354 | wset_frame (struct window *w, Lisp_Object val) |
| 360 | { | 355 | { |
| 361 | w->frame = val; | 356 | w->frame = val; |
| @@ -947,11 +942,6 @@ extern int windows_or_buffers_changed; | |||
| 947 | 942 | ||
| 948 | extern int cursor_type_changed; | 943 | extern int cursor_type_changed; |
| 949 | 944 | ||
| 950 | /* Number of windows displaying the selected buffer. Normally this is | ||
| 951 | 1, but it can be more. */ | ||
| 952 | |||
| 953 | extern int buffer_shared; | ||
| 954 | |||
| 955 | /* If *ROWS or *COLS are too small a size for FRAME, set them to the | 945 | /* If *ROWS or *COLS are too small a size for FRAME, set them to the |
| 956 | minimum allowable size. */ | 946 | minimum allowable size. */ |
| 957 | 947 | ||
| @@ -997,6 +987,8 @@ extern int window_body_cols (struct window *w); | |||
| 997 | extern void temp_output_buffer_show (Lisp_Object); | 987 | extern void temp_output_buffer_show (Lisp_Object); |
| 998 | extern void replace_buffer_in_windows (Lisp_Object); | 988 | extern void replace_buffer_in_windows (Lisp_Object); |
| 999 | extern void replace_buffer_in_windows_safely (Lisp_Object); | 989 | extern void replace_buffer_in_windows_safely (Lisp_Object); |
| 990 | /* This looks like a setter, but it is a bit special. */ | ||
| 991 | extern void wset_buffer (struct window *, Lisp_Object); | ||
| 1000 | extern void init_window_once (void); | 992 | extern void init_window_once (void); |
| 1001 | extern void init_window (void); | 993 | extern void init_window (void); |
| 1002 | extern void syms_of_window (void); | 994 | extern void syms_of_window (void); |
diff --git a/src/xdisp.c b/src/xdisp.c index 9464e87b362..cf0424ede17 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -515,11 +515,6 @@ Lisp_Object Qmenu_bar_update_hook; | |||
| 515 | 515 | ||
| 516 | static int overlay_arrow_seen; | 516 | static int overlay_arrow_seen; |
| 517 | 517 | ||
| 518 | /* Number of windows showing the buffer of the selected | ||
| 519 | window (or another buffer with the same base buffer). */ | ||
| 520 | |||
| 521 | int buffer_shared; | ||
| 522 | |||
| 523 | /* Vector containing glyphs for an ellipsis `...'. */ | 518 | /* Vector containing glyphs for an ellipsis `...'. */ |
| 524 | 519 | ||
| 525 | static Lisp_Object default_invis_vector[3]; | 520 | static Lisp_Object default_invis_vector[3]; |
| @@ -10894,9 +10889,8 @@ echo_area_display (int update_frame_p) | |||
| 10894 | static int | 10889 | static int |
| 10895 | buffer_shared_and_changed (void) | 10890 | buffer_shared_and_changed (void) |
| 10896 | { | 10891 | { |
| 10897 | /* The variable buffer_shared is set in redisplay_window and | 10892 | return (buffer_window_count (current_buffer) > 1 |
| 10898 | indicates that we redisplay a buffer in different windows. */ | 10893 | && UNCHANGED_MODIFIED < MODIFF); |
| 10899 | return (buffer_shared > 1 && UNCHANGED_MODIFIED < MODIFF); | ||
| 10900 | } | 10894 | } |
| 10901 | 10895 | ||
| 10902 | /* Nonzero if W doesn't reflect the actual state of current buffer due | 10896 | /* Nonzero if W doesn't reflect the actual state of current buffer due |
| @@ -13470,10 +13464,6 @@ redisplay_internal (void) | |||
| 13470 | FOR_EACH_FRAME (tail, frame) | 13464 | FOR_EACH_FRAME (tail, frame) |
| 13471 | XFRAME (frame)->updated_p = 0; | 13465 | XFRAME (frame)->updated_p = 0; |
| 13472 | 13466 | ||
| 13473 | /* Recompute # windows showing selected buffer. This will be | ||
| 13474 | incremented each time such a window is displayed. */ | ||
| 13475 | buffer_shared = 0; | ||
| 13476 | |||
| 13477 | FOR_EACH_FRAME (tail, frame) | 13467 | FOR_EACH_FRAME (tail, frame) |
| 13478 | { | 13468 | { |
| 13479 | struct frame *f = XFRAME (frame); | 13469 | struct frame *f = XFRAME (frame); |
| @@ -15568,21 +15558,6 @@ redisplay_window (Lisp_Object window, int just_this_one_p) | |||
| 15568 | if (mode_line_update_needed (w)) | 15558 | if (mode_line_update_needed (w)) |
| 15569 | update_mode_line = 1; | 15559 | update_mode_line = 1; |
| 15570 | 15560 | ||
| 15571 | /* Count number of windows showing the selected buffer. An indirect | ||
| 15572 | buffer counts as its base buffer. */ | ||
| 15573 | if (!just_this_one_p) | ||
| 15574 | { | ||
| 15575 | struct buffer *current_base, *window_base; | ||
| 15576 | current_base = current_buffer; | ||
| 15577 | window_base = XBUFFER (XWINDOW (selected_window)->buffer); | ||
| 15578 | if (current_base->base_buffer) | ||
| 15579 | current_base = current_base->base_buffer; | ||
| 15580 | if (window_base->base_buffer) | ||
| 15581 | window_base = window_base->base_buffer; | ||
| 15582 | if (current_base == window_base) | ||
| 15583 | buffer_shared++; | ||
| 15584 | } | ||
| 15585 | |||
| 15586 | /* Point refers normally to the selected window. For any other | 15561 | /* Point refers normally to the selected window. For any other |
| 15587 | window, set up appropriate value. */ | 15562 | window, set up appropriate value. */ |
| 15588 | if (!EQ (window, selected_window)) | 15563 | if (!EQ (window, selected_window)) |