* lisp.h (enum Lisp_Misc_Type): Del Lisp_Misc_Some_Buffer_Local_Value.
[bpt/emacs.git] / src / buffer.c
index ea4752b..c53d427 100644 (file)
@@ -7,7 +7,7 @@ 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;
@@ -1472,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;
@@ -1645,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"));
@@ -1906,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
@@ -1921,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
@@ -2481,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);
@@ -2511,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));
 
@@ -3957,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;
 {
@@ -4206,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;
 }
@@ -5026,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.  */
@@ -5265,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 ()
@@ -5525,6 +5561,8 @@ 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.  */);
@@ -5548,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.  */);
 
@@ -5672,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.  */);
@@ -5713,8 +5754,8 @@ 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:
 
@@ -6006,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.  */);