/* Buffer manipulation primitives for GNU Emacs.
- Copyright (C) 1985, 1986, 1987, 1988, 1989 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* A Lisp_Object pointer to the above, used for staticpro */
static Lisp_Object Vbuffer_local_symbols;
+/* This structure holds the required types for the values in the
+ buffer-local slots. If a slot contains Qnil, then the
+ corresponding buffer slot may contain a value of any type. If a
+ slot contains an integer, then prospective values' tags must be
+ equal to that integer. When a tag does not match, the function
+ buffer_slot_type_mismatch will signal an error. */
+struct buffer buffer_local_types;
+
/* Nonzero means don't allow modification of protected fields. */
int check_protected_fields;
DEFUN ("get-buffer-create", Fget_buffer_create, Sget_buffer_create, 1, 1, 0,
"Return the buffer named NAME, or create such a buffer and return it.\n\
A new buffer is created if there is no live buffer named NAME.\n\
+If NAME starts with a space, the new buffer does not keep undo information.\n\
If NAME is a buffer instead of a string, then it is the value returned.\n\
The value is never nil.")
(name)
b->auto_save_file_name = Qnil;
b->read_only = Qnil;
b->fieldlist = Qnil;
+
+ /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
+ INITIALIZE_INTERVAL (b, NULL_INTERVAL);
+
reset_buffer_local_variables(b);
}
return name;
}
-DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 1, 0,
+DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 2, 0,
"Return most recently selected buffer other than BUFFER.\n\
-Buffers not visible in windows are preferred to visible buffers.\n\
+Buffers not visible in windows are preferred to visible buffers,\n\
+unless optional second argument VISIBLE-OK is non-nil.\n\
If no other buffer exists, the buffer `*scratch*' is returned.\n\
If BUFFER is omitted or nil, some interesting buffer is returned.")
- (buffer)
- register Lisp_Object buffer;
+ (buffer, visible_ok)
+ register Lisp_Object buffer, visible_ok;
{
register Lisp_Object tail, buf, notsogood, tem;
notsogood = Qnil;
continue;
if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
continue;
- tem = Fget_buffer_window (buf, Qnil);
+ if (NILP (visible_ok))
+ tem = Fget_buffer_window (buf, Qnil);
+ else
+ tem = Qnil;
if (NILP (tem))
return buf;
if (NILP (notsogood))
DEFUN ("buffer-disable-undo", Fbuffer_disable_undo, Sbuffer_disable_undo, 1,1,
0,
"Make BUFFER stop keeping undo information.")
- (buf)
- register Lisp_Object buf;
+ (buffer)
+ register Lisp_Object buffer;
{
- CHECK_BUFFER (buf, 0);
- XBUFFER (buf)->undo_list = Qt;
+ Lisp_Object real_buffer;
+
+ if (NILP (buffer))
+ XSET (real_buffer, Lisp_Buffer, current_buffer);
+ else
+ {
+ real_buffer = Fget_buffer (buffer);
+ if (NILP (real_buffer))
+ nsberror (buffer);
+ }
+
+ XBUFFER (real_buffer)->undo_list = Qt;
+
return Qnil;
}
0, 1, "",
"Start keeping undo information for buffer BUFFER.\n\
No argument or nil as argument means do this for the current buffer.")
- (buf)
- register Lisp_Object buf;
+ (buffer)
+ register Lisp_Object buffer;
{
- register struct buffer *b;
- register Lisp_Object buf1;
+ Lisp_Object real_buffer;
- if (NILP (buf))
- b = current_buffer;
+ if (NILP (buffer))
+ XSET (real_buffer, Lisp_Buffer, current_buffer);
else
{
- buf1 = Fget_buffer (buf);
- if (NILP (buf1)) nsberror (buf);
- b = XBUFFER (buf1);
+ real_buffer = Fget_buffer (buffer);
+ if (NILP (real_buffer))
+ nsberror (buffer);
}
- if (EQ (b->undo_list, Qt))
- b->undo_list = Qnil;
+ if (EQ (XBUFFER (real_buffer)->undo_list, Qt))
+ XBUFFER (real_buffer)->undo_list = Qnil;
return Qnil;
}
unlock_buffer (b);
#endif /* CLASH_DETECTION */
-#ifdef subprocesses
kill_buffer_processes (buf);
-#endif /* subprocesses */
tem = Vinhibit_quit;
Vinhibit_quit = Qt;
}
b->markers = Qnil;
+ /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
+ INITIALIZE_INTERVAL (b, NULL_INTERVAL);
+ /* Perhaps we should explicitly free the interval tree here... */
+
b->name = Qnil;
BUFFER_FREE (BUF_BEG_ADDR (b));
b->undo_list = Qnil;
return Qt;
}
\f
-/* Put the element for buffer BUF at the front of buffer-alist.
- This is done when a buffer is selected "visibly".
- It keeps buffer-alist in the order of recency of selection
- so that other_buffer will return something nice. */
+/* Move the assoc for buffer BUF to the front of buffer-alist. Since
+ we do this each time BUF is selected visibly, the more recently
+ selected buffers are always closer to the front of the list. This
+ means that other_buffer is more likely to choose a relevant buffer. */
record_buffer (buf)
Lisp_Object buf;
prev = link;
}
- /* Effectively do Vbuffer_alist = Fdelq (link, Vbuffer_alist)
- but cannot use Fdelq here it that allows quitting. */
+ /* Effectively do Vbuffer_alist = Fdelq (link, Vbuffer_alist);
+ we cannot use Fdelq itself here because it allows quitting. */
if (NILP (prev))
Vbuffer_alist = XCONS (Vbuffer_alist)->cdr;
DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "",
"Put BUFFER at the end of the list of all buffers.\n\
There it is the least likely candidate for `other-buffer' to return;\n\
-thus, the least likely buffer for \\[switch-to-buffer] to select by default.")
+thus, the least likely buffer for \\[switch-to-buffer] to select by default.\n\
+BUFFER is also removed from the selected window if it was displayed there.\n\
+If BUFFER is omitted, the current buffer is buried.")
(buf)
register Lisp_Object buf;
{
- register Lisp_Object aelt, link;
-
+ /* Figure out what buffer we're going to bury. */
if (NILP (buf))
- {
- XSET (buf, Lisp_Buffer, current_buffer);
- Fswitch_to_buffer (Fother_buffer (buf), Qnil);
- }
+ XSET (buf, Lisp_Buffer, current_buffer);
else
{
Lisp_Object buf1;
if (NILP (buf1))
nsberror (buf);
buf = buf1;
- }
+ }
+
+ /* Remove it from the screen. */
+ if (EQ (buf, XWINDOW (selected_window)->buffer))
+ Fswitch_to_buffer (Fother_buffer (buf), Qnil);
+
+ /* Move it to the end of the buffer list. */
+ {
+ register Lisp_Object aelt, link;
+
+ aelt = Frassq (buf, Vbuffer_alist);
+ link = Fmemq (aelt, Vbuffer_alist);
+ Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
+ XCONS (link)->cdr = Qnil;
+ Vbuffer_alist = nconc2 (Vbuffer_alist, link);
+ }
- aelt = Frassq (buf, Vbuffer_alist);
- link = Fmemq (aelt, Vbuffer_alist);
- Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
- XCONS (link)->cdr = Qnil;
- Vbuffer_alist = nconc2 (Vbuffer_alist, link);
return Qnil;
}
\f
return collector;
}
\f
+/* Somebody has tried to store NEWVAL into the buffer-local slot with
+ offset XUINT (valcontents), and NEWVAL has an unacceptable type. */
+void
+buffer_slot_type_mismatch (valcontents, newval)
+ Lisp_Object valcontents, newval;
+{
+ unsigned int offset = XUINT (valcontents);
+ char *symbol_name =
+ (XSYMBOL (*(Lisp_Object *)(offset + (char *)&buffer_local_symbols))
+ ->name->data);
+ char *type_name;
+
+ switch (XINT (*(Lisp_Object *)(offset + (char *)&buffer_local_types)))
+ {
+ case Lisp_Int: type_name = "integers"; break;
+ case Lisp_String: type_name = "strings"; break;
+ case Lisp_Marker: type_name = "markers"; break;
+ case Lisp_Symbol: type_name = "symbols"; break;
+ case Lisp_Cons: type_name = "lists"; break;
+ case Lisp_Vector: type_name = "vector"; break;
+ default:
+ abort ();
+ }
+
+ error ("only %s should be stored in the buffer-local variable %s",
+ type_name, symbol_name);
+}
+\f
init_buffer_once ()
{
register Lisp_Object tem;
/* super-magic invisible buffer */
Vbuffer_alist = Qnil;
- tem = Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
- /* Want no undo records for *scratch*
- until after Emacs is dumped */
- Fbuffer_disable_undo (tem);
+ Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
}
init_buffer ()
"Default value of `case-fold-search' for buffers that don't override it.\n\
This is the same as (default-value 'case-fold-search).");
- DEFVAR_PER_BUFFER ("mode-line-format", ¤t_buffer->mode_line_format, 0);
+ DEFVAR_PER_BUFFER ("mode-line-format", ¤t_buffer->mode_line_format,
+ Qnil, 0);
/* This doc string is too long for cpp; cpp dies if it isn't in a comment.
But make-docfile finds it!
nil here means use current buffer's major mode.");
DEFVAR_PER_BUFFER ("major-mode", ¤t_buffer->major_mode,
+ make_number (Lisp_Symbol),
"Symbol for current buffer's major mode.");
DEFVAR_PER_BUFFER ("mode-name", ¤t_buffer->mode_name,
+ make_number (Lisp_String),
"Pretty name of current buffer's major mode (a string).");
- DEFVAR_PER_BUFFER ("abbrev-mode", ¤t_buffer->abbrev_mode,
+ DEFVAR_PER_BUFFER ("abbrev-mode", ¤t_buffer->abbrev_mode, Qnil,
"Non-nil turns on automatic expansion of abbrevs as they are inserted.\n\
Automatically becomes buffer-local when set in any fashion.");
DEFVAR_PER_BUFFER ("case-fold-search", ¤t_buffer->case_fold_search,
+ Qnil,
"*Non-nil if searches should ignore case.\n\
Automatically becomes buffer-local when set in any fashion.");
DEFVAR_PER_BUFFER ("fill-column", ¤t_buffer->fill_column,
+ make_number (Lisp_Int),
"*Column beyond which automatic line-wrapping should happen.\n\
Automatically becomes buffer-local when set in any fashion.");
DEFVAR_PER_BUFFER ("left-margin", ¤t_buffer->left_margin,
+ make_number (Lisp_Int),
"*Column for the default indent-line-function to indent to.\n\
Linefeed indents to this column in Fundamental mode.\n\
Automatically becomes buffer-local when set in any fashion.");
DEFVAR_PER_BUFFER ("tab-width", ¤t_buffer->tab_width,
+ make_number (Lisp_Int),
"*Distance between tab stops (for display of tab characters), in columns.\n\
Automatically becomes buffer-local when set in any fashion.");
- DEFVAR_PER_BUFFER ("ctl-arrow", ¤t_buffer->ctl_arrow,
+ DEFVAR_PER_BUFFER ("ctl-arrow", ¤t_buffer->ctl_arrow, Qnil,
"*Non-nil means display control chars with uparrow.\n\
Nil means use backslash and octal digits.\n\
Automatically becomes buffer-local when set in any fashion.\n\
This variable does not apply to characters whose display is specified\n\
in the current display table (if there is one).");
- DEFVAR_PER_BUFFER ("truncate-lines", ¤t_buffer->truncate_lines,
+ DEFVAR_PER_BUFFER ("truncate-lines", ¤t_buffer->truncate_lines, Qnil,
"*Non-nil means do not display continuation lines;\n\
give each line of text one screen line.\n\
Automatically becomes buffer-local when set in any fashion.\n\
\n\
Note that this is overridden by the variable\n\
`truncate-partial-width-windows' if that variable is non-nil\n\
-and this buffer is not full-screen width.");
+and this buffer is not full-frame width.");
DEFVAR_PER_BUFFER ("default-directory", ¤t_buffer->directory,
+ make_number (Lisp_String),
"Name of default directory of current buffer. Should end with slash.\n\
Each buffer has its own value of this variable.");
DEFVAR_PER_BUFFER ("auto-fill-function", ¤t_buffer->auto_fill_function,
+ Qnil,
"Function called (if non-nil) to perform auto-fill.\n\
It is called after self-inserting a space at a column beyond `fill-column'.\n\
Each buffer has its own value of this variable.\n\
It may not be a list of functions.");
DEFVAR_PER_BUFFER ("buffer-file-name", ¤t_buffer->filename,
+ make_number (Lisp_String),
"Name of file visited in current buffer, or nil if not visiting a file.\n\
Each buffer has its own value of this variable.");
DEFVAR_PER_BUFFER ("buffer-auto-save-file-name",
- ¤t_buffer->auto_save_file_name,
+ ¤t_buffer->auto_save_file_name,
+ make_number (Lisp_String),
"Name of file for auto-saving current buffer,\n\
or nil if buffer should not be auto-saved.\n\
Each buffer has its own value of this variable.");
- DEFVAR_PER_BUFFER ("buffer-read-only", ¤t_buffer->read_only,
+ DEFVAR_PER_BUFFER ("buffer-read-only", ¤t_buffer->read_only, Qnil,
"Non-nil if this buffer is read-only.\n\
Each buffer has its own value of this variable.");
- DEFVAR_PER_BUFFER ("buffer-backed-up", ¤t_buffer->backed_up,
+ DEFVAR_PER_BUFFER ("buffer-backed-up", ¤t_buffer->backed_up, Qnil,
"Non-nil if this buffer's file has been backed up.\n\
Backing up is done before the first time the file is saved.\n\
Each buffer has its own value of this variable.");
DEFVAR_PER_BUFFER ("buffer-saved-size", ¤t_buffer->save_length,
+ make_number (Lisp_Int),
"Length of current buffer when last read in, saved or auto-saved.\n\
0 initially.\n\
Each buffer has its own value of this variable.");
DEFVAR_PER_BUFFER ("selective-display", ¤t_buffer->selective_display,
+ Qnil,
"Non-nil enables selective display:\n\
Integer N as value means display only lines\n\
that start with less than n columns of space.\n\
#ifndef old
DEFVAR_PER_BUFFER ("selective-display-ellipses",
¤t_buffer->selective_display_ellipses,
+ Qnil,
"t means display ... on previous line when a line is invisible.\n\
Automatically becomes buffer-local when set in any fashion.");
#endif
- DEFVAR_PER_BUFFER ("overwrite-mode", ¤t_buffer->overwrite_mode,
+ DEFVAR_PER_BUFFER ("overwrite-mode", ¤t_buffer->overwrite_mode, Qnil,
"Non-nil if self-insertion should replace existing text.\n\
Automatically becomes buffer-local when set in any fashion.");
DEFVAR_PER_BUFFER ("buffer-display-table", ¤t_buffer->display_table,
+ Qnil,
"Display table that controls display of the contents of current buffer.\n\
Automatically becomes buffer-local when set in any fashion.\n\
The display table is a vector created with `make-display-table'.\n\
If this variable is nil, the value of `standard-display-table' is used.\n\
Each window can have its own, overriding display table.");
- DEFVAR_PER_BUFFER ("buffer-field-list", ¤t_buffer->fieldlist,
+ DEFVAR_PER_BUFFER ("buffer-field-list", ¤t_buffer->fieldlist, Qnil,
"List of fields in the current buffer. See `add-field'.");
DEFVAR_BOOL ("check-protected-fields", check_protected_fields,
The function is called, with no arguments, if it is non-nil.");
Vfirst_change_function = Qnil;
- DEFVAR_PER_BUFFER ("buffer-undo-list", ¤t_buffer->undo_list,
+ DEFVAR_PER_BUFFER ("buffer-undo-list", ¤t_buffer->undo_list, Qnil,
"List of undo entries in current buffer.\n\
Recent changes come first; older changes follow newer.\n\
\n\