summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2012-12-17 07:56:22 -0700
committerTom Tromey <tromey@redhat.com>2012-12-17 07:56:22 -0700
commit3d6eced1ae51ffd0a782130e7c334052277e2724 (patch)
tree5d1d2ad7cd3374f922886c4a72062511a035c168 /src/buffer.c
parentbf69f522a9e135f9aa483cedd53e71e915f2bf75 (diff)
parent7c3d167f48d6262ee4e5512aa50a07ee96bc1509 (diff)
downloademacs-3d6eced1ae51ffd0a782130e7c334052277e2724.tar.gz
merge from trunk
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c355
1 files changed, 175 insertions, 180 deletions
diff --git a/src/buffer.c b/src/buffer.c
index ef87f40e81a..c8864419076 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -26,7 +26,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <sys/param.h>
#include <errno.h>
#include <stdio.h>
-#include <setjmp.h>
#include <unistd.h>
#include <verify.h>
@@ -58,10 +57,6 @@ struct buffer *all_buffers;
struct buffer alignas (GCALIGNMENT) buffer_defaults;
-/* A Lisp_Object pointer to the above, used for staticpro */
-
-static Lisp_Object Vbuffer_defaults;
-
/* This structure marks which slots in a buffer have corresponding
default values in buffer_defaults.
Each such slot has a nonzero value in this structure.
@@ -76,18 +71,15 @@ static Lisp_Object Vbuffer_defaults;
and the corresponding slot in buffer_defaults is not used.
If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is
- zero, that is a bug */
+ zero, that is a bug. */
struct buffer buffer_local_flags;
/* This structure holds the names of symbols whose values may be
- buffer-local. It is indexed and accessed in the same way as the above. */
+ buffer-local. It is indexed and accessed in the same way as the above. */
struct buffer alignas (GCALIGNMENT) buffer_local_symbols;
-/* A Lisp_Object pointer to the above, used for staticpro */
-static Lisp_Object Vbuffer_local_symbols;
-
/* Return the symbol of the per-buffer variable at offset OFFSET in
the buffer structure. */
@@ -113,7 +105,7 @@ static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay,
static void swap_out_buffer_local_variables (struct buffer *b);
static void reset_buffer_local_variables (struct buffer *, bool);
-/* Alist of all buffer names vs the buffers. */
+/* Alist of all buffer names vs the buffers. */
/* This used to be a variable, but is no longer,
to prevent lossage due to user rplac'ing this alist or its elements. */
Lisp_Object Vbuffer_alist;
@@ -132,7 +124,7 @@ static Lisp_Object Qpermanent_local_hook;
static Lisp_Object Qprotected_field;
-static Lisp_Object QSFundamental; /* A string "Fundamental" */
+static Lisp_Object QSFundamental; /* A string "Fundamental". */
static Lisp_Object Qkill_buffer_hook;
static Lisp_Object Qbuffer_list_update_hook;
@@ -156,222 +148,222 @@ static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t);
static Lisp_Object buffer_lisp_local_variables (struct buffer *, bool);
/* These setters are used only in this file, so they can be private. */
-static inline void
+static void
bset_abbrev_mode (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (abbrev_mode) = val;
}
-static inline void
+static void
bset_abbrev_table (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (abbrev_table) = val;
}
-static inline void
+static void
bset_auto_fill_function (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (auto_fill_function) = val;
}
-static inline void
+static void
bset_auto_save_file_format (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (auto_save_file_format) = val;
}
-static inline void
+static void
bset_auto_save_file_name (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (auto_save_file_name) = val;
}
-static inline void
+static void
bset_backed_up (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (backed_up) = val;
}
-static inline void
+static void
bset_begv_marker (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (begv_marker) = val;
}
-static inline void
+static void
bset_bidi_display_reordering (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (bidi_display_reordering) = val;
}
-static inline void
+static void
bset_buffer_file_coding_system (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (buffer_file_coding_system) = val;
}
-static inline void
+static void
bset_cache_long_line_scans (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (cache_long_line_scans) = val;
}
-static inline void
+static void
bset_case_fold_search (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (case_fold_search) = val;
}
-static inline void
+static void
bset_ctl_arrow (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (ctl_arrow) = val;
}
-static inline void
+static void
bset_cursor_in_non_selected_windows (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (cursor_in_non_selected_windows) = val;
}
-static inline void
+static void
bset_cursor_type (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (cursor_type) = val;
}
-static inline void
+static void
bset_display_table (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (display_table) = val;
}
-static inline void
+static void
bset_extra_line_spacing (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (extra_line_spacing) = val;
}
-static inline void
+static void
bset_file_format (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (file_format) = val;
}
-static inline void
+static void
bset_file_truename (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (file_truename) = val;
}
-static inline void
+static void
bset_fringe_cursor_alist (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (fringe_cursor_alist) = val;
}
-static inline void
+static void
bset_fringe_indicator_alist (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (fringe_indicator_alist) = val;
}
-static inline void
+static void
bset_fringes_outside_margins (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (fringes_outside_margins) = val;
}
-static inline void
+static void
bset_header_line_format (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (header_line_format) = val;
}
-static inline void
+static void
bset_indicate_buffer_boundaries (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (indicate_buffer_boundaries) = val;
}
-static inline void
+static void
bset_indicate_empty_lines (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (indicate_empty_lines) = val;
}
-static inline void
+static void
bset_invisibility_spec (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (invisibility_spec) = val;
}
-static inline void
+static void
bset_left_fringe_width (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (left_fringe_width) = val;
}
-static inline void
+static void
bset_major_mode (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (major_mode) = val;
}
-static inline void
+static void
bset_mark (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (mark) = val;
}
-static inline void
+static void
bset_minor_modes (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (minor_modes) = val;
}
-static inline void
+static void
bset_mode_line_format (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (mode_line_format) = val;
}
-static inline void
+static void
bset_mode_name (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (mode_name) = val;
}
-static inline void
+static void
bset_name (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (name) = val;
}
-static inline void
+static void
bset_overwrite_mode (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (overwrite_mode) = val;
}
-static inline void
+static void
bset_pt_marker (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (pt_marker) = val;
}
-static inline void
+static void
bset_right_fringe_width (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (right_fringe_width) = val;
}
-static inline void
+static void
bset_save_length (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (save_length) = val;
}
-static inline void
+static void
bset_scroll_bar_width (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (scroll_bar_width) = val;
}
-static inline void
+static void
bset_scroll_down_aggressively (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (scroll_down_aggressively) = val;
}
-static inline void
+static void
bset_scroll_up_aggressively (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (scroll_up_aggressively) = val;
}
-static inline void
+static void
bset_selective_display (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (selective_display) = val;
}
-static inline void
+static void
bset_selective_display_ellipses (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (selective_display_ellipses) = val;
}
-static inline void
+static void
bset_vertical_scroll_bar_type (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (vertical_scroll_bar_type) = val;
}
-static inline void
+static void
bset_word_wrap (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (word_wrap) = val;
}
-static inline void
+static void
bset_zv_marker (struct buffer *b, Lisp_Object val)
{
b->INTERNAL_FIELD (zv_marker) = val;
@@ -393,7 +385,7 @@ DEFUN ("buffer-live-p", Fbuffer_live_p, Sbuffer_live_p, 1, 1, 0,
Value is nil if OBJECT is not a buffer or if it has been killed. */)
(Lisp_Object object)
{
- return ((BUFFERP (object) && ! NILP (BVAR (XBUFFER (object), name)))
+ return ((BUFFERP (object) && BUFFER_LIVE_P (XBUFFER (object)))
? Qt : Qnil);
}
@@ -412,7 +404,6 @@ followed by the rest of the buffers. */)
Lisp_Object framelist, prevlist, tail;
Lisp_Object args[3];
- CHECK_FRAME (frame);
framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
prevlist = Fnreverse (Fcopy_sequence
(XFRAME (frame)->buried_buffer_list));
@@ -554,13 +545,15 @@ even if it is dead. The return value is never nil. */)
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;
+ block_input ();
/* We allocate extra 1-byte at the tail and keep it always '\0' for
anchoring a search. */
alloc_buffer_text (b, BUF_GAP_SIZE (b) + 1);
- UNBLOCK_INPUT;
+ unblock_input ();
if (! BUF_BEG_ADDR (b))
buffer_memory_full (BUF_GAP_SIZE (b) + 1);
@@ -593,10 +586,6 @@ even if it is dead. The return value is never nil. */)
bset_width_table (b, Qnil);
b->prevent_redisplay_optimizations_p = 1;
- /* Put this on the chain of all buffers including killed ones. */
- b->header.next.buffer = all_buffers;
- all_buffers = b;
-
/* An ordinary buffer normally doesn't need markers
to handle BEGV and ZV. */
bset_pt_marker (b, Qnil);
@@ -661,13 +650,13 @@ copy_overlays (struct buffer *b, struct Lisp_Overlay *list)
/* Set an appropriate overlay of B. */
-static inline void
+static void
set_buffer_overlays_before (struct buffer *b, struct Lisp_Overlay *o)
{
b->overlays_before = o;
}
-static inline void
+static void
set_buffer_overlays_after (struct buffer *b, struct Lisp_Overlay *o)
{
b->overlays_after = o;
@@ -785,7 +774,7 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
base_buffer = Fget_buffer (base_buffer);
if (NILP (base_buffer))
error ("No such buffer: `%s'", SDATA (tem));
- if (NILP (BVAR (XBUFFER (base_buffer), name)))
+ if (!BUFFER_LIVE_P (XBUFFER (base_buffer)))
error ("Base buffer has been killed");
if (SCHARS (name) == 0)
@@ -805,6 +794,8 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
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;
@@ -817,10 +808,6 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
b->width_run_cache = 0;
bset_width_table (b, Qnil);
- /* Put this on the chain of all buffers including killed ones. */
- b->header.next.buffer = all_buffers;
- all_buffers = b;
-
name = Fcopy_sequence (name);
set_string_intervals (name, NULL);
bset_name (b, name);
@@ -911,6 +898,8 @@ delete_all_overlays (struct buffer *b)
{
struct Lisp_Overlay *ov, *next;
+ /* FIXME: Since each drop_overlay will scan BUF_MARKERS to unlink its
+ markers, we have an unneeded O(N^2) behavior here. */
for (ov = b->overlays_before; ov; ov = next)
{
drop_overlay (b, ov);
@@ -1240,7 +1229,7 @@ buffer_local_value_1 (Lisp_Object variable, Lisp_Object buffer)
result = Fdefault_value (variable);
break;
}
- default: abort ();
+ default: emacs_abort ();
}
return result;
@@ -1355,9 +1344,13 @@ A non-nil FLAG means mark the buffer modified. */)
/* If buffer becoming modified, lock the file.
If buffer becoming unmodified, unlock the file. */
- fn = BVAR (current_buffer, file_truename);
+ struct buffer *b = current_buffer->base_buffer
+ ? current_buffer->base_buffer
+ : current_buffer;
+
+ fn = BVAR (b, file_truename);
/* Test buffer-file-name so that binding it to nil is effective. */
- if (!NILP (fn) && ! NILP (BVAR (current_buffer, filename)))
+ if (!NILP (fn) && ! NILP (BVAR (b, filename)))
{
bool already = SAVE_MODIFF < MODIFF;
if (!already && !NILP (flag))
@@ -1538,6 +1531,16 @@ This does not change the name of the visited file (if any). */)
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
@@ -1551,23 +1554,15 @@ list first, followed by the list of all buffers. If no other buffer
exists, return the buffer `*scratch*' (creating it if necessary). */)
(register Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame)
{
- Lisp_Object tail, buf, pred;
- Lisp_Object notsogood = Qnil;
-
- if (NILP (frame))
- frame = selected_frame;
-
- CHECK_FRAME (frame);
+ struct frame *f = decode_any_frame (frame);
+ Lisp_Object tail = f->buffer_list, pred = f->buffer_predicate;
+ Lisp_Object buf, notsogood = Qnil;
- pred = frame_buffer_predicate (frame);
/* Consider buffers that have been seen in the frame first. */
- tail = XFRAME (frame)->buffer_list;
for (; CONSP (tail); tail = XCDR (tail))
{
buf = XCAR (tail);
- if (BUFFERP (buf) && !EQ (buf, buffer)
- && !NILP (BVAR (XBUFFER (buf), name))
- && (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))))
@@ -1585,9 +1580,7 @@ exists, return the buffer `*scratch*' (creating it if necessary). */)
for (; CONSP (tail); tail = XCDR (tail))
{
buf = Fcdr (XCAR (tail));
- if (BUFFERP (buf) && !EQ (buf, buffer)
- && !NILP (BVAR (XBUFFER (buf), name))
- && (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))))
@@ -1623,13 +1616,10 @@ other_buffer_safely (Lisp_Object buffer)
{
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)
- && !NILP (BVAR (XBUFFER (buf), name))
- && (SREF (BVAR (XBUFFER (buf), name), 0) != ' '))
+ if (candidate_buffer (buf, buffer))
return buf;
}
@@ -1671,18 +1661,11 @@ No argument or nil as argument means do this for the current buffer. */)
void
compact_buffer (struct buffer *buffer)
{
- /* Verify indirection counters. */
- if (buffer->base_buffer)
- {
- eassert (buffer->indirections == -1);
- eassert (buffer->base_buffer->indirections > 0);
- }
- else
- eassert (buffer->indirections >= 0);
+ BUFFER_CHECK_INDIRECTION (buffer);
/* Skip dead buffers, indirect buffers and buffers
which aren't changed since last compaction. */
- if (!NILP (buffer->INTERNAL_FIELD (name))
+ if (BUFFER_LIVE_P (buffer)
&& (buffer->base_buffer == NULL)
&& (buffer->text->compact != buffer->text->modiff))
{
@@ -1747,7 +1730,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
b = XBUFFER (buffer);
/* Avoid trouble for buffer already dead. */
- if (NILP (BVAR (b, name)))
+ if (!BUFFER_LIVE_P (b))
return Qnil;
/* Query if the buffer is still modified. */
@@ -1783,7 +1766,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
}
/* If the hooks have killed the buffer, exit now. */
- if (NILP (BVAR (b, name)))
+ if (!BUFFER_LIVE_P (b))
return Qt;
/* We have no more questions to ask. Verify that it is valid
@@ -1815,7 +1798,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
UNGCPRO;
/* Exit if we now have killed the base buffer (Bug#11665). */
- if (NILP (BVAR (b, name)))
+ if (!BUFFER_LIVE_P (b))
return Qt;
}
@@ -1826,7 +1809,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
replace_buffer_in_windows (buffer);
/* Exit if replacing the buffer in windows has killed our buffer. */
- if (NILP (BVAR (b, name)))
+ if (!BUFFER_LIVE_P (b))
return Qt;
/* Make this buffer not be current. Exit if it is the sole visible
@@ -1859,7 +1842,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
/* Killing buffer processes may run sentinels which may have killed
our buffer. */
- if (NILP (BVAR (b, name)))
+ if (!BUFFER_LIVE_P (b))
return Qt;
/* These may run Lisp code and into infinite loops (if someone
@@ -1891,7 +1874,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
}
/* Deleting an auto-save file could have killed our buffer. */
- if (NILP (BVAR (b, name)))
+ if (!BUFFER_LIVE_P (b))
return Qt;
if (b->base_buffer)
@@ -1899,12 +1882,16 @@ cleaning up all windows currently displaying the buffer to be killed. */)
/* Unchain all markers that belong to this indirect buffer.
Don't unchain the markers that belong to the base buffer
or its other indirect buffers. */
- for (m = BUF_MARKERS (b); m; )
+ struct Lisp_Marker **mp = &BUF_MARKERS (b);
+ while ((m = *mp))
{
- struct Lisp_Marker *next = m->next;
if (m->buffer == b)
- unchain_marker (m);
- m = next;
+ {
+ m->buffer = NULL;
+ *mp = m->next;
+ }
+ else
+ mp = &m->next;
}
}
else
@@ -1921,8 +1908,12 @@ cleaning up all windows currently displaying the buffer to be killed. */)
BUF_MARKERS (b) = NULL;
set_buffer_intervals (b, NULL);
- /* Perhaps we should explicitly free the interval tree here... */
+ /* Perhaps we should explicitly free the interval tree here... */
}
+ /* Since we've unlinked the markers, the overlays can't be here any more
+ either. */
+ b->overlays_before = NULL;
+ b->overlays_after = NULL;
/* Reset the local variables, so that this buffer's local values
won't be protected from GC. They would be protected
@@ -1933,17 +1924,23 @@ cleaning up all windows currently displaying the buffer to be killed. */)
bset_name (b, Qnil);
- BLOCK_INPUT;
+ block_input ();
if (b->base_buffer)
{
/* Notify our base buffer that we don't share the text anymore. */
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)
{
@@ -1956,7 +1953,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
b->width_run_cache = 0;
}
bset_width_table (b, Qnil);
- UNBLOCK_INPUT;
+ unblock_input ();
bset_undo_list (b, Qnil);
/* Run buffer-list-update-hook. */
@@ -2060,7 +2057,7 @@ the current buffer's major mode. */)
CHECK_BUFFER (buffer);
- if (NILP (BVAR (XBUFFER (buffer), name)))
+ if (!BUFFER_LIVE_P (XBUFFER (buffer)))
error ("Attempt to set major mode for a dead buffer");
if (strcmp (SSDATA (BVAR (XBUFFER (buffer), name)), "*scratch*") == 0)
@@ -2115,6 +2112,8 @@ set_buffer_internal_1 (register struct buffer *b)
if (current_buffer == b)
return;
+ BUFFER_CHECK_INDIRECTION (b);
+
old_buf = current_buffer;
current_buffer = b;
last_known_column_point = -1; /* invalidate indentation cache */
@@ -2186,7 +2185,7 @@ set_buffer_temp (struct buffer *b)
DEFUN ("set-buffer", Fset_buffer, Sset_buffer, 1, 1, 0,
doc: /* Make buffer BUFFER-OR-NAME current for editing operations.
BUFFER-OR-NAME may be a buffer or the name of an existing buffer. See
-also `save-excursion' when you want to make a buffer current
+also `with-current-buffer' when you want to make a buffer current
temporarily. This function does not display the buffer, so its effect
ends when the current command terminates. Use `switch-to-buffer' or
`pop-to-buffer' to switch buffers permanently. */)
@@ -2196,7 +2195,7 @@ ends when the current command terminates. Use `switch-to-buffer' or
buffer = Fget_buffer (buffer_or_name);
if (NILP (buffer))
nsberror (buffer_or_name);
- if (NILP (BVAR (XBUFFER (buffer), name)))
+ if (!BUFFER_LIVE_P (XBUFFER (buffer)))
error ("Selecting deleted buffer");
set_buffer_internal (XBUFFER (buffer));
return buffer;
@@ -2207,7 +2206,7 @@ ends when the current command terminates. Use `switch-to-buffer' or
Lisp_Object
set_buffer_if_live (Lisp_Object buffer)
{
- if (! NILP (BVAR (XBUFFER (buffer), name)))
+ if (BUFFER_LIVE_P (XBUFFER (buffer)))
set_buffer_internal (XBUFFER (buffer));
return Qnil;
}
@@ -2302,7 +2301,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
CHECK_BUFFER (buffer);
other_buffer = XBUFFER (buffer);
- if (NILP (BVAR (other_buffer, name)))
+ if (!BUFFER_LIVE_P (other_buffer))
error ("Cannot swap a dead buffer's text");
/* Actually, it probably works just fine.
@@ -2474,7 +2473,7 @@ current buffer is cleared. */)
begv = BEGV, zv = ZV;
if (narrowed)
- Fwiden ();
+ error ("Changing multibyteness in a narrowed buffer");
if (NILP (flag))
{
@@ -2669,7 +2668,7 @@ current buffer is cleared. */)
/* Make sure no markers were put on the chain
while the chain value was incorrect. */
if (BUF_MARKERS (current_buffer))
- abort ();
+ emacs_abort ();
BUF_MARKERS (current_buffer) = markers;
@@ -2690,15 +2689,16 @@ current buffer is cleared. */)
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. */
FOR_EACH_BUFFER (other)
- if (other->base_buffer == current_buffer && !NILP (BVAR (other, name)))
+ if (other->base_buffer == current_buffer && BUFFER_LIVE_P (other))
{
BVAR (other, enable_multibyte_characters)
= BVAR (current_buffer, enable_multibyte_characters);
@@ -3144,8 +3144,8 @@ compare_overlays (const void *v1, const void *v2)
between "equal" overlays. The result can still change between
invocations of Emacs, but it won't change in the middle of
`find_field' (bug#6830). */
- if (XHASH (s1->overlay) != XHASH (s2->overlay))
- return XHASH (s1->overlay) < XHASH (s2->overlay) ? -1 : 1;
+ if (!EQ (s1->overlay, s2->overlay))
+ return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1;
return 0;
}
@@ -3411,7 +3411,7 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
}
}
if (p != overlay_str_buf + total)
- abort ();
+ emacs_abort ();
if (pstr)
*pstr = overlay_str_buf;
return total;
@@ -3699,7 +3699,6 @@ fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
beforep->next = current_buffer->overlays_before;
set_buffer_overlays_before (current_buffer, before_list);
}
- recenter_overlay_lists (current_buffer, current_buffer->overlay_center);
if (afterp)
{
@@ -3857,17 +3856,16 @@ for the rear of the overlay advance when text is inserted there
end = OVERLAY_END (overlay);
if (OVERLAY_POSITION (end) < b->overlay_center)
{
- if (b->overlays_after)
- XOVERLAY (overlay)->next = b->overlays_after;
+ eassert (b->overlays_after || (XOVERLAY (overlay)->next == NULL));
+ XOVERLAY (overlay)->next = b->overlays_after;
set_buffer_overlays_after (b, XOVERLAY (overlay));
}
else
{
- if (b->overlays_before)
- XOVERLAY (overlay)->next = b->overlays_before;
+ eassert (b->overlays_before || (XOVERLAY (overlay)->next == NULL));
+ XOVERLAY (overlay)->next = b->overlays_before;
set_buffer_overlays_before (b, XOVERLAY (overlay));
}
-
/* This puts it in the right list, and in the right order. */
recenter_overlay_lists (b, b->overlay_center);
@@ -3891,17 +3889,17 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
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);
}
@@ -4151,7 +4149,7 @@ DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
/* Put all the overlays we want in a vector in overlay_vec.
Store the length in len. */
noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
- 0, 0, 0);
+ NULL, NULL, 0);
/* Make a list of them all. */
result = Flist (noverlays, overlay_vec);
@@ -4594,7 +4592,7 @@ buffer_slot_type_mismatch (Lisp_Object newval, int type)
case_Lisp_Int: predicate = Qintegerp; break;
case Lisp_String: predicate = Qstringp; break;
case Lisp_Symbol: predicate = Qsymbolp; break;
- default: abort ();
+ default: emacs_abort ();
}
wrong_type_argument (predicate, newval);
@@ -5042,7 +5040,7 @@ alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
{
void *p;
- BLOCK_INPUT;
+ block_input ();
#if defined USE_MMAP_FOR_BUFFERS
p = mmap_alloc ((void **) &b->text->beg, nbytes);
#elif defined REL_ALLOC
@@ -5053,12 +5051,12 @@ alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
if (p == NULL)
{
- UNBLOCK_INPUT;
+ unblock_input ();
memory_full (nbytes);
}
b->text->beg = (unsigned char *) p;
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Enlarge buffer B's text buffer by DELTA bytes. DELTA < 0 means
@@ -5070,7 +5068,7 @@ enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
void *p;
ptrdiff_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
+ delta);
- BLOCK_INPUT;
+ block_input ();
#if defined USE_MMAP_FOR_BUFFERS
p = mmap_realloc ((void **) &b->text->beg, nbytes);
#elif defined REL_ALLOC
@@ -5081,12 +5079,12 @@ enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
if (p == NULL)
{
- UNBLOCK_INPUT;
+ unblock_input ();
memory_full (nbytes);
}
BUF_BEG_ADDR (b) = (unsigned char *) p;
- UNBLOCK_INPUT;
+ unblock_input ();
}
@@ -5095,7 +5093,7 @@ enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
static void
free_buffer_text (struct buffer *b)
{
- BLOCK_INPUT;
+ block_input ();
#if defined USE_MMAP_FOR_BUFFERS
mmap_free ((void **) &b->text->beg);
@@ -5106,7 +5104,7 @@ free_buffer_text (struct buffer *b)
#endif
BUF_BEG_ADDR (b) = NULL;
- UNBLOCK_INPUT;
+ unblock_input ();
}
@@ -5119,11 +5117,6 @@ void
init_buffer_once (void)
{
int idx;
- /* If you add, remove, or reorder Lisp_Objects in a struct buffer, make
- sure that this is still correct. Otherwise, mark_vectorlike may not
- trace all Lisp_Objects in buffer_defaults and buffer_local_symbols. */
- const int pvecsize
- = (offsetof (struct buffer, own_text) - header_size) / word_size;
memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags);
@@ -5141,12 +5134,16 @@ init_buffer_once (void)
/* 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);
- XSETPVECTYPESIZE (&buffer_defaults, PVEC_BUFFER, pvecsize);
- XSETBUFFER (Vbuffer_defaults, &buffer_defaults);
- XSETPVECTYPESIZE (&buffer_local_symbols, PVEC_BUFFER, pvecsize);
- XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols);
+ /* This is not strictly necessary, but let's make them initialized. */
+ bset_name (&buffer_defaults, build_pure_c_string (" *buffer-defaults*"));
+ bset_name (&buffer_local_symbols, build_pure_c_string (" *buffer-local-symbols*"));
+ BUFFER_PVEC_INIT (&buffer_defaults);
+ BUFFER_PVEC_INIT (&buffer_local_symbols);
/* Set up the default values of various buffer slots. */
/* Must do these before making the first buffer! */
@@ -5275,7 +5272,7 @@ init_buffer_once (void)
/* Need more room? */
if (idx >= MAX_PER_BUFFER_VARS)
- abort ();
+ emacs_abort ();
last_per_buffer_idx = idx;
Vbuffer_alist = Qnil;
@@ -5416,7 +5413,7 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
if (PER_BUFFER_IDX (offset) == 0)
/* Did a DEFVAR_PER_BUFFER without initializing the corresponding
slot of buffer_local_flags */
- abort ();
+ emacs_abort ();
}
@@ -5428,8 +5425,6 @@ syms_of_buffer (void)
last_overlay_modification_hooks
= Fmake_vector (make_number (10), Qnil);
- staticpro (&Vbuffer_defaults);
- staticpro (&Vbuffer_local_symbols);
staticpro (&Qfundamental_mode);
staticpro (&Qmode_class);
staticpro (&QSFundamental);
@@ -6218,15 +6213,15 @@ is a member of the list. */);
doc: /* Cursor to use when this buffer is in the selected window.
Values are interpreted as follows:
- t use the cursor specified for the frame
- nil don't display a cursor
- box display a filled box cursor
- hollow display a hollow box cursor
- bar display a vertical bar cursor with default width
- (bar . WIDTH) display a vertical bar cursor with width WIDTH
- hbar display a horizontal bar cursor with default height
+ t use the cursor specified for the frame
+ nil don't display a cursor
+ box display a filled box cursor
+ hollow display a hollow box cursor
+ bar display a vertical bar cursor with default width
+ (bar . WIDTH) display a vertical bar cursor with width WIDTH
+ hbar display a horizontal bar cursor with default height
(hbar . HEIGHT) display a horizontal bar cursor with height HEIGHT
- ANYTHING ELSE display a hollow box cursor
+ ANYTHING ELSE display a hollow box cursor
When the buffer is displayed in a non-selected window, the
cursor's appearance is instead controlled by the variable