Tweak Emacs manual info menu ordering.
[bpt/emacs.git] / src / buffer.c
index fec6333..f73d2d0 100644 (file)
@@ -1,6 +1,6 @@
 /* Buffer manipulation primitives for GNU Emacs.
 
-Copyright (C) 1985-1989, 1993-1995, 1997-201 Free Software Foundation, Inc.
+Copyright (C) 1985-1989, 1993-1995, 1997-2012 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -33,8 +33,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "intervals.h"
 #include "window.h"
 #include "commands.h"
-#include "buffer.h"
 #include "character.h"
+#include "buffer.h"
 #include "region-cache.h"
 #include "indent.h"
 #include "blockinput.h"
@@ -107,8 +107,6 @@ static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS];
 
 int last_per_buffer_idx;
 
-static Lisp_Object Fset_buffer_major_mode (Lisp_Object);
-static Lisp_Object Fdelete_overlay (Lisp_Object);
 static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay,
                                     int after, Lisp_Object arg1,
                                     Lisp_Object arg2, Lisp_Object arg3);
@@ -128,7 +126,6 @@ static Lisp_Object Qchange_major_mode_hook;
 Lisp_Object Qfirst_change_hook;
 Lisp_Object Qbefore_change_functions;
 Lisp_Object Qafter_change_functions;
-static Lisp_Object Qucs_set_table_for_input;
 
 static Lisp_Object Qfundamental_mode, Qmode_class, Qpermanent_local;
 static Lisp_Object Qpermanent_local_hook;
@@ -272,7 +269,11 @@ See also `find-buffer-visiting'.  */)
      call the corresponding file handler.  */
   handler = Ffind_file_name_handler (filename, Qget_file_buffer);
   if (!NILP (handler))
-    return call2 (handler, Qget_file_buffer, filename);
+    {
+      Lisp_Object handled_buf = call2 (handler, Qget_file_buffer,
+                                      filename);
+      return BUFFERP (handled_buf) ? handled_buf : Qnil;
+    }
 
   for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
     {
@@ -389,7 +390,6 @@ even if it is dead.  The return value is never nil.  */)
 
   BVAR (b, mark) = Fmake_marker ();
   BUF_MARKERS (b) = NULL;
-  BVAR (b, name) = name;
 
   /* Put this in the alist of all live buffers.  */
   XSETBUFFER (buffer, b);
@@ -398,13 +398,6 @@ even if it is dead.  The return value is never nil.  */)
   if (!NILP (Vrun_hooks))
     call1 (Vrun_hooks, Qbuffer_list_update_hook);
 
-  /* 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)))
-    /* buffer is on buffer-alist, so no gcpro.  */
-    call1 (Qucs_set_table_for_input, buffer);
-
   return buffer;
 }
 
@@ -470,11 +463,7 @@ clone_per_buffer_values (struct buffer *from, struct buffer *to)
 
   XSETBUFFER (to_buffer, to);
 
-  /* buffer-local Lisp variables start at `undo_list',
-     tho only the ones from `name' on are GC'd normally.  */
-  for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER);
-       offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER);
-       offset += sizeof (Lisp_Object))
+  for_each_per_buffer_object_at (offset)
     {
       Lisp_Object obj;
 
@@ -616,7 +605,6 @@ CLONE nil means the indirect buffer's state is reset to default values.  */)
   Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil));
 
   BVAR (b, mark) = Fmake_marker ();
-  BVAR (b, name) = name;
 
   /* The multibyte status belongs to the base buffer.  */
   BVAR (b, enable_multibyte_characters) = BVAR (b->base_buffer, enable_multibyte_characters);
@@ -679,27 +667,40 @@ CLONE nil means the indirect buffer's state is reset to default values.  */)
   return buf;
 }
 
+/* Mark OV as no longer associated with B.  */
+
+static void
+drop_overlay (struct buffer *b, struct Lisp_Overlay *ov)
+{
+  eassert (b == XBUFFER (Fmarker_buffer (ov->start)));
+  modify_overlay (b, marker_position (ov->start), marker_position (ov->end));
+  Fset_marker (ov->start, Qnil, Qnil);
+  Fset_marker (ov->end, Qnil, Qnil);
+
+}
+
+/* Delete all overlays of B and reset it's overlay lists.  */
+
 void
 delete_all_overlays (struct buffer *b)
 {
-  Lisp_Object overlay;
+  struct Lisp_Overlay *ov, *next;
 
-  /* `reset_buffer' blindly sets the list of overlays to NULL, so we
-     have to empty the list, otherwise we end up with overlays that
-     think they belong to this buffer while the buffer doesn't know about
-     them any more.  */
-  while (b->overlays_before)
+  for (ov = b->overlays_before; ov; ov = next)
     {
-      XSETMISC (overlay, b->overlays_before);
-      Fdelete_overlay (overlay);
+      drop_overlay (b, ov);
+      next = ov->next;
+      ov->next = NULL;
     }
-  while (b->overlays_after)
+
+  for (ov = b->overlays_after; ov; ov = next)
     {
-      XSETMISC (overlay, b->overlays_after);
-      Fdelete_overlay (overlay);
+      drop_overlay (b, ov);
+      next = ov->next;
+      ov->next = NULL;
     }
-  eassert (b->overlays_before == NULL);
-  eassert (b->overlays_after == NULL);
+
+  b->overlays_before = b->overlays_after = NULL;
 }
 
 /* Reinitialize everything about a buffer except its name and contents
@@ -715,7 +716,7 @@ reset_buffer (register struct buffer *b)
   BVAR (b, filename) = Qnil;
   BVAR (b, file_truename) = Qnil;
   BVAR (b, directory) = (current_buffer) ? BVAR (current_buffer, directory) : Qnil;
-  b->modtime = 0;
+  EMACS_SET_SECS_NSECS (b->modtime, 0, UNKNOWN_MODTIME_NSECS);
   b->modtime_size = -1;
   XSETFASTINT (BVAR (b, save_length), 0);
   b->last_window_start = 1;
@@ -826,14 +827,8 @@ reset_buffer_local_variables (register struct buffer *b, int permanent_too)
     if (permanent_too || buffer_permanent_local_flags[i] == 0)
       SET_PER_BUFFER_VALUE_P (b, i, 0);
 
-  /* For each slot that has a default value,
-     copy that into the slot.  */
-
-  /* buffer-local Lisp variables start at `undo_list',
-     tho only the ones from `name' on are GC'd normally.  */
-  for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER);
-       offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER);
-       offset += sizeof (Lisp_Object))
+  /* For each slot that has a default value, copy that into the slot.  */
+  for_each_per_buffer_object_at (offset)
     {
       int idx = PER_BUFFER_IDX (offset);
       if ((idx > 0
@@ -854,10 +849,14 @@ 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.  */)
+it is in the sequence to be tried) even if a buffer with that name exists.
+
+If NAME begins with a space (i.e., a buffer that is not normally
+visible to users), then if buffer NAME already exists a random number
+is first appended to NAME, to speed up finding a non-existent buffer.  */)
   (register Lisp_Object name, Lisp_Object ignore)
 {
-  register Lisp_Object gentemp, tem;
+  register Lisp_Object gentemp, tem, tem2;
   ptrdiff_t count;
   char number[INT_BUFSIZE_BOUND (ptrdiff_t) + sizeof "<>"];
 
@@ -870,11 +869,23 @@ it is in the sequence to be tried) even if a buffer with that name exists.  */)
   if (NILP (tem))
     return name;
 
+  if (!strncmp (SSDATA (name), " ", 1)) /* see bug#1229 */
+    {
+      /* Note fileio.c:make_temp_name does random differently.  */
+      sprintf (number, "-%"pI"d", XFASTINT (Frandom (make_number (999999))));
+      tem2 = concat2 (name, build_string (number));
+      tem = Fget_buffer (tem2);
+      if (NILP (tem))
+       return tem2;
+    }
+  else
+    tem2 = name;
+
   count = 1;
   while (1)
     {
       sprintf (number, "<%"pD"d>", ++count);
-      gentemp = concat2 (name, build_string (number));
+      gentemp = concat2 (tem2, build_string (number));
       tem = Fstring_equal (gentemp, ignore);
       if (!NILP (tem))
        return gentemp;
@@ -938,6 +949,21 @@ DEFUN ("buffer-local-value", Fbuffer_local_value,
 If VARIABLE does not have a buffer-local binding in BUFFER, the value
 is the default binding of the variable. */)
   (register Lisp_Object variable, register Lisp_Object buffer)
+{
+  register Lisp_Object result = buffer_local_value_1 (variable, buffer);
+
+  if (EQ (result, Qunbound))
+    xsignal1 (Qvoid_variable, variable);
+
+  return result;
+}
+
+
+/* Like Fbuffer_local_value, but return Qunbound if the variable is
+   locally unbound.  */
+
+Lisp_Object
+buffer_local_value_1 (Lisp_Object variable, Lisp_Object buffer)
 {
   register struct buffer *buf;
   register Lisp_Object result;
@@ -991,10 +1017,7 @@ is the default binding of the variable. */)
     default: abort ();
     }
 
-  if (!EQ (result, Qunbound))
-    return result;
-
-  xsignal1 (Qvoid_variable, variable);
+  return result;
 }
 
 /* Return an alist of the Lisp-level buffer-local bindings of
@@ -1022,7 +1045,10 @@ buffer_lisp_local_variables (struct buffer *buf)
       if (buf != current_buffer)
        val = XCDR (elt);
 
-      result = Fcons (Fcons (XCAR (elt), val), result);
+      result = Fcons (EQ (val, Qunbound)
+                     ? XCAR (elt)
+                     : Fcons (XCAR (elt), val),
+                     result);
     }
 
   return result;
@@ -1054,19 +1080,17 @@ No argument or nil as argument means use current buffer as BUFFER.  */)
   {
     int offset, idx;
 
-    /* buffer-local Lisp variables start at `undo_list',
-       tho only the ones from `name' on are GC'd normally.  */
-    for (offset = PER_BUFFER_VAR_OFFSET (FIRST_FIELD_PER_BUFFER);
-        offset <= PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER);
-        /* sizeof EMACS_INT == sizeof Lisp_Object */
-        offset += (sizeof (EMACS_INT)))
+    for_each_per_buffer_object_at (offset)
       {
        idx = PER_BUFFER_IDX (offset);
        if ((idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
            && SYMBOLP (PER_BUFFER_SYMBOL (offset)))
-         result = Fcons (Fcons (PER_BUFFER_SYMBOL (offset),
-                                PER_BUFFER_VALUE (buf, offset)),
-                         result);
+         {
+           Lisp_Object sym = PER_BUFFER_SYMBOL (offset);
+           Lisp_Object val = PER_BUFFER_VALUE (buf, offset);
+           result = Fcons (EQ (val, Qunbound) ? sym : Fcons (sym, val),
+                           result);
+         }
       }
   }
 
@@ -1422,24 +1446,26 @@ No argument or nil as argument means do this for the current buffer.  */)
   DEFVAR_LISP ("kill-buffer-hook", ..., "\
 Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\
 The buffer being killed will be current while the hook is running.\n\
-See `kill-buffer'."
- */
+
+Functions run by this hook are supposed to not change the current
+buffer.  See `kill-buffer'."
+*/
 DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ",
-       doc: /* Kill buffer BUFFER-OR-NAME.
+       doc: /* Kill the buffer specified by BUFFER-OR-NAME.
 The argument may be a buffer or the name of an existing buffer.
 Argument nil or omitted means kill the current buffer.  Return t if the
 buffer is actually killed, nil otherwise.
 
-This function calls `replace-buffer-in-windows' for cleaning up all
-windows currently displaying the buffer to be killed.  The functions in
-`kill-buffer-query-functions' are called with the buffer to be killed as
-the current buffer.  If any of them returns nil, the buffer is not
-killed.  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.
+The functions in `kill-buffer-query-functions' are called with the
+buffer to be killed as the current buffer.  If any of them returns nil,
+the buffer is not killed.  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.  Functions called by any of these hooks are
+supposed to not change the current buffer.
 
 Any processes that have this buffer as the `process-buffer' are killed
-with SIGHUP.  */)
+with SIGHUP.  This function calls `replace-buffer-in-windows' for
+cleaning up all windows currently displaying the buffer to be killed. */)
   (Lisp_Object buffer_or_name)
 {
   Lisp_Object buffer;
@@ -1493,6 +1519,10 @@ with SIGHUP.  */)
     unbind_to (count, Qnil);
   }
 
+  /* If the hooks have killed the buffer, exit now.  */
+  if (NILP (BVAR (b, name)))
+    return Qt;
+
   /* We have no more questions to ask.  Verify that it is valid
      to kill the buffer.  This must be done after the questions
      since anything can happen within do_yes_or_no_p.  */
@@ -1501,9 +1531,6 @@ with SIGHUP.  */)
   if (EQ (buffer, XWINDOW (minibuf_window)->buffer))
     return Qnil;
 
-  if (NILP (BVAR (b, name)))
-    return Qnil;
-
   /* When we kill a base buffer, kill all its indirect buffers.
      We do it at this stage so nothing terrible happens if they
      ask questions or their hooks get errors.  */
@@ -1524,11 +1551,24 @@ with SIGHUP.  */)
          }
 
       UNGCPRO;
+
+      /* Exit if we now have killed the base buffer (Bug#11665).  */
+      if (NILP (BVAR (b, name)))
+       return Qt;
     }
 
-  /* Make this buffer not be current.
-     In the process, notice if this is the sole visible buffer
-     and give up if so.  */
+  /* Run replace_buffer_in_windows before making another buffer current
+     since set-window-buffer-start-and-point will refuse to make another
+     buffer current if the selected window does not show the current
+     buffer.  (Bug#10114) */
+  replace_buffer_in_windows (buffer);
+
+  /* Exit if replacing the buffer in windows has killed our buffer.  */
+  if (NILP (BVAR (b, name)))
+    return Qt;
+
+  /* Make this buffer not be current.  Exit if it is the sole visible
+     buffer.  */
   if (b == current_buffer)
     {
       tem = Fother_buffer (buffer, Qnil, Qnil);
@@ -1537,15 +1577,12 @@ with SIGHUP.  */)
        return Qnil;
     }
 
-  /* Notice if the buffer to kill is the sole visible buffer
-     when we're currently in the mini-buffer, and give up if so.  */
+  /* If the buffer now current is shown in the minibuffer and our buffer
+     is the sole other buffer give up.  */
   XSETBUFFER (tem, current_buffer);
-  if (EQ (tem, XWINDOW (minibuf_window)->buffer))
-    {
-      tem = Fother_buffer (buffer, Qnil, Qnil);
-      if (EQ (buffer, tem))
-       return Qnil;
-    }
+  if (EQ (tem, XWINDOW (minibuf_window)->buffer)
+      && EQ (buffer, Fother_buffer (buffer, Qnil, Qnil)))
+    return Qnil;
 
   /* Now there is no question: we can kill the buffer.  */
 
@@ -1558,15 +1595,13 @@ with SIGHUP.  */)
   kill_buffer_processes (buffer);
   UNGCPRO;
 
-  /* Killing buffer processes may run sentinels which may
-     have called kill-buffer.  */
-
+  /* Killing buffer processes may run sentinels which may have killed
+     our buffer.  */
   if (NILP (BVAR (b, name)))
-    return Qnil;
+    return Qt;
 
   /* These may run Lisp code and into infinite loops (if someone
      insisted on circular lists) so allow quitting here.  */
-  replace_buffer_in_windows (buffer);
   frames_discard_buffer (buffer);
 
   clear_charpos_cache (b);
@@ -1575,8 +1610,7 @@ with SIGHUP.  */)
   Vinhibit_quit = Qt;
   /* Remove the buffer from the list of all buffers.  */
   Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist);
-  /* If replace_buffer_in_windows didn't do its job correctly fix that
-     now.  */
+  /* If replace_buffer_in_windows didn't do its job fix that now.  */
   replace_buffer_in_windows_safely (buffer);
   Vinhibit_quit = tem;
 
@@ -1594,6 +1628,10 @@ with SIGHUP.  */)
        internal_delete_file (BVAR (b, auto_save_file_name));
     }
 
+  /* Deleting an auto-save file could have killed our buffer.  */
+  if (NILP (BVAR (b, name)))
+    return Qt;
+
   if (b->base_buffer)
     {
       /* Unchain all markers that belong to this indirect buffer.
@@ -1626,7 +1664,7 @@ with SIGHUP.  */)
 
   /* Reset the local variables, so that this buffer's local values
      won't be protected from GC.  They would be protected
-     if they happened to remain encached in their symbols.
+     if they happened to remain cached in their symbols.
      This gets rid of them for certain.  */
   swap_out_buffer_local_variables (b);
   reset_buffer_local_variables (b, 1);
@@ -1702,7 +1740,7 @@ record_buffer (Lisp_Object buffer)
 /* Move BUFFER to the end of the buffer (a)lists.  Do nothing if the
    buffer is killed.  For the selected frame's buffer list this moves
    BUFFER to its end even if it was never shown in that frame.  If
-   this happens we have a feature, hence `unrecord-buffer' should be
+   this happens we have a feature, hence `bury-buffer-internal' should be
    called only when BUFFER was shown in the selected frame.  */
 
 DEFUN ("bury-buffer-internal", Fbury_buffer_internal, Sbury_buffer_internal,
@@ -1998,10 +2036,6 @@ advance_to_char_boundary (ptrdiff_t byte_pos)
   return byte_pos;
 }
 
-#ifdef REL_ALLOC
-extern void r_alloc_reset_variable (POINTER_TYPE *, POINTER_TYPE *);
-#endif /* REL_ALLOC */
-
 DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
        1, 1, 0,
        doc: /* Swap the text between current buffer and BUFFER.  */)
@@ -2049,10 +2083,10 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
   eassert (current_buffer->text == &current_buffer->own_text);
   eassert (other_buffer->text == &other_buffer->own_text);
 #ifdef REL_ALLOC
-  r_alloc_reset_variable ((POINTER_TYPE **) &current_buffer->own_text.beg,
-                         (POINTER_TYPE **) &other_buffer->own_text.beg);
-  r_alloc_reset_variable ((POINTER_TYPE **) &other_buffer->own_text.beg,
-                         (POINTER_TYPE **) &current_buffer->own_text.beg);
+  r_alloc_reset_variable ((void **) &current_buffer->own_text.beg,
+                         (void **) &other_buffer->own_text.beg);
+  r_alloc_reset_variable ((void **) &other_buffer->own_text.beg,
+                         (void **) &current_buffer->own_text.beg);
 #endif /* REL_ALLOC */
 
   swapfield (pt, ptrdiff_t);
@@ -2480,7 +2514,7 @@ swap_out_buffer_local_variables (struct buffer *b)
       Lisp_Object sym = XCAR (XCAR (alist));
       eassert (XSYMBOL (sym)->redirect == SYMBOL_LOCALIZED);
       /* Need not do anything if some other buffer's binding is
-        now encached.  */
+        now cached.  */
       if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer))
        {
          /* Symbol is set up for this buffer's old local value:
@@ -2772,11 +2806,11 @@ mouse_face_overlay_overlaps (Lisp_Object overlay)
   Lisp_Object *v, tem;
 
   size = 10;
-  v = (Lisp_Object *) alloca (size * sizeof *v);
+  v = alloca (size * sizeof *v);
   n = overlays_in (start, end, 0, &v, &size, NULL, NULL);
   if (n > size)
     {
-      v = (Lisp_Object *) alloca (n * sizeof *v);
+      v = alloca (n * sizeof *v);
       overlays_in (start, end, 0, &v, &n, NULL, NULL);
     }
 
@@ -2848,6 +2882,12 @@ compare_overlays (const void *v1, const void *v2)
     return s1->beg < s2->beg ? -1 : 1;
   if (s1->end != s2->end)
     return s2->end < s1->end ? -1 : 1;
+  /* Avoid the non-determinism of qsort by choosing an arbitrary ordering
+     between "equal" overlays.  The result can still change between
+     invocations of Emacs, but it won't change in the middle of
+     `find_field' (bug#6830).  */
+  if (XHASH (s1->overlay) != XHASH (s2->overlay))
+    return XHASH (s1->overlay) < XHASH (s2->overlay) ? -1 : 1;
   return 0;
 }
 
@@ -2858,8 +2898,7 @@ ptrdiff_t
 sort_overlays (Lisp_Object *overlay_vec, ptrdiff_t noverlays, struct window *w)
 {
   ptrdiff_t i, j;
-  struct sortvec *sortvec;
-  sortvec = (struct sortvec *) alloca (noverlays * sizeof (struct sortvec));
+  struct sortvec *sortvec = alloca (noverlays * sizeof *sortvec);
 
   /* Put the valid and relevant overlays into sortvec.  */
 
@@ -3669,10 +3708,10 @@ If BUFFER is omitted, and OVERLAY is in no buffer, put it in the current
 buffer.  */)
   (Lisp_Object overlay, Lisp_Object beg, Lisp_Object end, Lisp_Object buffer)
 {
-  struct buffer *b, *ob;
+  struct buffer *b, *ob = 0;
   Lisp_Object obuffer;
   ptrdiff_t count = SPECPDL_INDEX ();
-  ptrdiff_t n_beg, n_end;
+  ptrdiff_t n_beg, n_end, o_beg IF_LINT (= 0), o_end IF_LINT (= 0);
 
   CHECK_OVERLAY (overlay);
   if (NILP (buffer))
@@ -3681,6 +3720,9 @@ buffer.  */)
     XSETBUFFER (buffer, current_buffer);
   CHECK_BUFFER (buffer);
 
+  if (NILP (Fbuffer_live_p (buffer)))
+    error ("Attempt to move overlay to a dead buffer");
+
   if (MARKERP (beg)
       && ! EQ (Fmarker_buffer (beg), buffer))
     error ("Marker points into wrong buffer");
@@ -3697,34 +3739,38 @@ buffer.  */)
       temp = beg; beg = end; end = temp;
     }
 
-  Fset_marker (OVERLAY_START (overlay), beg, buffer);
-  Fset_marker (OVERLAY_END (overlay), end, buffer);
-  n_beg = marker_position (OVERLAY_START (overlay));
-  n_end = marker_position (OVERLAY_END (overlay));
-
-  if (n_beg == n_end && ! NILP (Foverlay_get (overlay, Qevaporate)))
-    return Fdelete_overlay (overlay);
-
   specbind (Qinhibit_quit, Qt);
 
   obuffer = Fmarker_buffer (OVERLAY_START (overlay));
   b = XBUFFER (buffer);
-  ob = BUFFERP (obuffer) ? XBUFFER (obuffer) : (struct buffer *) 0;
+
+  if (!NILP (obuffer))
+    {
+      ob = XBUFFER (obuffer);
+
+      o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
+      o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
+
+      ob->overlays_before =
+        unchain_overlay (ob->overlays_before, XOVERLAY (overlay));
+      ob->overlays_after =
+        unchain_overlay (ob->overlays_after, XOVERLAY (overlay));
+      eassert (XOVERLAY (overlay)->next == NULL);
+    }
+
+  /* Set the overlay boundaries, which may clip them.  */
+  Fset_marker (OVERLAY_START (overlay), beg, buffer);
+  Fset_marker (OVERLAY_END (overlay), end, buffer);
+
+  n_beg = marker_position (OVERLAY_START (overlay));
+  n_end = marker_position (OVERLAY_END (overlay));
 
   /* If the overlay has changed buffers, do a thorough redisplay.  */
   if (!EQ (buffer, obuffer))
     {
       /* Redisplay where the overlay was.  */
-      if (!NILP (obuffer))
-       {
-         ptrdiff_t o_beg;
-         ptrdiff_t o_end;
-
-         o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
-         o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
-
-         modify_overlay (ob, o_beg, o_end);
-       }
+      if (ob)
+        modify_overlay (ob, o_beg, o_end);
 
       /* Redisplay where the overlay is going to be.  */
       modify_overlay (b, n_beg, n_end);
@@ -3732,11 +3778,6 @@ buffer.  */)
   else
     /* Redisplay the area the overlay has just left, or just enclosed.  */
     {
-      ptrdiff_t o_beg, o_end;
-
-      o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
-      o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
-
       if (o_beg == n_beg)
        modify_overlay (b, o_end, n_end);
       else if (o_end == n_end)
@@ -3745,16 +3786,13 @@ buffer.  */)
        modify_overlay (b, min (o_beg, n_beg), max (o_end, n_end));
     }
 
-  if (!NILP (obuffer))
-    {
-      ob->overlays_before
-       = unchain_overlay (ob->overlays_before, XOVERLAY (overlay));
-      ob->overlays_after
-       = unchain_overlay (ob->overlays_after, XOVERLAY (overlay));
-      eassert (XOVERLAY (overlay)->next == NULL);
-    }
+  /* Delete the overlay if it is empty after clipping and has the
+     evaporate property.  */
+  if (n_beg == n_end && !NILP (Foverlay_get (overlay, Qevaporate)))
+    return unbind_to (count, Fdelete_overlay (overlay));
 
-  /* Put the overlay on the wrong list.  */
+  /* Put the overlay into the new buffer's overlay lists, first on the
+     wrong list.  */
   if (n_end < b->overlay_center)
     {
       XOVERLAY (overlay)->next = b->overlays_after;
@@ -3789,14 +3827,13 @@ DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
   b = XBUFFER (buffer);
   specbind (Qinhibit_quit, Qt);
 
-  b->overlays_before = unchain_overlay (b->overlays_before,XOVERLAY (overlay));
-  b->overlays_after  = unchain_overlay (b->overlays_after, XOVERLAY (overlay));
+  b->overlays_before
+    = unchain_overlay (b->overlays_before, XOVERLAY (overlay));
+  b->overlays_after
+    = unchain_overlay (b->overlays_after, XOVERLAY (overlay));
   eassert (XOVERLAY (overlay)->next == NULL);
-  modify_overlay (b,
-                 marker_position (OVERLAY_START (overlay)),
-                 marker_position (OVERLAY_END   (overlay)));
-  Fset_marker (OVERLAY_START (overlay), Qnil, Qnil);
-  Fset_marker (OVERLAY_END   (overlay), Qnil, Qnil);
+
+  drop_overlay (b, XOVERLAY (overlay));
 
   /* When deleting an overlay with before or after strings, turn off
      display optimizations for the affected buffer, on the basis that
@@ -3864,7 +3901,7 @@ DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
 
   len = 10;
   /* We can't use alloca here because overlays_at can call xrealloc.  */
-  overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
+  overlay_vec = xmalloc (len * sizeof *overlay_vec);
 
   /* Put all the overlays we want in a vector in overlay_vec.
      Store the length in len.  */
@@ -3895,7 +3932,7 @@ end of the buffer.  */)
   CHECK_NUMBER_COERCE_MARKER (end);
 
   len = 10;
-  overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
+  overlay_vec = xmalloc (len * sizeof *overlay_vec);
 
   /* Put all the overlays we want in a vector in overlay_vec.
      Store the length in len.  */
@@ -3923,7 +3960,7 @@ the value is (point-max).  */)
   CHECK_NUMBER_COERCE_MARKER (pos);
 
   len = 10;
-  overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
+  overlay_vec = xmalloc (len * sizeof *overlay_vec);
 
   /* Put all the overlays we want in a vector in overlay_vec.
      Store the length in len.
@@ -3967,7 +4004,7 @@ the value is (point-min).  */)
     return pos;
 
   len = 10;
-  overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
+  overlay_vec = xmalloc (len * sizeof *overlay_vec);
 
   /* Put all the overlays we want in a vector in overlay_vec.
      Store the length in len.
@@ -4222,7 +4259,7 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, int after,
        First copy the vector contents, in case some of these hooks
        do subsequent modification of the buffer.  */
     ptrdiff_t size = last_overlay_modification_hooks_used;
-    Lisp_Object *copy = (Lisp_Object *) alloca (size * sizeof (Lisp_Object));
+    Lisp_Object *copy = alloca (size * sizeof *copy);
     ptrdiff_t i;
 
     memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents,
@@ -4375,7 +4412,7 @@ struct mmap_region
   /* Pointer to the location holding the address of the memory
      allocated with the mmap'd block.  The variable actually points
      after this structure.  */
-  POINTER_TYPE **var;
+  void **var;
 
   /* Next and previous in list of all mmap'd regions.  */
   struct mmap_region *next, *prev;
@@ -4399,7 +4436,7 @@ static int mmap_fd_1;
 
 static int mmap_page_size;
 
-/* 1 means mmap has been intialized.  */
+/* 1 means mmap has been initialized.  */
 
 static int mmap_initialized_p;
 
@@ -4422,7 +4459,7 @@ static int mmap_initialized_p;
    to the start of the user-visible part of the region.  */
 
 #define MMAP_USER_AREA(P) \
-     ((POINTER_TYPE *) ((char *) (P) + MMAP_REGION_STRUCT_SIZE))
+     ((void *) ((char *) (P) + MMAP_REGION_STRUCT_SIZE))
 
 #define MEM_ALIGN      sizeof (double)
 
@@ -4430,7 +4467,7 @@ static int mmap_initialized_p;
    is currently mapped.  Used to prevent overwriting an existing
    memory mapping.
 
-   Default is to conservativly assume the address range is occupied by
+   Default is to conservatively assume the address range is occupied by
    something else.  This can be overridden by system configuration
    files if system-specific means to determine this exists.  */
 
@@ -4438,7 +4475,7 @@ static int mmap_initialized_p;
 #define MMAP_ALLOCATED_P(start, end) 1
 #endif
 
-/* Perform necessary intializations for the use of mmap.  */
+/* Perform necessary initializations for the use of mmap.  */
 
 static void
 mmap_init (void)
@@ -4471,7 +4508,7 @@ mmap_init (void)
    is at END - 1.  */
 
 static struct mmap_region *
-mmap_find (POINTER_TYPE *start, POINTER_TYPE *end)
+mmap_find (void *start, void *end)
 {
   struct mmap_region *r;
   char *s = (char *) start, *e = (char *) end;
@@ -4509,7 +4546,7 @@ mmap_free_1 (struct mmap_region *r)
   else
     mmap_regions = r->next;
 
-  if (munmap ((POINTER_TYPE *) r, r->nbytes_mapped) == -1)
+  if (munmap (r, r->nbytes_mapped) == -1)
     {
       fprintf (stderr, "munmap: %s\n", emacs_strerror (errno));
       return 0;
@@ -4551,13 +4588,13 @@ mmap_enlarge (struct mmap_region *r, int npages)
         I'm not sure this is worth doing, let's see.  */
       if (!MMAP_ALLOCATED_P (region_end, region_end + nbytes))
        {
-         POINTER_TYPE *p;
+         void *p;
 
          p = mmap (region_end, nbytes, PROT_READ | PROT_WRITE,
                    MAP_ANON | MAP_PRIVATE | MAP_FIXED, mmap_fd, 0);
          if (p == MAP_FAILED)
            ; /* fprintf (stderr, "mmap: %s\n", emacs_strerror (errno)); */
-         else if (p != (POINTER_TYPE *) region_end)
+         else if (p != region_end)
            {
              /* Kernels are free to choose a different address.  In
                 that case, unmap what we've mapped above; we have
@@ -4619,8 +4656,8 @@ mmap_set_vars (int restore_p)
    If we can't allocate the necessary memory, set *VAR to null, and
    return null.  */
 
-static POINTER_TYPE *
-mmap_alloc (POINTER_TYPE **var, size_t nbytes)
+static void *
+mmap_alloc (void **var, size_t nbytes)
 {
   void *p;
   size_t map;
@@ -4661,7 +4698,7 @@ mmap_alloc (POINTER_TYPE **var, size_t nbytes)
    PTR.  Store 0 in *PTR to show there's no block allocated.  */
 
 static void
-mmap_free (POINTER_TYPE **var)
+mmap_free (void **var)
 {
   mmap_init ();
 
@@ -4678,10 +4715,10 @@ mmap_free (POINTER_TYPE **var)
    and return this value.  If more memory cannot be allocated, then
    leave *VAR unchanged, and return null.  */
 
-static POINTER_TYPE *
-mmap_realloc (POINTER_TYPE **var, size_t nbytes)
+static void *
+mmap_realloc (void **var, size_t nbytes)
 {
-  POINTER_TYPE *result;
+  void *result;
 
   mmap_init ();
 
@@ -4700,7 +4737,7 @@ mmap_realloc (POINTER_TYPE **var, size_t nbytes)
       if (room < nbytes)
        {
          /* Must enlarge.  */
-         POINTER_TYPE *old_ptr = *var;
+         void *old_ptr = *var;
 
          /* Try to map additional pages at the end of the region.
             If that fails, allocate a new region,  copy data
@@ -4757,25 +4794,18 @@ mmap_realloc (POINTER_TYPE **var, size_t nbytes)
                            Buffer-text Allocation
  ***********************************************************************/
 
-#ifdef REL_ALLOC
-extern POINTER_TYPE *r_alloc (POINTER_TYPE **, size_t);
-extern POINTER_TYPE *r_re_alloc (POINTER_TYPE **, size_t);
-extern void r_alloc_free (POINTER_TYPE **ptr);
-#endif /* REL_ALLOC */
-
-
 /* Allocate NBYTES bytes for buffer B's text buffer.  */
 
 static void
 alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
 {
-  POINTER_TYPE *p;
+  void *p;
 
   BLOCK_INPUT;
 #if defined USE_MMAP_FOR_BUFFERS
-  p = mmap_alloc ((POINTER_TYPE **) &b->text->beg, nbytes);
+  p = mmap_alloc ((void **) &b->text->beg, nbytes);
 #elif defined REL_ALLOC
-  p = r_alloc ((POINTER_TYPE **) &b->text->beg, nbytes);
+  p = r_alloc ((void **) &b->text->beg, nbytes);
 #else
   p = xmalloc (nbytes);
 #endif
@@ -4796,14 +4826,14 @@ alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
 void
 enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
 {
-  POINTER_TYPE *p;
+  void *p;
   ptrdiff_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
                      + delta);
   BLOCK_INPUT;
 #if defined USE_MMAP_FOR_BUFFERS
-  p = mmap_realloc ((POINTER_TYPE **) &b->text->beg, nbytes);
+  p = mmap_realloc ((void **) &b->text->beg, nbytes);
 #elif defined REL_ALLOC
-  p = r_re_alloc ((POINTER_TYPE **) &b->text->beg, nbytes);
+  p = r_re_alloc ((void **) &b->text->beg, nbytes);
 #else
   p = xrealloc (b->text->beg, nbytes);
 #endif
@@ -4827,9 +4857,9 @@ free_buffer_text (struct buffer *b)
   BLOCK_INPUT;
 
 #if defined USE_MMAP_FOR_BUFFERS
-  mmap_free ((POINTER_TYPE **) &b->text->beg);
+  mmap_free ((void **) &b->text->beg);
 #elif defined REL_ALLOC
-  r_alloc_free ((POINTER_TYPE **) &b->text->beg);
+  r_alloc_free ((void **) &b->text->beg);
 #else
   xfree (b->text->beg);
 #endif
@@ -4848,6 +4878,12 @@ void
 init_buffer_once (void)
 {
   int idx;
+  /* If you add, remove, or reorder Lisp_Objects in a struct buffer, make
+     sure that this is still correct.  Otherwise, mark_vectorlike may not
+     trace all Lisp_Objects in buffer_defaults and buffer_local_symbols.  */
+  const int pvecsize
+    = (offsetof (struct buffer, own_text) - sizeof (struct vectorlike_header))
+    / sizeof (Lisp_Object);
 
   memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags);
 
@@ -4864,9 +4900,9 @@ init_buffer_once (void)
   buffer_local_symbols.text = &buffer_local_symbols.own_text;
   BUF_INTERVALS (&buffer_defaults) = 0;
   BUF_INTERVALS (&buffer_local_symbols) = 0;
-  XSETPVECTYPESIZE (&buffer_defaults, PVEC_BUFFER, 0);
+  XSETPVECTYPESIZE (&buffer_defaults, PVEC_BUFFER, pvecsize);
   XSETBUFFER (Vbuffer_defaults, &buffer_defaults);
-  XSETPVECTYPESIZE (&buffer_local_symbols, PVEC_BUFFER, 0);
+  XSETPVECTYPESIZE (&buffer_local_symbols, PVEC_BUFFER, pvecsize);
   XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols);
 
   /* Set up the default values of various buffer slots.  */
@@ -4880,9 +4916,7 @@ init_buffer_once (void)
   BVAR (&buffer_defaults, case_fold_search) = Qt;
   BVAR (&buffer_defaults, auto_fill_function) = Qnil;
   BVAR (&buffer_defaults, selective_display) = Qnil;
-#ifndef old
   BVAR (&buffer_defaults, selective_display_ellipses) = Qt;
-#endif
   BVAR (&buffer_defaults, abbrev_table) = Qnil;
   BVAR (&buffer_defaults, display_table) = Qnil;
   BVAR (&buffer_defaults, undo_list) = Qnil;
@@ -4961,9 +4995,7 @@ init_buffer_once (void)
   XSETFASTINT (BVAR (&buffer_local_flags, case_fold_search), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, auto_fill_function), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, selective_display), idx); ++idx;
-#ifndef old
   XSETFASTINT (BVAR (&buffer_local_flags, selective_display_ellipses), idx); ++idx;
-#endif
   XSETFASTINT (BVAR (&buffer_local_flags, tab_width), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, truncate_lines), idx); ++idx;
   XSETFASTINT (BVAR (&buffer_local_flags, word_wrap), idx); ++idx;
@@ -5021,8 +5053,6 @@ init_buffer_once (void)
   Qkill_buffer_hook = intern_c_string ("kill-buffer-hook");
   Fput (Qkill_buffer_hook, Qpermanent_local, Qt);
 
-  Qucs_set_table_for_input = intern_c_string ("ucs-set-table-for-input");
-
   /* super-magic invisible buffer */
   Vprin1_to_string_buffer = Fget_buffer_create (make_pure_c_string (" prin1"));
   Vbuffer_alist = Qnil;
@@ -5067,7 +5097,7 @@ init_buffer (void)
   if (!(IS_DIRECTORY_SEP (pwd[len - 1])))
     {
       /* Grow buffer to add directory separator and '\0'.  */
-      pwd = (char *) realloc (pwd, len + 2);
+      pwd = realloc (pwd, len + 2);
       if (!pwd)
        fatal ("`get_current_dir_name' failed: %s\n", strerror (errno));
       pwd[len] = DIRECTORY_SEP;
@@ -5178,9 +5208,6 @@ syms_of_buffer (void)
   DEFSYM (Qafter_change_functions, "after-change-functions");
   DEFSYM (Qkill_buffer_query_functions, "kill-buffer-query-functions");
 
-  /* The next one is initialized in init_buffer_once.  */
-  staticpro (&Qucs_set_table_for_input);
-
   Fput (Qprotected_field, Qerror_conditions,
        pure_cons (Qprotected_field, pure_cons (Qerror, Qnil)));
   Fput (Qprotected_field, Qerror_message,
@@ -5222,7 +5249,7 @@ This is the same as (default-value 'ctl-arrow).  */);
 
   DEFVAR_BUFFER_DEFAULTS ("default-enable-multibyte-characters",
                          enable_multibyte_characters,
-                         doc: /* *Default value of `enable-multibyte-characters' for buffers not overriding it.
+                         doc: /* Default value of `enable-multibyte-characters' for buffers not overriding it.
 This is the same as (default-value 'enable-multibyte-characters).  */);
 
   DEFVAR_BUFFER_DEFAULTS ("default-buffer-file-coding-system",
@@ -5332,31 +5359,40 @@ the mode line appears at the bottom.  */);
   DEFVAR_PER_BUFFER ("mode-line-format", &BVAR (current_buffer, mode_line_format),
                     Qnil,
                     doc: /* Template for displaying mode line for current buffer.
-Each buffer has its own value of this variable.
-Value may be nil, a string, a symbol or a list or cons cell.
+
+The value may be nil, a string, a symbol or a list.
+
 A value of nil means don't display a mode line.
-For a symbol, its value is used (but it is ignored if t or nil).
- A string appearing directly as the value of a symbol is processed verbatim
- in that the %-constructs below are not recognized.
- Note that unless the symbol is marked as a `risky-local-variable', all
- properties in any strings, as well as all :eval and :propertize forms
- in the value of that symbol will be ignored.
-For a list of the form `(:eval FORM)', FORM is evaluated and the result
- is used as a mode line element.  Be careful--FORM should not load any files,
- because that can cause an infinite recursion.
-For a list of the form `(:propertize ELT PROPS...)', ELT is displayed
- with the specified properties PROPS applied.
-For a list whose car is a symbol, the symbol's value is taken,
- and if that is non-nil, the cadr of the list is processed recursively.
- Otherwise, the caddr of the list (if there is one) is processed.
-For a list whose car is a string or list, each element is processed
- recursively and the results are effectively concatenated.
-For a list whose car is an integer, the cdr of the list is processed
-  and padded (if the number is positive) or truncated (if negative)
-  to the width specified by that number.
+
+For any symbol other than t or nil, the symbol's value is processed as
+ a mode line construct.  As a special exception, if that value is a
+ string, the string is processed verbatim, without handling any
+ %-constructs (see below).  Also, unless the symbol has a non-nil
+ `risky-local-variable' property, all properties in any strings, as
+ well as all :eval and :propertize forms in the value, are ignored.
+
+A list whose car is a string or list is processed by processing each
+ of the list elements recursively, as separate mode line constructs,
+ and concatenating the results.
+
+A list of the form `(:eval FORM)' is processed by evaluating FORM and
+ using the result as a mode line construct.  Be careful--FORM should
+ not load any files, because that can cause an infinite recursion.
+
+A list of the form `(:propertize ELT PROPS...)' is processed by
+ processing ELT as the mode line construct, and adding the text
+ properties PROPS to the result.
+
+A list whose car is a symbol is processed by examining the symbol's
+ value, and, if that value is non-nil, processing the cadr of the list
+ recursively; and if that value is nil, processing the caddr of the
+ list recursively.
+
+A list whose car is an integer is processed by processing the cadr of
+ the list, and padding (if the number is positive) or truncating (if
+ negative) to the width specified by that number.
+
 A string is printed verbatim in the mode line except for %-constructs:
-  (%-constructs are allowed when the string is the entire mode-line-format
-   or when it is found in a cons-cell or a list)
   %b -- print buffer name.      %f -- print visited file name.
   %F -- print frame name.
   %* -- print %, * or hyphen.   %+ -- print *, % or hyphen.
@@ -5384,7 +5420,7 @@ A string is printed verbatim in the mode line except for %-constructs:
 Decimal digits after the % specify field width to which to pad.  */);
 
   DEFVAR_BUFFER_DEFAULTS ("default-major-mode", major_mode,
-                         doc: /* *Value of `major-mode' for new buffers.  */);
+                         doc: /* Value of `major-mode' for new buffers.  */);
 
   DEFVAR_PER_BUFFER ("major-mode", &BVAR (current_buffer, major_mode),
                     make_number (Lisp_Symbol),
@@ -5415,25 +5451,25 @@ Use the command `abbrev-mode' to change this variable.  */);
 
   DEFVAR_PER_BUFFER ("case-fold-search", &BVAR (current_buffer, case_fold_search),
                     Qnil,
-                    doc: /* *Non-nil if searches and matches should ignore case.  */);
+                    doc: /* Non-nil if searches and matches should ignore case.  */);
 
   DEFVAR_PER_BUFFER ("fill-column", &BVAR (current_buffer, fill_column),
                     make_number (LISP_INT_TAG),
-                    doc: /* *Column beyond which automatic line-wrapping should happen.
+                    doc: /* Column beyond which automatic line-wrapping should happen.
 Interactively, you can set the buffer local value using \\[set-fill-column].  */);
 
   DEFVAR_PER_BUFFER ("left-margin", &BVAR (current_buffer, left_margin),
                     make_number (LISP_INT_TAG),
-                    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", &BVAR (current_buffer, tab_width),
                     make_number (LISP_INT_TAG),
-                    doc: /* *Distance between tab stops (for display of tab characters), in columns.
+                    doc: /* Distance between tab stops (for display of tab characters), in columns.
 This should be an integer greater than zero.  */);
 
   DEFVAR_PER_BUFFER ("ctl-arrow", &BVAR (current_buffer, ctl_arrow), Qnil,
-                    doc: /* *Non-nil means display control chars with uparrow.
+                    doc: /* Non-nil means display control chars with uparrow.
 A value of nil means use backslash and octal digits.
 This variable does not apply to characters whose display is specified
 in the current display table (if there is one).  */);
@@ -5474,7 +5510,7 @@ This variable is never applied to a way of decoding a file while reading it.  */
 
   DEFVAR_PER_BUFFER ("bidi-paragraph-direction",
                     &BVAR (current_buffer, bidi_paragraph_direction), Qnil,
-                    doc: /* *If non-nil, forces directionality of text paragraphs in the buffer.
+                    doc: /* If non-nil, forces directionality of text paragraphs in the buffer.
 
 If this is nil (the default), the direction of each paragraph is
 determined by the first strong directional character of its text.
@@ -5485,7 +5521,7 @@ This variable has no effect unless the buffer's value of
 \`bidi-display-reordering' is non-nil.  */);
 
  DEFVAR_PER_BUFFER ("truncate-lines", &BVAR (current_buffer, truncate_lines), Qnil,
-                    doc: /* *Non-nil means do not display continuation lines.
+                    doc: /* Non-nil means do not display continuation lines.
 Instead, give each line of text just one screen line.
 
 Note that this is overridden by the variable
@@ -5495,7 +5531,7 @@ and this buffer is not full-frame width.
 Minibuffers set this variable to nil.  */);
 
   DEFVAR_PER_BUFFER ("word-wrap", &BVAR (current_buffer, word_wrap), Qnil,
-                    doc: /* *Non-nil means to use word-wrapping for continuation lines.
+                    doc: /* Non-nil means to use word-wrapping for continuation lines.
 When word-wrapping is on, continuation lines are wrapped at the space
 or tab character nearest to the right window edge.
 If nil, continuation lines are wrapped at the right screen edge.
@@ -5504,7 +5540,13 @@ This variable has no effect if long lines are truncated (see
 `truncate-lines' and `truncate-partial-width-windows').  If you use
 word-wrapping, you might want to reduce the value of
 `truncate-partial-width-windows', since wrapping can make text readable
-in narrower windows.  */);
+in narrower windows.
+
+Instead of setting this variable directly, most users should use
+Visual Line mode .  Visual Line mode, when enabled, sets `word-wrap'
+to t, and additionally redefines simple editing commands to act on
+visual lines rather than logical lines.  See the documentation of
+`visual-line-mode'.  */);
 
   DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory),
                     make_number (Lisp_String),
@@ -5561,12 +5603,10 @@ 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.  */);
 
-#ifndef old
   DEFVAR_PER_BUFFER ("selective-display-ellipses",
                     &BVAR (current_buffer, selective_display_ellipses),
                     Qnil,
                     doc: /* Non-nil means display ... on previous line when a line is invisible.  */);
-#endif
 
   DEFVAR_PER_BUFFER ("overwrite-mode", &BVAR (current_buffer, overwrite_mode), Qnil,
                     doc: /* Non-nil if self-insertion should replace existing text.
@@ -5616,39 +5656,39 @@ See also the functions `display-table-slot' and `set-display-table-slot'.  */);
 
   DEFVAR_PER_BUFFER ("left-margin-width", &BVAR (current_buffer, left_margin_cols),
                     Qnil,
-                    doc: /* *Width of left marginal area for display of a buffer.
+                    doc: /* Width of left marginal area for display of a buffer.
 A value of nil means no marginal area.  */);
 
   DEFVAR_PER_BUFFER ("right-margin-width", &BVAR (current_buffer, right_margin_cols),
                     Qnil,
-                    doc: /* *Width of right marginal area for display of a buffer.
+                    doc: /* Width of right marginal area for display of a buffer.
 A value of nil means no marginal area.  */);
 
   DEFVAR_PER_BUFFER ("left-fringe-width", &BVAR (current_buffer, left_fringe_width),
                     Qnil,
-                    doc: /* *Width of this buffer's left fringe (in pixels).
+                    doc: /* Width of this buffer's left fringe (in pixels).
 A value of 0 means no left fringe is shown in this buffer's window.
 A value of nil means to use the left fringe width from the window's frame.  */);
 
   DEFVAR_PER_BUFFER ("right-fringe-width", &BVAR (current_buffer, right_fringe_width),
                     Qnil,
-                    doc: /* *Width of this buffer's right fringe (in pixels).
+                    doc: /* Width of this buffer's right fringe (in pixels).
 A value of 0 means no right fringe is shown in this buffer's window.
 A value of nil means to use the right fringe width from the window's frame.  */);
 
   DEFVAR_PER_BUFFER ("fringes-outside-margins", &BVAR (current_buffer, fringes_outside_margins),
                     Qnil,
-                    doc: /* *Non-nil means to display fringes outside display margins.
+                    doc: /* Non-nil means to display fringes outside display margins.
 A value of nil means to display fringes between margins and buffer text.  */);
 
   DEFVAR_PER_BUFFER ("scroll-bar-width", &BVAR (current_buffer, scroll_bar_width),
                     Qnil,
-                    doc: /* *Width of this buffer's scroll bars in pixels.
+                    doc: /* Width of this buffer's scroll bars in pixels.
 A value of nil means to use the scroll bar width from the window's frame.  */);
 
   DEFVAR_PER_BUFFER ("vertical-scroll-bar", &BVAR (current_buffer, vertical_scroll_bar_type),
                     Qnil,
-                    doc: /* *Position of this buffer's vertical scroll bar.
+                    doc: /* Position of this buffer's vertical scroll bar.
 The value takes effect whenever you tell a window to display this buffer;
 for instance, with `set-window-buffer' or when `display-buffer' displays it.
 
@@ -5658,13 +5698,13 @@ A value of t (the default) means do whatever the window's frame specifies.  */);
 
   DEFVAR_PER_BUFFER ("indicate-empty-lines",
                     &BVAR (current_buffer, indicate_empty_lines), Qnil,
-                    doc: /* *Visually indicate empty lines after the buffer end.
+                    doc: /* Visually indicate empty lines after the buffer end.
 If non-nil, a bitmap is displayed in the left fringe of a window on
 window-systems.  */);
 
   DEFVAR_PER_BUFFER ("indicate-buffer-boundaries",
                     &BVAR (current_buffer, indicate_buffer_boundaries), Qnil,
-                    doc: /* *Visually indicate buffer boundaries and scrolling.
+                    doc: /* Visually indicate buffer boundaries and scrolling.
 If non-nil, the first and last line of the buffer are marked in the fringe
 of a window on window-systems with angle bitmaps, or if the window can be
 scrolled, the top and bottom line of the window are marked with up and down
@@ -5689,7 +5729,7 @@ fringe, but no arrow bitmaps, use ((top .  left) (bottom . left)).  */);
 
   DEFVAR_PER_BUFFER ("fringe-indicator-alist",
                     &BVAR (current_buffer, fringe_indicator_alist), Qnil,
-                    doc: /* *Mapping from logical to physical fringe indicator bitmaps.
+                    doc: /* Mapping from logical to physical fringe indicator bitmaps.
 The value is an alist where each element (INDICATOR . BITMAPS)
 specifies the fringe bitmaps used to display a specific logical
 fringe indicator.
@@ -5708,7 +5748,7 @@ symbol which is used in both left and right fringes.  */);
 
   DEFVAR_PER_BUFFER ("fringe-cursor-alist",
                     &BVAR (current_buffer, fringe_cursor_alist), Qnil,
-                    doc: /* *Mapping from logical to physical fringe cursor bitmaps.
+                    doc: /* Mapping from logical to physical fringe cursor bitmaps.
 The value is an alist where each element (CURSOR . BITMAP)
 specifies the fringe bitmaps used to display a specific logical
 cursor type in the fringe.
@@ -5801,9 +5841,9 @@ An entry (TEXT . POSITION) represents the deletion of the string TEXT
 from (abs POSITION).  If POSITION is positive, point was at the front
 of the text being deleted; if negative, point was at the end.
 
-An entry (t HIGH . LOW) indicates that the buffer previously had
-\"unmodified\" status.  HIGH and LOW are the high and low 16-bit portions
-of the visited file's modification time, as of that time.  If the
+An entry (t HIGH LOW USEC PSEC) indicates that the buffer was previously
+unmodified; (HIGH LOW USEC PSEC) is in the same style as (current-time)
+and is the visited file's modification time, as of that time.  If the
 modification time of the most recent save is different, this entry is
 obsolete.
 
@@ -5872,7 +5912,7 @@ set when a file is visited.  */);
 
   DEFVAR_PER_BUFFER ("buffer-auto-save-file-format",
                     &BVAR (current_buffer, auto_save_file_format), Qnil,
-                    doc: /* *Format in which to write auto-save files.
+                    doc: /* Format in which to write auto-save files.
 Should be a list of symbols naming formats that are defined in `format-alist'.
 If it is t, which is the default, auto-save files are written in the
 same format as a regular save would use.  */);
@@ -5922,7 +5962,7 @@ Lisp programs may give this variable certain special values:
   Vtransient_mark_mode = Qnil;
 
   DEFVAR_LISP ("inhibit-read-only", Vinhibit_read_only,
-              doc: /* *Non-nil means disregard read-only status of buffers or characters.
+              doc: /* Non-nil means disregard read-only status of buffers or characters.
 If the value is t, disregard `buffer-read-only' and all `read-only'
 text properties.  If the value is a list, disregard `buffer-read-only'
 and disregard a `read-only' text property if the property value
@@ -5957,7 +5997,7 @@ to the default frame line height.  A value of nil means add no extra space.  */)
 
   DEFVAR_PER_BUFFER ("cursor-in-non-selected-windows",
                     &BVAR (current_buffer, cursor_in_non_selected_windows), Qnil,
-                    doc: /* *Non-nil means show a cursor in non-selected windows.
+                    doc: /* Non-nil means show a cursor in non-selected windows.
 If nil, only shows a cursor in the selected window.
 If t, displays a cursor related to the usual cursor type
 \(a solid box becomes hollow, a bar becomes a narrower bar).
@@ -5967,7 +6007,9 @@ Use Custom to set this variable and update the display."  */);
   DEFVAR_LISP ("kill-buffer-query-functions", Vkill_buffer_query_functions,
               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.  */);
+
+If any of them returns nil, the buffer is not killed.  Functions run by
+this hook are supposed to not change the current buffer.  */);
   Vkill_buffer_query_functions = Qnil;
 
   DEFVAR_LISP ("change-major-mode-hook", Vchange_major_mode_hook,
@@ -5980,7 +6022,7 @@ The function `kill-all-local-variables' runs this before doing anything else.  *
               doc: /* Hook run when the buffer list changes.
 Functions running this hook are `get-buffer-create',
 `make-indirect-buffer', `rename-buffer', `kill-buffer',
-`record-buffer' and `unrecord-buffer'.  */);
+and `bury-buffer-internal'.  */);
   Vbuffer_list_update_hook = Qnil;
   DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook");