* buffer.c (reset_buffer): Do INITIALIZE_INTERVAL on the buffer's
[bpt/emacs.git] / src / buffer.c
index ad70801..96327b3 100644 (file)
@@ -85,6 +85,14 @@ struct buffer buffer_local_symbols;
 /* 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;
@@ -172,6 +180,7 @@ int buffer_count;
 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)
@@ -262,6 +271,10 @@ reset_buffer (b)
   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);
 }
 
@@ -526,13 +539,14 @@ This does not change the name of the visited file (if any).")
   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;
@@ -544,7 +558,10 @@ If BUFFER is omitted or nil, some interesting buffer is returned.")
        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))
@@ -716,6 +733,10 @@ with `delete-process'.")
     }
   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;
@@ -903,18 +924,14 @@ 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.\n\
-If the argument is nil, bury the current buffer\n\
-and switch to some other buffer in the selected window.")
+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;
@@ -923,13 +940,23 @@ and switch to some other buffer in the selected window.")
       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
@@ -1201,6 +1228,34 @@ if any protected fields overlap this portion.")
   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;
@@ -1378,7 +1433,8 @@ This is the same as (default-value 'tab-width).");
     "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", &current_buffer->mode_line_format, 0);
+  DEFVAR_PER_BUFFER ("mode-line-format", &current_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!
@@ -1415,53 +1471,61 @@ Decimal digits after the % specify field width to which to pad.");
 nil here means use current buffer's major mode.");
 
   DEFVAR_PER_BUFFER ("major-mode", &current_buffer->major_mode,
+                    make_number (Lisp_Symbol),
     "Symbol for current buffer's major mode.");
 
   DEFVAR_PER_BUFFER ("mode-name", &current_buffer->mode_name,
+                     make_number (Lisp_String),
     "Pretty name of current buffer's major mode (a string).");
 
-  DEFVAR_PER_BUFFER ("abbrev-mode", &current_buffer->abbrev_mode,
+  DEFVAR_PER_BUFFER ("abbrev-mode", &current_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", &current_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", &current_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", &current_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", &current_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", &current_buffer->ctl_arrow,
+  DEFVAR_PER_BUFFER ("ctl-arrow", &current_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", &current_buffer->truncate_lines,
+  DEFVAR_PER_BUFFER ("truncate-lines", &current_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", &current_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", &current_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\
@@ -1469,30 +1533,34 @@ NOTE: This variable is not an ordinary hook;\n\
 It may not be a list of functions.");
 
   DEFVAR_PER_BUFFER ("buffer-file-name", &current_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",
-                   &current_buffer->auto_save_file_name,
+                    &current_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", &current_buffer->read_only,
+  DEFVAR_PER_BUFFER ("buffer-read-only", &current_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", &current_buffer->backed_up,
+  DEFVAR_PER_BUFFER ("buffer-backed-up", &current_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", &current_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", &current_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\
@@ -1503,15 +1571,17 @@ Automatically becomes buffer-local when set in any fashion.");
 #ifndef old
   DEFVAR_PER_BUFFER ("selective-display-ellipses",
                    &current_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", &current_buffer->overwrite_mode,
+  DEFVAR_PER_BUFFER ("overwrite-mode", &current_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", &current_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\
@@ -1527,7 +1597,7 @@ The remaining five elements are ropes that control the display of\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", &current_buffer->fieldlist,
+  DEFVAR_PER_BUFFER ("buffer-field-list", &current_buffer->fieldlist, Qnil,
     "List of fields in the current buffer.  See `add-field'.");
 
   DEFVAR_BOOL ("check-protected-fields", check_protected_fields,
@@ -1568,7 +1638,7 @@ cause calls to any `before-change-function' or `after-change-function'.");
 The function is called, with no arguments, if it is non-nil.");
   Vfirst_change_function = Qnil;
 
-  DEFVAR_PER_BUFFER ("buffer-undo-list", &current_buffer->undo_list,
+  DEFVAR_PER_BUFFER ("buffer-undo-list", &current_buffer->undo_list, Qnil,
     "List of undo entries in current buffer.\n\
 Recent changes come first; older changes follow newer.\n\
 \n\