Revision: emacs@sv.gnu.org/emacs--devo--0--patch-106
[bpt/emacs.git] / src / buffer.c
index 2ca4332..5c3d106 100644 (file)
@@ -1,6 +1,7 @@
 /* Buffer manipulation primitives for GNU Emacs.
-   Copyright (C) 1985,86,87,88,89,93,94,95,97,98, 1999, 2000, 2001, 02, 03, 2004
-       Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994,
+                 1995, 1997, 1998, 1999, 2000, 2001, 2002,
+                 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -16,8 +17,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #include <config.h>
 
@@ -31,10 +32,6 @@ Boston, MA 02111-1307, USA.  */
 extern int errno;
 #endif
 
-#ifndef MAXPATHLEN
-/* in 4.1 [probably SunOS? -stef] , param.h fails to define this. */
-#define MAXPATHLEN 1024
-#endif /* not MAXPATHLEN */
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -182,6 +179,7 @@ static void alloc_buffer_text P_ ((struct buffer *, size_t));
 static void free_buffer_text P_ ((struct buffer *b));
 static struct Lisp_Overlay * copy_overlays P_ ((struct buffer *, struct Lisp_Overlay *));
 static void modify_overlay P_ ((struct buffer *, EMACS_INT, EMACS_INT));
+static Lisp_Object buffer_lisp_local_variables P_ ((struct buffer *));
 
 
 /* For debugging; temporary.  See set_buffer_internal.  */
@@ -487,7 +485,7 @@ static void
 clone_per_buffer_values (from, to)
      struct buffer *from, *to;
 {
-  Lisp_Object to_buffer, tem;
+  Lisp_Object to_buffer;
   int offset;
 
   XSETBUFFER (to_buffer, to);
@@ -515,16 +513,11 @@ clone_per_buffer_values (from, to)
   to->overlays_before = copy_overlays (to, from->overlays_before);
   to->overlays_after = copy_overlays (to, from->overlays_after);
 
-  /* Copy the alist of local variables,
-     and all the alist elements too.  */
-  to->local_var_alist
-    = Fcopy_sequence (from->local_var_alist);
-  for (tem = to->local_var_alist; CONSP (tem);
-       tem = XCDR (tem))
-    XSETCAR (tem, Fcons (XCAR (XCAR (tem)), XCDR (XCAR (tem))));
+  /* Get (a copy of) the alist of Lisp-level local variables of FROM
+     and install that in TO.  */
+  to->local_var_alist = buffer_lisp_local_variables (from);
 }
 
-
 DEFUN ("make-indirect-buffer", Fmake_indirect_buffer, Smake_indirect_buffer,
        2, 3,
        "bMake indirect buffer (to buffer): \nBName of indirect buffer: ",
@@ -634,7 +627,21 @@ CLONE nil means the indirect buffer's state is reset to default values.  */)
       XMARKER (b->zv_marker)->insertion_type = 1;
     }
   else
-    clone_per_buffer_values (b->base_buffer, b);
+    {
+      struct buffer *old_b = current_buffer;
+
+      clone_per_buffer_values (b->base_buffer, b);
+      b->filename = Qnil;
+      b->file_truename = Qnil;
+      b->display_count = make_number (0);
+      b->backed_up = Qnil;
+      b->auto_save_file_name = Qnil;
+      set_buffer_internal_1 (b);
+      Fset (intern ("buffer-save-without-query"), Qnil);
+      Fset (intern ("buffer-file-number"), Qnil);
+      Fset (intern ("buffer-stale-function"), Qnil);
+      set_buffer_internal_1 (old_b);
+    }
 
   return buf;
 }
@@ -867,20 +874,23 @@ DEFUN ("buffer-local-value", Fbuffer_local_value,
        Sbuffer_local_value, 2, 2, 0,
        doc: /* Return the value of VARIABLE in BUFFER.
 If VARIABLE does not have a buffer-local binding in BUFFER, the value
-is the default binding of variable. */)
-     (symbol, buffer)
-     register Lisp_Object symbol;
+is the default binding of the variable. */)
+     (variable, buffer)
+     register Lisp_Object variable;
      register Lisp_Object buffer;
 {
   register struct buffer *buf;
   register Lisp_Object result;
 
-  CHECK_SYMBOL (symbol);
+  CHECK_SYMBOL (variable);
   CHECK_BUFFER (buffer);
   buf = XBUFFER (buffer);
 
+  if (SYMBOLP (variable))
+    variable = indirect_variable (variable);
+
   /* Look in local_var_list */
-  result = Fassoc (symbol, buf->local_var_alist);
+  result = Fassoc (variable, buf->local_var_alist);
   if (NILP (result))
     {
       int offset, idx;
@@ -895,7 +905,7 @@ is the default binding of variable. */)
          idx = PER_BUFFER_IDX (offset);
          if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
              && SYMBOLP (PER_BUFFER_SYMBOL (offset))
-             && EQ (PER_BUFFER_SYMBOL (offset), symbol))
+             && EQ (PER_BUFFER_SYMBOL (offset), variable))
            {
              result = PER_BUFFER_VALUE (buf, offset);
              found = 1;
@@ -904,7 +914,7 @@ is the default binding of variable. */)
        }
 
       if (!found)
-       result = Fdefault_value (symbol);
+       result = Fdefault_value (variable);
     }
   else
     {
@@ -912,7 +922,7 @@ is the default binding of variable. */)
       Lisp_Object current_alist_element;
 
       /* What binding is loaded right now?  */
-      valcontents = SYMBOL_VALUE (symbol);
+      valcontents = SYMBOL_VALUE (variable);
       current_alist_element
        = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr);
 
@@ -929,7 +939,44 @@ is the default binding of variable. */)
     }
 
   if (EQ (result, Qunbound))
-    return Fsignal (Qvoid_variable, Fcons (symbol, Qnil));
+    return Fsignal (Qvoid_variable, Fcons (variable, Qnil));
+
+  return result;
+}
+
+/* Return an alist of the Lisp-level buffer-local bindings of
+   buffer BUF.  That is, don't include the variables maintained
+   in special slots in the buffer object.  */
+
+static Lisp_Object
+buffer_lisp_local_variables (buf)
+     struct buffer *buf;
+{
+  Lisp_Object result = Qnil;
+  register Lisp_Object tail;
+  for (tail = buf->local_var_alist; CONSP (tail); tail = XCDR (tail))
+    {
+      Lisp_Object val, elt;
+
+      elt = XCAR (tail);
+
+      /* Reference each variable in the alist in buf.
+        If inquiring about the current buffer, this gets the current values,
+        so store them into the alist so the alist is up to date.
+        If inquiring about some other buffer, this swaps out any values
+        for that buffer, making the alist up to date automatically.  */
+      val = find_symbol_value (XCAR (elt));
+      /* Use the current buffer value only if buf is the current buffer.  */
+      if (buf != current_buffer)
+       val = XCDR (elt);
+
+      /* If symbol is unbound, put just the symbol in the list.  */
+      if (EQ (val, Qunbound))
+       result = Fcons (XCAR (elt), result);
+      /* Otherwise, put (symbol . value) in the list.  */
+      else
+       result = Fcons (Fcons (XCAR (elt), val), result);
+    }
 
   return result;
 }
@@ -955,34 +1002,7 @@ No argument or nil as argument means use current buffer as BUFFER.  */)
       buf = XBUFFER (buffer);
     }
 
-  result = Qnil;
-
-  {
-    register Lisp_Object tail;
-    for (tail = buf->local_var_alist; CONSP (tail); tail = XCDR (tail))
-      {
-       Lisp_Object val, elt;
-
-       elt = XCAR (tail);
-
-       /* Reference each variable in the alist in buf.
-          If inquiring about the current buffer, this gets the current values,
-          so store them into the alist so the alist is up to date.
-          If inquiring about some other buffer, this swaps out any values
-          for that buffer, making the alist up to date automatically.  */
-       val = find_symbol_value (XCAR (elt));
-       /* Use the current buffer value only if buf is the current buffer.  */
-       if (buf != current_buffer)
-         val = XCDR (elt);
-
-       /* If symbol is unbound, put just the symbol in the list.  */
-       if (EQ (val, Qunbound))
-         result = Fcons (XCAR (elt), result);
-       /* Otherwise, put (symbol . value) in the list.  */
-       else
-         result = Fcons (Fcons (XCAR (elt), val), result);
-      }
-  }
+  result = buffer_lisp_local_variables (buf);
 
   /* Add on all the variables stored in special slots.  */
   {
@@ -1004,7 +1024,6 @@ No argument or nil as argument means use current buffer as BUFFER.  */)
 
   return result;
 }
-
 \f
 DEFUN ("buffer-modified-p", Fbuffer_modified_p, Sbuffer_modified_p,
        0, 1, 0,
@@ -1340,7 +1359,8 @@ with SIGHUP.  */)
     /* First run the query functions; if any query is answered no,
        don't kill the buffer.  */
     arglist[0] = Qkill_buffer_query_functions;
-    if (NILP (Frun_hook_with_args_until_failure (1, arglist)))
+    tem = Frun_hook_with_args_until_failure (1, arglist);
+    if (NILP (tem))
       return unbind_to (count, Qnil);
 
     /* Then run the hooks.  */
@@ -1703,9 +1723,6 @@ do not put this buffer at the front of the list of recently selected ones.  */)
        }
     }
   Fset_buffer (buf);
-  if (NILP (norecord))
-    /* Why bother ?  Fselect_window will do it for us anyway.  -stef  */
-    record_buffer (buf);
   Fselect_window (Fdisplay_buffer (buf, other_window, Qnil), norecord);
   return buf;
 }
@@ -1952,6 +1969,7 @@ DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "",
        doc: /* Put BUFFER at the end of the list of all buffers.
 There it is the least likely candidate for `other-buffer' to return;
 thus, the least likely buffer for \\[switch-to-buffer] to select by default.
+You can specify a buffer name as BUFFER, or an actual buffer object.
 If BUFFER is nil or omitted, bury the current buffer.
 Also, if BUFFER is nil or omitted, remove the current buffer from the
 selected window if it is displayed there.  */)
@@ -3534,10 +3552,12 @@ DEFUN ("make-overlay", Fmake_overlay, Smake_overlay, 2, 5, 0,
        doc: /* Create a new overlay with range BEG to END in BUFFER.
 If omitted, BUFFER defaults to the current buffer.
 BEG and END may be integers or markers.
-The fourth arg FRONT-ADVANCE, if non-nil, makes the
-front delimiter advance when text is inserted there.
-The fifth arg REAR-ADVANCE, if non-nil, makes the
-rear delimiter advance when text is inserted there.  */)
+The fourth arg FRONT-ADVANCE, if non-nil, makes the marker
+for the front of the overlay advance when text is inserted there
+(which means the text *is not* included in the overlay).
+The fifth arg REAR-ADVANCE, if non-nil, makes the marker
+for the rear of the overlay advance when text is inserted there
+(which means the text *is* included in the overlay).  */)
      (beg, end, buffer, front_advance, rear_advance)
      Lisp_Object beg, end, buffer;
      Lisp_Object front_advance, rear_advance;
@@ -3829,7 +3849,8 @@ DEFUN ("overlay-end", Foverlay_end, Soverlay_end, 1, 1, 0,
 }
 
 DEFUN ("overlay-buffer", Foverlay_buffer, Soverlay_buffer, 1, 1, 0,
-       doc: /* Return the buffer OVERLAY belongs to.  */)
+       doc: /* Return the buffer OVERLAY belongs to.
+Return nil if OVERLAY has been deleted.  */)
      (overlay)
        Lisp_Object overlay;
 {
@@ -4951,6 +4972,7 @@ init_buffer_once ()
   buffer_defaults.direction_reversed = Qnil;
   buffer_defaults.cursor_type = Qt;
   buffer_defaults.extra_line_spacing = Qnil;
+  buffer_defaults.cursor_in_non_selected_windows = Qt;
 
 #ifdef DOS_NT
   buffer_defaults.buffer_file_type = Qnil; /* TEXT */
@@ -5047,6 +5069,7 @@ init_buffer_once ()
   XSETFASTINT (buffer_local_flags.header_line_format, idx); ++idx;
   XSETFASTINT (buffer_local_flags.cursor_type, idx); ++idx;
   XSETFASTINT (buffer_local_flags.extra_line_spacing, idx); ++idx;
+  XSETFASTINT (buffer_local_flags.cursor_in_non_selected_windows, idx); ++idx;
 
   /* Need more room? */
   if (idx >= MAX_PER_BUFFER_VARS)
@@ -5086,11 +5109,9 @@ init_buffer_once ()
 void
 init_buffer ()
 {
-  char buf[MAXPATHLEN + 1];
   char *pwd;
-  struct stat dotstat, pwdstat;
   Lisp_Object temp;
-  int rc;
+  int len;
 
 #ifdef USE_MMAP_FOR_BUFFERS
  {
@@ -5109,40 +5130,28 @@ init_buffer ()
   if (NILP (buffer_defaults.enable_multibyte_characters))
     Fset_buffer_multibyte (Qnil);
 
-  /* If PWD is accurate, use it instead of calling getwd.  PWD is
-     sometimes a nicer name, and using it may avoid a fatal error if a
-     parent directory is searchable but not readable.  */
-  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
-      && dotstat.st_dev == pwdstat.st_dev
-      && strlen (pwd) < MAXPATHLEN)
-    strcpy (buf, pwd);
-#ifdef HAVE_GETCWD
-  else if (getcwd (buf, MAXPATHLEN+1) == 0)
-    fatal ("`getcwd' failed: %s\n", strerror (errno));
-#else
-  else if (getwd (buf) == 0)
-    fatal ("`getwd' failed: %s\n", buf);
-#endif
+  pwd = get_current_dir_name ();
+
+  if (!pwd)
+    fatal ("`get_current_dir_name' failed: %s\n", strerror (errno));
 
 #ifndef VMS
   /* Maybe this should really use some standard subroutine
      whose definition is filename syntax dependent.  */
-  rc = strlen (buf);
-  if (!(IS_DIRECTORY_SEP (buf[rc - 1])))
+  len = strlen (pwd);
+  if (!(IS_DIRECTORY_SEP (pwd[len - 1])))
     {
-      buf[rc] = DIRECTORY_SEP;
-      buf[rc + 1] = '\0';
+      /* Grow buffer to add directory separator and '\0'.  */
+      pwd = (char *) xrealloc (pwd, len + 2);
+      pwd[len] = DIRECTORY_SEP;
+      pwd[len + 1] = '\0';
     }
 #endif /* not VMS */
 
-  current_buffer->directory = make_unibyte_string (buf, strlen (buf));
+  current_buffer->directory = make_unibyte_string (pwd, strlen (pwd));
   if (! NILP (buffer_defaults.enable_multibyte_characters))
-    /* At this momemnt, we still don't know how to decode the
-       direcotry name.  So, we keep the bytes in multibyte form so
+    /* At this moment, we still don't know how to decode the
+       directory name.  So, we keep the bytes in multibyte form so
        that ENCODE_FILE correctly gets the original bytes.  */
     current_buffer->directory
       = string_to_multibyte (current_buffer->directory);
@@ -5161,6 +5170,8 @@ init_buffer ()
 
   temp = get_minibuffer (0);
   XBUFFER (temp)->directory = current_buffer->directory;
+
+  free (pwd);
 }
 
 /* initialize the buffer routines */
@@ -5238,6 +5249,11 @@ This is the same as (default-value 'cursor-type).  */);
                     doc: /* Default value of `line-spacing' for buffers that don't override it.
 This is the same as (default-value 'line-spacing).  */);
 
+  DEFVAR_LISP_NOPRO ("default-cursor-in-non-selected-windows",
+                    &buffer_defaults.cursor_in_non_selected_windows,
+                    doc: /* Default value of `cursor-in-non-selected-windows'.
+This is the same as (default-value 'cursor-in-non-selected-windows).  */);
+
   DEFVAR_LISP_NOPRO ("default-abbrev-mode",
                     &buffer_defaults.abbrev_mode,
                     doc: /* Default value of `abbrev-mode' for buffers that do not override it.
@@ -5248,19 +5264,19 @@ This is the same as (default-value 'abbrev-mode).  */);
                     doc: /* Default value of `ctl-arrow' for buffers that do not override it.
 This is the same as (default-value 'ctl-arrow).  */);
 
-   DEFVAR_LISP_NOPRO ("default-direction-reversed",
-                     &buffer_defaults.direction_reversed,
-                     doc: /* Default value of `direction-reversed' for buffers that do not override it.
+  DEFVAR_LISP_NOPRO ("default-direction-reversed",
+                     &buffer_defaults.direction_reversed,
+                     doc: /* Default value of `direction-reversed' for buffers that do not override it.
 This is the same as (default-value 'direction-reversed).  */);
 
-   DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters",
-                     &buffer_defaults.enable_multibyte_characters,
-                     doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it.
+  DEFVAR_LISP_NOPRO ("default-enable-multibyte-characters",
+                     &buffer_defaults.enable_multibyte_characters,
+                     doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it.
 This is the same as (default-value 'enable-multibyte-characters).  */);
 
-   DEFVAR_LISP_NOPRO ("default-buffer-file-coding-system",
-                     &buffer_defaults.buffer_file_coding_system,
-                     doc: /* Default value of `buffer-file-coding-system' for buffers not overriding it.
+  DEFVAR_LISP_NOPRO ("default-buffer-file-coding-system",
+                     &buffer_defaults.buffer_file_coding_system,
+                     doc: /* Default value of `buffer-file-coding-system' for buffers not overriding it.
 This is the same as (default-value 'buffer-file-coding-system).  */);
 
   DEFVAR_LISP_NOPRO ("default-truncate-lines",
@@ -5671,7 +5687,7 @@ arrow bitmaps.
 
 If value is a symbol `left' or `right', both angle and arrow bitmaps
 are displayed in the left or right fringe, resp.  Any other value
-that doesn't look like an alist means displat the angle bitmaps in
+that doesn't look like an alist means display the angle bitmaps in
 the left fringe but no arrows.
 
 You can exercise more precise control by using an alist as the
@@ -5696,7 +5712,7 @@ 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
 case that you moved off with C-f means scrolling just one line.  1.0 means
 point goes at the top, so that in that simple case, the window
-window scrolls by a full window height.  Meaningful values are
+scrolls by a full window height.  Meaningful values are
 between 0.0 and 1.0, inclusive.  */);
 
   DEFVAR_PER_BUFFER ("scroll-down-aggressively",
@@ -5709,7 +5725,7 @@ 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
 case that you moved off with C-b means scrolling just one line.  1.0 means
 point goes at the bottom, so that in that simple case, the window
-window scrolls by a full window height.  Meaningful values are
+scrolls by a full window height.  Meaningful values are
 between 0.0 and 1.0, inclusive.  */);
 
 /*DEFVAR_LISP ("debug-check-symbol", &Vcheck_symbol,
@@ -5782,7 +5798,13 @@ An entry (nil PROPERTY VALUE BEG . END) indicates that a text property
 was modified between BEG and END.  PROPERTY is the property name,
 and VALUE is the old value.
 
-An entry (FUN-NAME . ARGS) means undo the change with (apply FUN-NAME ARGS).
+An entry (apply FUN-NAME . ARGS) means undo the change with
+\(apply FUN-NAME ARGS).
+
+An entry (apply DELTA BEG END FUN-NAME . ARGS) supports selective undo
+in the active region.  BEG and END is the range affected by this entry
+and DELTA is the number of bytes added or deleted in that range by
+this change.
 
 An entry (MARKER . DISTANCE) indicates that the marker MARKER
 was adjusted in position by the offset DISTANCE (an integer).
@@ -5891,15 +5913,15 @@ is a member of the list.  */);
      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
-  nil           don't display a cursor
-  box           display a filled box cursor
-  hollow        display a hollow box cursor
-  bar           display a vertical bar cursor with default width
-  (bar . WIDTH)         display a vertical bar cursor with width WIDTH
-  hbar          display a horizontal bar cursor with default width
-  (hbar . WIDTH) display a horizontal bar cursor with width WIDTH
-  ANYTHING ELSE         display a hollow box cursor.
+  t              use the cursor specified for the frame
+  nil            don't display a cursor
+  box            display a filled box cursor
+  hollow         display a hollow box cursor
+  bar            display a vertical bar cursor with default width
+  (bar . WIDTH)          display a vertical bar cursor with width WIDTH
+  hbar           display a horizontal bar cursor with default height
+  (hbar . HEIGHT) display a horizontal bar cursor with height HEIGHT
+  ANYTHING ELSE          display a hollow box cursor
 
 When the buffer is displayed in a nonselected window,
 this variable has no effect; the cursor appears as a hollow box.  */);
@@ -5911,6 +5933,11 @@ 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.  */);
 
+  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.  */);
+
   DEFVAR_LISP ("kill-buffer-query-functions", &Vkill_buffer_query_functions,
               doc: /* List of functions called with no args to query before killing a buffer.  */);
   Vkill_buffer_query_functions = Qnil;