(Finsert_file_contents): Update call to CHAR_HEAD_P.
[bpt/emacs.git] / src / buffer.c
index 3c914c2..ffe6237 100644 (file)
@@ -23,6 +23,9 @@ Boston, MA 02111-1307, USA.  */
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/param.h>
+#include <errno.h>
+
+extern int errno;
 
 #ifndef MAXPATHLEN
 /* in 4.1, param.h fails to define this. */
@@ -39,6 +42,7 @@ Boston, MA 02111-1307, USA.  */
 #include "region-cache.h"
 #include "indent.h"
 #include "blockinput.h"
+#include "frame.h"
 
 struct buffer *current_buffer;         /* the current buffer */
 
@@ -161,6 +165,7 @@ Lisp_Object Qinsert_behind_hooks;
 /* For debugging; temporary.  See set_buffer_internal.  */
 /* Lisp_Object Qlisp_mode, Vcheck_symbol; */
 
+void
 nsberror (spec)
      Lisp_Object spec;
 {
@@ -179,11 +184,34 @@ Value is nil if OBJECT is not a buffer or if it has been killed.")
          ? Qt : Qnil);
 }
 
-DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 0, 0,
-  "Return a list of all existing live buffers.")
-  ()
+DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 1, 0,
+  "Return a list of all existing live buffers.\n\
+If the optional arg FRAME is a frame, we return that frame's buffer list.")
+  (frame)
+     Lisp_Object frame;
 {
-  return Fmapcar (Qcdr, Vbuffer_alist);
+  Lisp_Object framelist, general;
+  general = Fmapcar (Qcdr, Vbuffer_alist);
+
+  if (FRAMEP (frame))
+    {
+      Lisp_Object tail;
+
+      CHECK_FRAME (frame, 1);
+
+      framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
+
+      /* Remove from GENERAL any buffer that duplicates one in FRAMELIST.  */
+      tail = framelist;
+      while (! NILP (tail))
+       {
+         general = Fdelq (XCONS (tail)->car, general);
+         tail = XCONS (tail)->cdr;
+       }
+      return nconc2 (framelist, general);
+    }
+
+  return general;
 }
 
 /* Like Fassoc, but use Fstring_equal to compare
@@ -1087,7 +1115,7 @@ with SIGHUP.")
   /* Delete any auto-save file, if we saved it in this session.  */
   if (STRINGP (b->auto_save_file_name)
       && b->auto_save_modified != 0
-      && SAVE_MODIFF < b->auto_save_modified)
+      && BUF_SAVE_MODIFF (b) < b->auto_save_modified)
     {
       Lisp_Object tem;
       tem = Fsymbol_value (intern ("delete-auto-save-files"));
@@ -1165,6 +1193,7 @@ with SIGHUP.")
    selected buffers are always closer to the front of the list.  This
    means that other_buffer is more likely to choose a relevant buffer.  */
 
+void
 record_buffer (buf)
      Lisp_Object buf;
 {
@@ -1379,19 +1408,22 @@ set_buffer_internal_1 (b)
        {
          Lisp_Object obuf;
          XSETBUFFER (obuf, old_buf);
-         Fset_marker (old_buf->pt_marker, BUF_PT (old_buf), obuf);
+         Fset_marker (old_buf->pt_marker, make_number (BUF_PT (old_buf)),
+                      obuf);
        }
       if (! NILP (old_buf->begv_marker))
        {
          Lisp_Object obuf;
          XSETBUFFER (obuf, old_buf);
-         Fset_marker (old_buf->begv_marker, BUF_BEGV (old_buf), obuf);
+         Fset_marker (old_buf->begv_marker, make_number (BUF_BEGV (old_buf)),
+                      obuf);
        }
       if (! NILP (old_buf->zv_marker))
        {
          Lisp_Object obuf;
          XSETBUFFER (obuf, old_buf);
-         Fset_marker (old_buf->zv_marker, BUF_ZV (old_buf), obuf);
+         Fset_marker (old_buf->zv_marker, make_number (BUF_ZV (old_buf)),
+                      obuf);
        }
     }
 
@@ -1463,19 +1495,22 @@ set_buffer_temp (b)
        {
          Lisp_Object obuf;
          XSETBUFFER (obuf, old_buf);
-         Fset_marker (old_buf->pt_marker, BUF_PT (old_buf), obuf);
+         Fset_marker (old_buf->pt_marker, make_number (BUF_PT (old_buf)),
+                      obuf);
        }
       if (! NILP (old_buf->begv_marker))
        {
          Lisp_Object obuf;
          XSETBUFFER (obuf, old_buf);
-         Fset_marker (old_buf->begv_marker, BUF_BEGV (old_buf), obuf);
+         Fset_marker (old_buf->begv_marker, make_number (BUF_BEGV (old_buf)),
+                      obuf);
        }
       if (! NILP (old_buf->zv_marker))
        {
          Lisp_Object obuf;
          XSETBUFFER (obuf, old_buf);
-         Fset_marker (old_buf->zv_marker, BUF_ZV (old_buf), obuf);
+         Fset_marker (old_buf->zv_marker, make_number (BUF_ZV (old_buf)),
+                      obuf);
        }
     }
 
@@ -1534,6 +1569,9 @@ selected window if it is displayed there.")
   if (NILP (buffer))
     {
       XSETBUFFER (buffer, current_buffer);
+
+      /* If we're burying the current buffer, unshow it.  */
+      Fswitch_to_buffer (Fother_buffer (buffer, Qnil), Qnil);
     }
   else
     {
@@ -1545,13 +1583,6 @@ selected window if it is displayed there.")
       buffer = buf1;
     }
 
-  /* Unshow the buffer in the selected window, if it is there.  */
-  if (EQ (XWINDOW (selected_window)->buffer, buffer))
-    Fswitch_to_buffer (Fother_buffer (buffer, Qnil), Qnil);
-  /* Otherwise, unshow it in other frames.  */
-  else
-    Freplace_buffer_in_windows (buffer);
-
   /* Move buffer to the end of the buffer list.  */
   {
     register Lisp_Object aelt, link;
@@ -1584,6 +1615,7 @@ so the buffer is truly empty after this.")
   return Qnil;
 }
 
+void
 validate_region (b, e)
      register Lisp_Object *b, *e;
 {
@@ -2101,7 +2133,7 @@ struct sortstrlist
    it's more efficient to hold onto the memory instead of repeatedly
    allocating and freeing it.  */
 static struct sortstrlist overlay_heads, overlay_tails;
-static char *overlay_str_buf;
+static unsigned char *overlay_str_buf;
 
 /* Allocated length of overlay_str_buf.  */
 static int overlay_str_len;
@@ -2236,12 +2268,15 @@ overlay_strings (pos, w, pstr)
     {
       Lisp_Object tem;
       int i;
-      char *p;
+      unsigned char *p;
       int total = overlay_heads.bytes + overlay_tails.bytes;
 
       if (total > overlay_str_len)
-       overlay_str_buf = (char *)xrealloc (overlay_str_buf,
-                                           overlay_str_len = total);
+       {
+         overlay_str_len = total;
+         overlay_str_buf = (unsigned char *)xrealloc (overlay_str_buf,
+                                                      total);
+       }
       p = overlay_str_buf;
       for (i = overlay_tails.used; --i >= 0;)
        {
@@ -2502,8 +2537,10 @@ fix_overlays_in_range (start, end)
          if (startpos > endpos)
            {
              int tem;
-             Fset_marker (OVERLAY_START (overlay), endpos, Qnil);
-             Fset_marker (OVERLAY_END (overlay), startpos, Qnil);
+             Fset_marker (OVERLAY_START (overlay), make_number (endpos),
+                          Qnil);
+             Fset_marker (OVERLAY_END (overlay), make_number (startpos),
+                          Qnil);
              tem = startpos; startpos = endpos; endpos = tem;
            }
          /* Add it to the end of the wrong list.  Later on,
@@ -2536,8 +2573,10 @@ fix_overlays_in_range (start, end)
          if (startpos > endpos)
            {
              int tem;
-             Fset_marker (OVERLAY_START (overlay), endpos, Qnil);
-             Fset_marker (OVERLAY_END (overlay), startpos, Qnil);
+             Fset_marker (OVERLAY_START (overlay), make_number (endpos),
+                          Qnil);
+             Fset_marker (OVERLAY_END (overlay), make_number (startpos),
+                          Qnil);
              tem = startpos; startpos = endpos; endpos = tem;
            }
          if (endpos < XINT (current_buffer->overlay_center))
@@ -2581,6 +2620,7 @@ fix_overlays_in_range (start, end)
    `overlays_before' of the buffer *BP.  Before the insertion, `point'
    was at PREV, and now is at POS.  */
 
+void
 fix_overlays_before (bp, prev, pos)
      struct buffer *bp;
      int prev, pos;
@@ -2762,10 +2802,12 @@ modify_overlay (buf, start, end)
        }
     }
 
-  ++OVERLAY_MODIFF;
+  ++BUF_OVERLAY_MODIFF (buf);
 }
 
 \f\f
+Lisp_Object Fdelete_overlay ();
+
 DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
   "Set the endpoints of OVERLAY to BEG and END in BUFFER.\n\
 If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.\n\
@@ -2816,15 +2858,13 @@ buffer.")
       /* Redisplay where the overlay was.  */
       if (!NILP (obuffer))
        {
-         Lisp_Object o_beg;
-         Lisp_Object o_end;
+         int o_beg;
+         int o_end;
 
-         o_beg = OVERLAY_START (overlay);
-         o_end = OVERLAY_END   (overlay);
-         o_beg = OVERLAY_POSITION (o_beg);
-         o_end = OVERLAY_POSITION (o_end);
+         o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
+         o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
 
-         modify_overlay (ob, XINT (o_beg), XINT (o_end));
+         modify_overlay (ob, o_beg, o_end);
        }
 
       /* Redisplay where the overlay is going to be.  */
@@ -2833,24 +2873,21 @@ buffer.")
   else
     /* Redisplay the area the overlay has just left, or just enclosed.  */
     {
-      Lisp_Object o_beg;
-      Lisp_Object o_end;
+      int o_beg, o_end;
       int change_beg, change_end;
 
-      o_beg = OVERLAY_START (overlay);
-      o_end = OVERLAY_END   (overlay);
-      o_beg = OVERLAY_POSITION (o_beg);
-      o_end = OVERLAY_POSITION (o_end);
+      o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
+      o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
 
-      if (XINT (o_beg) == XINT (beg))
-       modify_overlay (b, XINT (o_end), XINT (end));
-      else if (XINT (o_end) == XINT (end))
-       modify_overlay (b, XINT (o_beg), XINT (beg));
+      if (o_beg == XINT (beg))
+       modify_overlay (b, o_end, XINT (end));
+      else if (o_end == XINT (end))
+       modify_overlay (b, o_beg, XINT (beg));
       else
        {
-         if (XINT (beg) < XINT (o_beg)) o_beg = beg;
-         if (XINT (end) > XINT (o_end)) o_end = end;
-         modify_overlay (b, XINT (o_beg), XINT (o_end));
+         if (XINT (beg) < o_beg) o_beg = XINT (beg);
+         if (XINT (end) > o_end) o_end = XINT (end);
+         modify_overlay (b, o_beg, o_end);
        }
     }
 
@@ -3567,6 +3604,7 @@ init_buffer_once ()
   buffer_defaults.buffer_file_type = Qnil; /* TEXT */
 #endif
   buffer_defaults.enable_multibyte_characters = Qt;
+  buffer_defaults.buffer_file_coding_system = Qnil;
   XSETFASTINT (buffer_defaults.fill_column, 70);
   XSETFASTINT (buffer_defaults.left_margin, 0);
   buffer_defaults.cache_long_line_scans = Qnil;
@@ -3627,7 +3665,10 @@ init_buffer_once ()
   XSETFASTINT (buffer_local_flags.enable_multibyte_characters, 0x80000);
   /* Make this one a permanent local.  */
   buffer_permanent_local_flags |= 0x80000;
-
+  XSETFASTINT (buffer_local_flags.buffer_file_coding_system, 0x100000);
+  /* Make this one a permanent local.  */
+  buffer_permanent_local_flags |= 0x100000;
+  
   Vbuffer_alist = Qnil;
   current_buffer = 0;
   all_buffers = 0;
@@ -3672,8 +3713,13 @@ init_buffer ()
       && 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
 
 #ifndef VMS
   /* Maybe this should really use some standard subroutine
@@ -3691,7 +3737,12 @@ init_buffer ()
   /* Add /: to the front of the name
      if it would otherwise be treated as magic.  */
   temp = Ffind_file_name_handler (current_buffer->directory, Qt);
-  if (! NILP (temp))
+  if (! NILP (temp)
+      /* If the default dir is just /, TEMP is non-nil
+        because of the ange-ftp completion handler.
+        However, it is not necessary to turn / into /:/.
+        So avoid doing that.  */
+      && strcmp ("/", XSTRING (current_buffer->directory)->data))
     current_buffer->directory
       = concat2 (build_string ("/:"), current_buffer->directory);
 
@@ -3777,6 +3828,11 @@ This is the same as (default-value 'ctl-arrow).");
      "Default value of `enable-multibyte-characters' for buffers not overriding it.\n\
  This is the same as (default-value 'enable-multibyte-characters).");
  
+   DEFVAR_LISP_NOPRO ("default-buffer-file-coding-system",
+             &buffer_defaults.buffer_file_coding_system,
+     "Default value of `buffer-file-coding-system' for buffers not overriding it.\n\
+ This is the same as (default-value 'buffer-file-coding-system).");
   DEFVAR_LISP_NOPRO ("default-truncate-lines",
              &buffer_defaults.truncate_lines,
     "Default value of `truncate-lines' for buffers that do not override it.\n\
@@ -3835,11 +3891,14 @@ A string is printed verbatim in the mode line except for %-constructs:\n\
   (%-constructs are allowed when the string is the entire mode-line-format\n\
    or when it is found in a cons-cell or a list)\n\
   %b -- print buffer name.      %f -- print visited file name.\n\
+  %F -- print frame name.\n\
   %* -- print %, * or hyphen.   %+ -- print *, % or hyphen.\n\
        % means buffer is read-only and * means it is modified.\n\
        For a modified read-only buffer, %* gives % and %+ gives *.\n\
   %s -- print process status.   %l -- print the current line number.\n\
   %c -- print the current column number (this makes editing slower).\n\
+        To make the column number update correctly in all cases,\n\
+       `column-number-mode' must be non-nil.\n\
   %p -- print percent of buffer above top of window, or Top, Bot or All.\n\
   %P -- print percent of buffer above bottom of window, perhaps plus Top,\n\
         or print Bottom or All.\n\
@@ -3896,10 +3955,20 @@ in the current display table (if there is one).");
 
   DEFVAR_PER_BUFFER ("enable-multibyte-characters",
                     &current_buffer->enable_multibyte_characters, Qnil,
-    "Non-nil means the buffer contents are regarded as multi-byte form\n\
+    "*Non-nil means the buffer contents are regarded as multi-byte form\n\
 of characters, not a binary code.  This affects the display, file I/O,\n\
 and behaviors of various editing commands.");
 
+  DEFVAR_PER_BUFFER ("buffer-file-coding-system",
+                    &current_buffer->buffer_file_coding_system, Qnil,
+    "Coding system to be used for encoding the buffer contents on saving.\n\
+If it is nil, the buffer is saved without any code conversion unless\n\
+some coding system is specified in file-coding-system-alist\n\
+for the buffer file.\n\
+\n\
+This variable is never applied to a way of decoding\n\
+a file while reading it.");
+
   DEFVAR_PER_BUFFER ("direction-reversed", &current_buffer->direction_reversed,
                     Qnil,
     "*Non-nil means lines in the buffer are displayed right to left.");
@@ -4049,7 +4118,7 @@ Three arguments are passed to the function: the positions of\n\
 the beginning and end of the range of changed text,\n\
 and the length of the pre-change text replaced by that range.\n\
 \(For an insertion, the pre-change length is zero;\n\
-for a deletion, that length is the number of characters deleted,\n\
+for a deletion, that length is the number of bytes deleted,\n\
 and the post-change beginning and end are at the same place.)\n\
 \n\
 Buffer changes made while executing the `after-change-function'\n\
@@ -4080,9 +4149,9 @@ accomplishing an equivalent result by using other variables.");
               "List of function to call after each text change.\n\
 Three arguments are passed to each function: the positions of\n\
 the beginning and end of the range of changed text,\n\
-and the length of the pre-change text replaced by that range.\n\
+and the length in bytes of the pre-change text replaced by that range.\n\
 \(For an insertion, the pre-change length is zero;\n\
-for a deletion, that length is the number of characters deleted,\n\
+for a deletion, that length is the number of bytes deleted,\n\
 and the post-change beginning and end are at the same place.)\n\
 \n\
 Buffer changes made while executing the `after-change-functions'\n\