* lisp.h (enum Lisp_Misc_Type): Del Lisp_Misc_Some_Buffer_Local_Value.
[bpt/emacs.git] / src / buffer.c
index f2f15a5..c53d427 100644 (file)
@@ -1,13 +1,13 @@
 /* Buffer manipulation primitives for GNU Emacs.
    Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994,
                  1995, 1997, 1998, 1999, 2000, 2001, 2002,
-                 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+                 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -361,8 +361,6 @@ The value is never nil.  */)
 
   b = (struct buffer *) allocate_buffer ();
 
-  b->size = sizeof (struct buffer) / sizeof (EMACS_INT);
-
   /* An ordinary buffer uses its own struct buffer_text.  */
   b->text = &b->own_text;
   b->base_buffer = 0;
@@ -416,10 +414,7 @@ The value is never nil.  */)
   STRING_SET_INTERVALS (name, NULL_INTERVAL);
   b->name = name;
 
-  if (SREF (name, 0) != ' ')
-    b->undo_list = Qnil;
-  else
-    b->undo_list = Qt;
+  b->undo_list = (SREF (name, 0) != ' ') ? Qnil : Qt;
 
   reset_buffer (b);
   reset_buffer_local_variables (b, 1);
@@ -432,7 +427,7 @@ The value is never nil.  */)
   XSETBUFFER (buf, b);
   Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil));
 
-  /* An error in calling the function here (should someone redfine it)
+  /* An error in calling the function here (should someone redefine it)
      can lead to infinite regress until you run out of stack.  rms
      says that's not worth protecting against.  */
   if (!NILP (Ffboundp (Qucs_set_table_for_input)))
@@ -566,12 +561,10 @@ CLONE nil means the indirect buffer's state is reset to default values.  */)
     error ("Empty string for buffer name is not allowed");
 
   b = (struct buffer *) allocate_buffer ();
-  b->size = sizeof (struct buffer) / sizeof (EMACS_INT);
 
-  if (XBUFFER (base_buffer)->base_buffer)
-    b->base_buffer = XBUFFER (base_buffer)->base_buffer;
-  else
-    b->base_buffer = XBUFFER (base_buffer);
+  b->base_buffer = (XBUFFER (base_buffer)->base_buffer
+                   ? XBUFFER (base_buffer)->base_buffer
+                   : XBUFFER (base_buffer));
 
   /* Use the base buffer's text object.  */
   b->text = b->base_buffer->text;
@@ -804,9 +797,8 @@ DEFUN ("generate-new-buffer-name", Fgenerate_new_buffer_name, Sgenerate_new_buff
 If there is no live buffer named NAME, then return NAME.
 Otherwise modify name by appending `<NUMBER>', incrementing NUMBER
 \(starting at 2) until an unused name is found, and then return that name.
-Optional second argument IGNORE specifies a name that is okay to use
-\(if it is in the sequence to be tried)
-even if a buffer with that name exists.  */)
+Optional second argument IGNORE specifies a name that is okay to use (if
+it is in the sequence to be tried) even if a buffer with that name exists.  */)
      (name, ignore)
      register Lisp_Object name, ignore;
 {
@@ -1145,8 +1137,8 @@ state of the current buffer.  Use with care.  */)
 DEFUN ("buffer-modified-tick", Fbuffer_modified_tick, Sbuffer_modified_tick,
        0, 1, 0,
        doc: /* Return BUFFER's tick counter, incremented for each change in text.
-Each buffer has a tick counter which is incremented each time the text in
-that buffer is changed.  It wraps around occasionally.
+Each buffer has a tick counter which is incremented each time the
+text in that buffer is changed.  It wraps around occasionally.
 No argument or nil as argument means use current buffer as BUFFER.  */)
      (buffer)
      register Lisp_Object buffer;
@@ -1344,15 +1336,16 @@ See `kill-buffer'."
  */
 DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 1, 1, "bKill buffer: ",
        doc: /* Kill the buffer BUFFER.
-The argument may be a buffer or may be the name of a buffer.
-An argument of nil means kill the current buffer.
+The argument may be a buffer or the name of a buffer.
+With a nil argument, kill the current buffer.
+
+Value is t if the buffer is actually killed, nil otherwise.
 
-Value is t if the buffer is actually killed, nil if user says no.
+The functions in `kill-buffer-query-functions' are called with BUFFER as
+the current buffer.  If any of them returns nil, the buffer is not killed.
 
-The value of `kill-buffer-hook' (which may be local to that buffer),
-if not void, is a list of functions to be called, with no arguments,
-before the buffer is actually killed.  The buffer to be killed is current
-when the hook functions are called.
+The hook `kill-buffer-hook' is run before the buffer is actually killed.
+The buffer being killed will be current while the hook is running.
 
 Any processes that have this buffer as the `process-buffer' are killed
 with SIGHUP.  */)
@@ -1471,7 +1464,16 @@ with SIGHUP.  */)
   unlock_buffer (b);
 #endif /* CLASH_DETECTION */
 
+  GCPRO1 (buf);
   kill_buffer_processes (buf);
+  UNGCPRO;
+
+  /* Killing buffer processes may run sentinels which may
+     have called kill-buffer.  */
+
+  if (NILP (b->name))
+    return Qnil;
+
   clear_charpos_cache (b);
 
   tem = Vinhibit_quit;
@@ -1644,6 +1646,8 @@ the current buffer's major mode.  */)
   int count;
   Lisp_Object function;
 
+  CHECK_BUFFER (buffer);
+
   if (STRINGP (XBUFFER (buffer)->name)
       && strcmp (SDATA (XBUFFER (buffer)->name), "*scratch*") == 0)
     function = find_symbol_value (intern ("initial-major-mode"));
@@ -1905,8 +1909,7 @@ set_buffer_internal_1 (b)
   for (tail = b->local_var_alist; CONSP (tail); tail = XCDR (tail))
     {
       valcontents = SYMBOL_VALUE (XCAR (XCAR (tail)));
-      if ((BUFFER_LOCAL_VALUEP (valcontents)
-          || SOME_BUFFER_LOCAL_VALUEP (valcontents))
+      if ((BUFFER_LOCAL_VALUEP (valcontents))
          && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
              (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem))))
        /* Just reference the variable
@@ -1920,8 +1923,7 @@ set_buffer_internal_1 (b)
     for (tail = old_buf->local_var_alist; CONSP (tail); tail = XCDR (tail))
       {
        valcontents = SYMBOL_VALUE (XCAR (XCAR (tail)));
-       if ((BUFFER_LOCAL_VALUEP (valcontents)
-            || SOME_BUFFER_LOCAL_VALUEP (valcontents))
+       if ((BUFFER_LOCAL_VALUEP (valcontents))
            && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
                (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem))))
          /* Just reference the variable
@@ -2480,7 +2482,7 @@ the normal hook `change-major-mode-hook'.  */)
   /* Any which are supposed to be permanent,
      make local again, with the same values they had.  */
 
-  for (alist = oalist; !NILP (alist); alist = XCDR (alist))
+  for (alist = oalist; CONSP (alist); alist = XCDR (alist))
     {
       sym = XCAR (XCAR (alist));
       tem = Fget (sym, Qpermanent_local);
@@ -2510,7 +2512,7 @@ swap_out_buffer_local_variables (b)
   XSETBUFFER (buffer, b);
   oalist = b->local_var_alist;
 
-  for (alist = oalist; !NILP (alist); alist = XCDR (alist))
+  for (alist = oalist; CONSP (alist); alist = XCDR (alist))
     {
       sym = XCAR (XCAR (alist));
 
@@ -3956,7 +3958,7 @@ OVERLAY.  */)
 
 \f
 DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
-       doc: /* Return a list of the overlays that contain position POS.  */)
+       doc: /* Return a list of the overlays that contain the character at POS.  */)
      (pos)
      Lisp_Object pos;
 {
@@ -4205,15 +4207,8 @@ add_overlay_mod_hooklist (functionlist, overlay)
   int oldsize = XVECTOR (last_overlay_modification_hooks)->size;
 
   if (last_overlay_modification_hooks_used == oldsize)
-    {
-      Lisp_Object old;
-      old = last_overlay_modification_hooks;
-      last_overlay_modification_hooks
-       = Fmake_vector (make_number (oldsize * 2), Qnil);
-      bcopy (XVECTOR (old)->contents,
-            XVECTOR (last_overlay_modification_hooks)->contents,
-            sizeof (Lisp_Object) * oldsize);
-    }
+    last_overlay_modification_hooks = larger_vector 
+      (last_overlay_modification_hooks, oldsize * 2, Qnil);
   AREF (last_overlay_modification_hooks, last_overlay_modification_hooks_used++) = functionlist;
   AREF (last_overlay_modification_hooks, last_overlay_modification_hooks_used++) = overlay;
 }
@@ -5025,7 +5020,9 @@ init_buffer_once ()
   buffer_local_symbols.text = &buffer_local_symbols.own_text;
   BUF_INTERVALS (&buffer_defaults) = 0;
   BUF_INTERVALS (&buffer_local_symbols) = 0;
+  XSETPVECTYPE (&buffer_defaults, PVEC_BUFFER);
   XSETBUFFER (Vbuffer_defaults, &buffer_defaults);
+  XSETPVECTYPE (&buffer_local_symbols, PVEC_BUFFER);
   XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols);
 
   /* Set up the default values of various buffer slots.  */
@@ -5264,6 +5261,46 @@ init_buffer ()
   free (pwd);
 }
 
+/* Similar to defvar_lisp but define a variable whose value is the Lisp
+   Object stored in the current buffer.  address is the address of the slot
+   in the buffer that is current now. */
+
+/* TYPE is nil for a general Lisp variable.
+   An integer specifies a type; then only LIsp values
+   with that type code are allowed (except that nil is allowed too).
+   LNAME is the LIsp-level variable name.
+   VNAME is the name of the buffer slot.
+   DOC is a dummy where you write the doc string as a comment.  */
+#define DEFVAR_PER_BUFFER(lname, vname, type, doc)  \
+ defvar_per_buffer (lname, vname, type, 0)
+
+static void
+defvar_per_buffer (namestring, address, type, doc)
+     char *namestring;
+     Lisp_Object *address;
+     Lisp_Object type;
+     char *doc;
+{
+  Lisp_Object sym, val;
+  int offset;
+
+  sym = intern (namestring);
+  val = allocate_misc ();
+  offset = (char *)address - (char *)current_buffer;
+
+  XMISCTYPE (val) = Lisp_Misc_Buffer_Objfwd;
+  XBUFFER_OBJFWD (val)->offset = offset;
+  SET_SYMBOL_VALUE (sym, val);
+  PER_BUFFER_SYMBOL (offset) = sym;
+  PER_BUFFER_TYPE (offset) = type;
+
+  if (PER_BUFFER_IDX (offset) == 0)
+    /* Did a DEFVAR_PER_BUFFER without initializing the corresponding
+       slot of buffer_local_flags */
+    abort ();
+}
+
+
 /* initialize the buffer routines */
 void
 syms_of_buffer ()
@@ -5385,8 +5422,8 @@ This is the same as (default-value 'fill-column).  */);
 This is the same as (default-value 'left-margin).  */);
 
   DEFVAR_LISP_NOPRO ("default-tab-width",
-             &buffer_defaults.tab_width,
-    doc: /* Default value of `tab-width' for buffers that do not override it.
+                    &buffer_defaults.tab_width,
+                    doc: /* Default value of `tab-width' for buffers that do not override it.
 This is the same as (default-value 'tab-width).  */);
 
   DEFVAR_LISP_NOPRO ("default-case-fold-search",
@@ -5461,13 +5498,13 @@ This is the same as (default-value 'fringe-cursor-alist').  */);
                     &buffer_defaults.scroll_up_aggressively,
                     doc: /* Default value of `scroll-up-aggressively'.
 This value applies in buffers that don't have their own local values.
-This variable is an alias for (default-value 'scroll-up-aggressively).  */);
+This is the same as (default-value 'scroll-up-aggressively).  */);
 
   DEFVAR_LISP_NOPRO ("default-scroll-down-aggressively",
                     &buffer_defaults.scroll_down_aggressively,
                     doc: /* Default value of `scroll-down-aggressively'.
 This value applies in buffers that don't have their own local values.
-This variable is an alias for (default-value 'scroll-down-aggressively).  */);
+This is the same as (default-value 'scroll-down-aggressively).  */);
 
   DEFVAR_PER_BUFFER ("header-line-format",
                     &current_buffer->header_line_format,
@@ -5524,14 +5561,16 @@ A string is printed verbatim in the mode line except for %-constructs:
   %z -- print mnemonics of keyboard, terminal, and buffer coding systems.
   %Z -- like %z, but including the end-of-line format.
   %e -- print error message about full memory.
+  %@ -- print @ or hyphen.  @ means that default-directory is on a
+        remote machine.
   %[ -- print one [ for each recursive editing level.  %] similar.
   %% -- print %.   %- -- print infinitely many dashes.
 Decimal digits after the % specify field width to which to pad.  */);
 
   DEFVAR_LISP_NOPRO ("default-major-mode", &buffer_defaults.major_mode,
                     doc: /* *Major mode for new buffers.  Defaults to `fundamental-mode'.
-nil here means use current buffer's major mode, provided it is not
-marked as "special".
+A value of nil means use current buffer's major mode,
+provided it is not marked as "special".
 
 When a mode is used by default, `find-file' switches to it
 before it reads the contents into the buffer and before
@@ -5547,6 +5586,9 @@ its hooks should not expect certain variables such as
                      Qnil,
                     doc: /* Pretty name of current buffer's major mode (a string).  */);
 
+  DEFVAR_PER_BUFFER ("local-abbrev-table", &current_buffer->abbrev_table, Qnil,
+                    doc: /* Local (mode-specific) abbrev table of current buffer.  */);
+
   DEFVAR_PER_BUFFER ("abbrev-mode", &current_buffer->abbrev_mode, Qnil,
                     doc: /* Non-nil turns on automatic expansion of abbrevs as they are inserted.  */);
 
@@ -5561,7 +5603,7 @@ Interactively, you can set the buffer local value using \\[set-fill-column].  */
 
   DEFVAR_PER_BUFFER ("left-margin", &current_buffer->left_margin,
                     make_number (Lisp_Int),
-                    doc: /* *Column for the default indent-line-function to indent to.
+                    doc: /* *Column for the default `indent-line-function' to indent to.
 Linefeed indents to this column in Fundamental mode.  */);
 
   DEFVAR_PER_BUFFER ("tab-width", &current_buffer->tab_width,
@@ -5671,8 +5713,8 @@ Backing up is done before the first time the file is saved.  */);
   DEFVAR_PER_BUFFER ("selective-display", &current_buffer->selective_display,
                     Qnil,
                     doc: /* Non-nil enables selective display.
-An Integer N as value means display only lines
-that start with less than n columns of space.
+An integer N as value means display only lines
+that start with less than N columns of space.
 A value of t means that the character ^M makes itself and
 all the rest of the line invisible; also, when saving the buffer
 in a file, save the ^M as a newline.  */);
@@ -5708,12 +5750,12 @@ primitives `aref' and `aset' can be used to access elements of a char-table.
 Each of the char-table elements control how to display the corresponding
 text character: the element at index C in the table says how to display
 the character whose code is C.  Each element should be a vector of
-characters or nil.  nil means display the character in the default fashion;
-otherwise, the characters from the vector are delivered to the screen
-instead of the original character.
+characters or nil.  The value nil means display the character in the
+default fashion; otherwise, the characters from the vector are delivered
+to the screen instead of the original character.
 
-For example, (aset buffer-display-table ?X ?Y) will cause Emacs to display
-a capital Y instead of each X character.
+For example, (aset buffer-display-table ?X [?Y]) tells Emacs
+to display a capital Y instead of each X character.
 
 In addition, a char-table has six extra slots to control the display of:
 
@@ -5841,7 +5883,7 @@ cursor type.  */);
                     &current_buffer->scroll_up_aggressively, Qnil,
                     doc: /* How far to scroll windows upward.
 If you move point off the bottom, the window scrolls automatically.
-This variable controls how far it scrolls.  nil, the default,
+This variable controls how far it scrolls.  The value nil, the default,
 means scroll to center point.  A fraction means scroll to put point
 that fraction of the window's height from the bottom of the window.
 When the value is 0.0, point goes at the bottom line, which in the simple
@@ -5854,7 +5896,7 @@ between 0.0 and 1.0, inclusive.  */);
                     &current_buffer->scroll_down_aggressively, Qnil,
                     doc: /* How far to scroll windows downward.
 If you move point off the top, the window scrolls automatically.
-This variable controls how far it scrolls.  nil, the default,
+This variable controls how far it scrolls.  The value nil, the default,
 means scroll to center point.  A fraction means scroll to put point
 that fraction of the window's height from the top of the window.
 When the value is 0.0, point goes at the top line, which in the simple
@@ -5948,8 +5990,8 @@ An entry of the form POSITION indicates that point was at the buffer
 location given by the integer.  Undoing an entry of this form places
 point at POSITION.
 
-nil marks undo boundaries.  The undo command treats the changes
-between two undo boundaries as a single step to be undone.
+Entries with value `nil' mark undo boundaries.  The undo command treats
+the changes between two undo boundaries as a single step to be undone.
 
 If the value of the variable is t, undo information is not recorded.  */);
 
@@ -6005,7 +6047,7 @@ same format as a regular save would use.  */);
 The default is t, which means that text is invisible
 if it has a non-nil `invisible' property.
 If the value is a list, a text character is invisible if its `invisible'
-property is an element in that list.
+property is an element in that list (or is a list with members in common).
 If an element is a cons cell of the form (PROP . ELLIPSIS),
 then characters with property value PROP are invisible,
 and they have an ellipsis as well if ELLIPSIS is non-nil.  */);
@@ -6045,7 +6087,7 @@ is a member of the list.  */);
   Vinhibit_read_only = Qnil;
 
   DEFVAR_PER_BUFFER ("cursor-type", &current_buffer->cursor_type, Qnil,
-     doc: /* Cursor to use when this buffer is in the selected window.
+                    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
@@ -6066,15 +6108,17 @@ this variable has no effect; the cursor appears as a hollow box.  */);
                     doc: /* Additional space to put between lines when displaying a buffer.
 The space is measured in pixels, and put below lines on window systems.
 If value is a floating point number, it specifies the spacing relative
-to the default frame line height.  nil means add no extra space.  */);
+to the default frame line height.  A value of nil means add no extra space.  */);
 
   DEFVAR_PER_BUFFER ("cursor-in-non-selected-windows",
                     &current_buffer->cursor_in_non_selected_windows, Qnil,
-    doc: /* *Cursor type to display in non-selected windows.
-t means to use hollow box cursor.  See `cursor-type' for other values.  */);
+                    doc: /* *Cursor type to display in non-selected windows.
+The value t means to use hollow box cursor.  See `cursor-type' for other values.  */);
 
   DEFVAR_LISP ("kill-buffer-query-functions", &Vkill_buffer_query_functions,
-              doc: /* List of functions called with no args to query before killing a buffer.  */);
+              doc: /* List of functions called with no args to query before killing a buffer.
+The buffer being killed will be current while the functions are running.
+If any of them returns nil, the buffer is not killed.  */);
   Vkill_buffer_query_functions = Qnil;
 
   DEFVAR_LISP ("change-major-mode-hook", &Vchange_major_mode_hook,