/* Buffer manipulation primitives for GNU Emacs.
- Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995, 1997, 1998
+ Copyright (C) 1985,86,87,88,89,93,94,95,97,98, 1999
Free Software Foundation, Inc.
This file is part of GNU Emacs.
Lisp_Object Qbefore_change_functions;
Lisp_Object Qafter_change_functions;
+/* If nonzero, all modification hooks are suppressed. */
+int inhibit_modification_hooks;
+
Lisp_Object Qfundamental_mode, Qmode_class, Qpermanent_local;
Lisp_Object Qprotected_field;
b->mark = Fmake_marker ();
b->name = name;
+ /* The multibyte status belongs to the base buffer. */
+ b->enable_multibyte_characters = b->base_buffer->enable_multibyte_characters;
+
/* Make sure the base buffer has markers for its narrowing. */
if (NILP (b->base_buffer->pt_marker))
{
b->file_format = Qnil;
b->last_selected_window = Qnil;
XSETINT (b->display_count, 0);
+ b->display_time = Qnil;
b->extra2 = Qnil;
b->extra3 = Qnil;
b->enable_multibyte_characters = buffer_defaults.enable_multibyte_characters;
If buffer becoming unmodified, unlock the file. */
fn = current_buffer->file_truename;
- if (!NILP (fn))
+ /* Test buffer-file-name so that binding it to nil is effective. */
+ if (!NILP (fn) && ! NILP (current_buffer->filename))
{
already = SAVE_MODIFF < MODIFF;
if (!already && !NILP (flag))
return current_buffer->name;
}
-DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 2, 0,
+DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0,
"Return most recently selected buffer other than BUFFER.\n\
Buffers not visible in windows are preferred to visible buffers,\n\
unless optional second argument VISIBLE-OK is non-nil.\n\
+If the optional third argument FRAME is non-nil, use that frame's\n\
+buffer list instead of the selected frame's buffer list.\n\
If no other buffer exists, the buffer `*scratch*' is returned.\n\
If BUFFER is omitted or nil, some interesting buffer is returned.")
- (buffer, visible_ok)
- register Lisp_Object buffer, visible_ok;
+ (buffer, visible_ok, frame)
+ register Lisp_Object buffer, visible_ok, frame;
{
Lisp_Object Fset_buffer_major_mode ();
register Lisp_Object tail, buf, notsogood, tem, pred, add_ons;
notsogood = Qnil;
+ if (NILP (frame))
+ frame = Fselected_frame ();
+
tail = Vbuffer_alist;
- pred = frame_buffer_predicate ();
+ pred = frame_buffer_predicate (frame);
/* Consider buffers that have been seen in the selected frame
before other buffers. */
- tem = frame_buffer_list ();
+ tem = frame_buffer_list (frame);
add_ons = Qnil;
while (CONSP (tem))
{
and give up if so. */
if (b == current_buffer)
{
- tem = Fother_buffer (buf, Qnil);
+ tem = Fother_buffer (buf, Qnil, Qnil);
Fset_buffer (tem);
if (b == current_buffer)
return Qnil;
Lisp_Object buf;
{
register Lisp_Object link, prev;
+ Lisp_Object frame;
+ frame = Fselected_frame ();
prev = Qnil;
for (link = Vbuffer_alist; CONSP (link); link = XCONS (link)->cdr)
/* Now move this buffer to the front of frame_buffer_list also. */
prev = Qnil;
- for (link = frame_buffer_list (); CONSP (link); link = XCONS (link)->cdr)
+ for (link = frame_buffer_list (frame); CONSP (link);
+ link = XCONS (link)->cdr)
{
if (EQ (XCONS (link)->car, buf))
break;
if (CONSP (link))
{
if (NILP (prev))
- set_frame_buffer_list (XCONS (frame_buffer_list ())->cdr);
+ set_frame_buffer_list (frame,
+ XCONS (frame_buffer_list (frame))->cdr);
else
XCONS (prev)->cdr = XCONS (XCONS (prev)->cdr)->cdr;
- XCONS (link)->cdr = frame_buffer_list ();
- set_frame_buffer_list (link);
+ XCONS (link)->cdr = frame_buffer_list (frame);
+ set_frame_buffer_list (frame, link);
}
else
- set_frame_buffer_list (Fcons (buf, frame_buffer_list ()));
+ set_frame_buffer_list (frame, Fcons (buf, frame_buffer_list (frame)));
}
DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0,
error ("Cannot switch buffers in a dedicated window");
if (NILP (buffer))
- buf = Fother_buffer (Fcurrent_buffer (), Qnil);
+ buf = Fother_buffer (Fcurrent_buffer (), Qnil, Qnil);
else
{
buf = Fget_buffer (buffer);
{
register Lisp_Object buf;
if (NILP (buffer))
- buf = Fother_buffer (Fcurrent_buffer (), Qnil);
+ buf = Fother_buffer (Fcurrent_buffer (), Qnil, Qnil);
else
{
buf = Fget_buffer (buffer);
XSETBUFFER (buffer, current_buffer);
/* If we're burying the current buffer, unshow it. */
- Fswitch_to_buffer (Fother_buffer (buffer, Qnil), Qnil);
+ Fswitch_to_buffer (Fother_buffer (buffer, Qnil, Qnil), Qnil);
}
else
{
Lisp_Object flag;
{
Lisp_Object tail, markers;
+ struct buffer *other;
+
+ if (current_buffer->base_buffer)
+ error ("Cannot do `set-buffer-multibyte' on an indirect buffer");
/* Do nothing if nothing actually changes. */
if (NILP (flag) == NILP (current_buffer->enable_multibyte_characters))
}
tail = markers = BUF_MARKERS (current_buffer);
+
+ /* This prevents BYTE_TO_CHAR (that is, buf_bytepos_to_charpos) from
+ getting confused by the markers that have not yet been updated.
+ It is also a signal that it should never create a marker. */
BUF_MARKERS (current_buffer) = Qnil;
while (XSYMBOL (tail) != XSYMBOL (Qnil))
tail = XMARKER (tail)->chain;
}
+
+ /* Make sure no markers were put on the chain
+ while the chain value was incorrect. */
+ if (! EQ (BUF_MARKERS (current_buffer), Qnil))
+ abort ();
+
BUF_MARKERS (current_buffer) = markers;
/* Do this last, so it can calculate the new correspondences
set_intervals_multibyte (1);
}
+ /* Copy this buffer's new multibyte status
+ into all of its indirect buffers. */
+ for (other = all_buffers; other; other = other->next)
+ if (other->base_buffer == current_buffer && !NILP (other->name))
+ other->enable_multibyte_characters
+ = current_buffer->enable_multibyte_characters;
+
return flag;
}
\f
buffer_defaults.cache_long_line_scans = Qnil;
buffer_defaults.file_truename = Qnil;
XSETFASTINT (buffer_defaults.display_count, 0);
+ buffer_defaults.display_time = Qnil;
/* Assign the local-flags to the slots that have default values.
The local flag is a bit that is used in the buffer
XSETINT (buffer_local_flags.invisibility_spec, -1);
XSETINT (buffer_local_flags.file_format, -1);
XSETINT (buffer_local_flags.display_count, -1);
+ XSETINT (buffer_local_flags.display_time, -1);
XSETINT (buffer_local_flags.enable_multibyte_characters, -1);
XSETFASTINT (buffer_local_flags.mode_line_format, 1);
Vbuffer_alist = Qnil;
Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
+
+ inhibit_modification_hooks = 0;
}
void
/* If PWD is accurate, use it instead of calling getwd. This is faster
when PWD is right, and may avoid a fatal error. */
- if ((pwd = getenv ("PWD")) != 0 && IS_DIRECTORY_SEP (*pwd)
+ if ((pwd = getenv ("PWD")) != 0
+ && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
&& stat (pwd, &pwdstat) == 0
&& stat (".", &dotstat) == 0
&& dotstat.st_ino == pwdstat.st_ino
DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters",
&buffer_defaults.enable_multibyte_characters,
- "Default value of `enable-multibyte-characters' for buffers not overriding it.\n\
- This is the same as (default-value 'enable-multibyte-characters).");
+ "*Default value of `enable-multibyte-characters' for buffers not overriding it.\n\
+This is the same as (default-value 'enable-multibyte-characters).");
DEFVAR_LISP_NOPRO ("default-buffer-file-coding-system",
&buffer_defaults.buffer_file_coding_system,
"Default value of `buffer-file-coding-system' for buffers not overriding it.\n\
- This is the same as (default-value 'buffer-file-coding-system).");
+This is the same as (default-value 'buffer-file-coding-system).");
DEFVAR_LISP_NOPRO ("default-truncate-lines",
&buffer_defaults.truncate_lines,
DEFVAR_PER_BUFFER ("case-fold-search", ¤t_buffer->case_fold_search,
Qnil,
- "*Non-nil if searches should ignore case.\n\
+ "*Non-nil if searches and matches should ignore case.\n\
Automatically becomes buffer-local when set in any fashion.");
DEFVAR_PER_BUFFER ("fill-column", ¤t_buffer->fill_column,
DEFVAR_PER_BUFFER ("enable-multibyte-characters",
¤t_buffer->enable_multibyte_characters,
make_number (-1),
- "*Non-nil means the buffer contents are regarded as multi-byte form\n\
-of characters, not a binary code. This affects the display, file I/O,\n\
-and behaviors of various editing commands.");
+ "Non-nil means the buffer contents are regarded as multi-byte characters.\n\
+Otherwise they are regarded as unibyte. This affects the display,\n\
+file I/O and the behavior of various editing commands.\n\
+\n\
+This variable is buffer-local but you cannot set it directly;\n\
+use the function `set-buffer-multibyte' to change a buffer's representation.\n\
+Changing its default value with `setq-default' is supported.\n\
+See also variable `default-enable-multibyte-characters' and Info node\n\
+`(elisp)Text Representations'.");
DEFVAR_PER_BUFFER ("buffer-file-coding-system",
¤t_buffer->buffer_file_coding_system, Qnil,
"Coding system to be used for encoding the buffer contents on saving.\n\
-If it is nil, the buffer is saved without any code conversion unless\n\
-some coding system is specified in `file-coding-system-alist'\n\
+This variable applies to saving the buffer, and also to `write-region'\n\
+and other functions that use `write-region'.\n\
+It does not apply to sending output to subprocesses, however.\n\
+\n\
+If this is nil, the buffer is saved without any code conversion\n\
+unless some coding system is specified in `file-coding-system-alist'\n\
for the buffer file.\n\
\n\
+The variable `coding-system-for-write', if non-nil, overrides this variable.\n\
+\n\
This variable is never applied to a way of decoding\n\
a file while reading it.");
That's because these variables are temporarily set to nil.\n\
As a result, a hook function cannot straightforwardly alter the value of\n\
these variables. See the Emacs Lisp manual for a way of\n\
-accomplishing an equivalent result by using other variables.");
+accomplishing an equivalent result by using other variables.\n\
+\n\
+If an unhandled error happens in running these functions,\n\
+the variable's value remains nil. That prevents the error\n\
+from happening repeatedly and making Emacs nonfunctional.");
Vbefore_change_functions = Qnil;
DEFVAR_LISP ("after-change-functions", &Vafter_change_functions,
That's because these variables are temporarily set to nil.\n\
As a result, a hook function cannot straightforwardly alter the value of\n\
these variables. See the Emacs Lisp manual for a way of\n\
-accomplishing an equivalent result by using other variables.");
-
+accomplishing an equivalent result by using other variables.\n\
+\n\
+If an unhandled error happens in running these functions,\n\
+the variable's value remains nil. That prevents the error\n\
+from happening repeatedly and making Emacs nonfunctional.");
Vafter_change_functions = Qnil;
DEFVAR_LISP ("first-change-hook", &Vfirst_change_hook,
but make-docfile can find it in this comment. */
DEFVAR_PER_BUFFER ("buffer-undo-list", ¤t_buffer->undo_list, Qnil,
"List of undo entries in current buffer.\n\
+This variable is always local in all buffers.\n\
Recent changes come first; older changes follow newer.\n\
\n\
An entry (BEG . END) represents an insertion which begins at\n\
functions; it should only affect their performance.");
DEFVAR_PER_BUFFER ("point-before-scroll", ¤t_buffer->point_before_scroll, Qnil,
- "Value of point before the last series of scroll operations, or nil.");
+ "Value of point before the last series of scroll operations, or nil.\n\
+This variable is always local in all buffers.");
DEFVAR_PER_BUFFER ("buffer-file-format", ¤t_buffer->file_format, Qnil,
"List of formats to use when saving this buffer.\n\
+This variable is always local in all buffers.\n\
Formats are defined by `format-alist'. This variable is\n\
set when a file is visited. Automatically local in all buffers.");
DEFVAR_PER_BUFFER ("buffer-invisibility-spec",
¤t_buffer->invisibility_spec, Qnil,
"Invisibility spec of this buffer.\n\
+This variable is always local in all buffers.\n\
The default is t, which means that text is invisible\n\
if it has a non-nil `invisible' property.\n\
If the value is a list, a text character is invisible if its `invisible'\n\
DEFVAR_PER_BUFFER ("buffer-display-count",
¤t_buffer->display_count, Qnil,
- "A number incremented each time the buffer is displayed in a window.");
+ "A number incremented each time this buffer is displayed in a window.\n\
+This variable is always local in all buffers.\n\
+The function `set-window-buffer increments it.");
+
+ DEFVAR_PER_BUFFER ("buffer-display-time",
+ ¤t_buffer->display_time, Qnil,
+ "Time stamp updated each time this buffer is displayed in a window.\n\
+This variable is always local in all buffers.\n\
+The function `set-window-buffer' updates this variable\n\
+to the value obtained by calling `current-time'.\n\
+If the buffer has never been shown in a window, the value is nil.");
DEFVAR_LISP ("transient-mark-mode", &Vtransient_mark_mode,
"*Non-nil means deactivate the mark when the buffer contents change.\n\