/* Buffer manipulation primitives for GNU Emacs.
-Copyright (C) 1985-1989, 1993-1995, 1997-2012 Free Software Foundation, Inc.
+Copyright (C) 1985-1989, 1993-1995, 1997-2013 Free Software Foundation,
+Inc.
This file is part of GNU Emacs.
b->base_buffer = NULL;
/* No one shares the text with us now. */
b->indirections = 0;
+ /* No one shows us now. */
+ b->window_count = 0;
BUF_GAP_SIZE (b) = 20;
block_input ();
BUF_CHARS_MODIFF (b) = 1;
BUF_OVERLAY_MODIFF (b) = 1;
BUF_SAVE_MODIFF (b) = 1;
+ BUF_COMPACT (b) = 1;
set_buffer_intervals (b, NULL);
BUF_UNCHANGED_MODIFIED (b) = 1;
BUF_OVERLAY_UNCHANGED_MODIFIED (b) = 1;
b->indirections = -1;
/* Notify base buffer that we share the text now. */
b->base_buffer->indirections++;
+ /* Always -1 for an indirect buffer. */
+ b->window_count = -1;
b->pt = b->base_buffer->pt;
b->begv = b->base_buffer->begv;
A non-nil FLAG means mark the buffer modified. */)
(Lisp_Object flag)
{
- Lisp_Object fn, buffer, window;
+ Lisp_Object fn;
#ifdef CLASH_DETECTION
/* If buffer becoming modified, lock the file.
Ideally, I think there should be another mechanism for fontifying
buffers without "modifying" buffers, or redisplay should be
smarter about updating the `*' in mode lines. --gerd */
- XSETBUFFER (buffer, current_buffer);
- window = Fget_buffer_window (buffer, Qt);
- if (WINDOWP (window))
+ if (buffer_window_count (current_buffer))
{
++update_mode_lines;
current_buffer->prevent_redisplay_optimizations_p = 1;
return BVAR (current_buffer, name);
}
+/* True if B can be used as 'other-than-BUFFER' buffer. */
+
+static bool
+candidate_buffer (Lisp_Object b, Lisp_Object buffer)
+{
+ return (BUFFERP (b) && !EQ (b, buffer)
+ && BUFFER_LIVE_P (XBUFFER (b))
+ && !BUFFER_HIDDEN_P (XBUFFER (b)));
+}
+
DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0,
doc: /* Return most recently selected buffer other than BUFFER.
Buffers not visible in windows are preferred to visible buffers, unless
for (; CONSP (tail); tail = XCDR (tail))
{
buf = XCAR (tail);
- if (BUFFERP (buf) && !EQ (buf, buffer)
- && BUFFER_LIVE_P (XBUFFER (buf))
- && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')
+ if (candidate_buffer (buf, buffer)
/* If the frame has a buffer_predicate, disregard buffers that
don't fit the predicate. */
&& (NILP (pred) || !NILP (call1 (pred, buf))))
for (; CONSP (tail); tail = XCDR (tail))
{
buf = Fcdr (XCAR (tail));
- if (BUFFERP (buf) && !EQ (buf, buffer)
- && BUFFER_LIVE_P (XBUFFER (buf))
- && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')
+ if (candidate_buffer (buf, buffer)
/* If the frame has a buffer_predicate, disregard buffers that
don't fit the predicate. */
&& (NILP (pred) || !NILP (call1 (pred, buf))))
{
Lisp_Object tail, buf;
- tail = Vbuffer_alist;
- for (; CONSP (tail); tail = XCDR (tail))
+ for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
{
buf = Fcdr (XCAR (tail));
- if (BUFFERP (buf) && !EQ (buf, buffer)
- && BUFFER_LIVE_P (XBUFFER (buf))
- && (SREF (BVAR (XBUFFER (buf), name), 0) != ' '))
+ if (candidate_buffer (buf, buffer))
return buf;
}
which aren't changed since last compaction. */
if (BUFFER_LIVE_P (buffer)
&& (buffer->base_buffer == NULL)
- && (buffer->text->compact != buffer->text->modiff))
+ && (BUF_COMPACT (buffer) != BUF_MODIFF (buffer)))
{
/* If a buffer's undo list is Qt, that means that undo is
turned off in that buffer. Calling truncate_undo_list on
if (!buffer->text->inhibit_shrinking)
{
/* If a buffer's gap size is more than 10% of the buffer
- size, or larger than 2000 bytes, then shrink it
- accordingly. Keep a minimum size of 20 bytes. */
- int size = min (2000, max (20, (buffer->text->z_byte / 10)));
-
- if (buffer->text->gap_size > size)
- {
- struct buffer *save_current = current_buffer;
- current_buffer = buffer;
- make_gap (-(buffer->text->gap_size - size));
- current_buffer = save_current;
- }
+ size, or larger than GAP_BYTES_DFL bytes, then shrink it
+ accordingly. Keep a minimum size of GAP_BYTES_MIN bytes. */
+ ptrdiff_t size = clip_to_bounds (GAP_BYTES_MIN,
+ BUF_Z_BYTE (buffer) / 10,
+ GAP_BYTES_DFL);
+ if (BUF_GAP_SIZE (buffer) > size)
+ make_gap_1 (buffer, -(BUF_GAP_SIZE (buffer) - size));
}
- buffer->text->compact = buffer->text->modiff;
+ BUF_COMPACT (buffer) = BUF_MODIFF (buffer);
}
}
eassert (b->indirections == -1);
b->base_buffer->indirections--;
eassert (b->base_buffer->indirections >= 0);
+ /* Make sure that we wasn't confused. */
+ eassert (b->window_count == -1);
}
else
- /* No one shares our buffer text, can free it. */
- free_buffer_text (b);
+ {
+ /* Make sure that no one shows us. */
+ eassert (b->window_count == 0);
+ /* No one shares our buffer text, can free it. */
+ free_buffer_text (b);
+ }
if (b->newline_cache)
{
DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0,
doc: /* Set an appropriate major mode for BUFFER.
For the *scratch* buffer, use `initial-major-mode', otherwise choose a mode
-according to `default-major-mode'.
+according to the default value of `major-mode'.
Use this function before selecting the buffer, since it may need to inspect
the current buffer's major mode. */)
(Lisp_Object buffer)
UNGCPRO;
- /* Changing the multibyteness of a buffer means that all windows
- showing that buffer must be updated thoroughly. */
current_buffer->prevent_redisplay_optimizations_p = 1;
- ++windows_or_buffers_changed;
+
+ /* If buffer is shown in a window, let redisplay consider other windows. */
+ if (buffer_window_count (current_buffer))
+ ++windows_or_buffers_changed;
/* Copy this buffer's new multibyte status
into all of its indirect buffers. */
BUF_COMPUTE_UNCHANGED (buf, start, end);
- /* If this is a buffer not in the selected window,
- we must do other windows. */
- if (buf != XBUFFER (XWINDOW (selected_window)->buffer))
- windows_or_buffers_changed = 1;
- /* If multiple windows show this buffer, we must do other windows. */
- else if (buffer_shared > 1)
- windows_or_buffers_changed = 1;
- /* If we modify an overlay at the end of the buffer, we cannot
- be sure that window end is still valid. */
- else if (end >= ZV && start <= ZV)
- windows_or_buffers_changed = 1;
+ /* If BUF is visible, consider updating the display if ... */
+ if (buffer_window_count (buf) > 0)
+ {
+ /* ... it's visible in other window than selected, */
+ if (buf != XBUFFER (XWINDOW (selected_window)->buffer))
+ windows_or_buffers_changed = 1;
+ /* ... or if we modify an overlay at the end of the buffer
+ and so we cannot be sure that window end is still valid. */
+ else if (end >= ZV && start <= ZV)
+ windows_or_buffers_changed = 1;
+ }
++BUF_OVERLAY_MODIFF (buf);
}
/* No one will share the text with these buffers, but let's play it safe. */
buffer_defaults.indirections = 0;
buffer_local_symbols.indirections = 0;
+ /* Likewise no one will display them. */
+ buffer_defaults.window_count = 0;
+ buffer_local_symbols.window_count = 0;
set_buffer_intervals (&buffer_defaults, NULL);
set_buffer_intervals (&buffer_local_symbols, NULL);
/* This is not strictly necessary, but let's make them initialized. */