* simple.el (count-words): Report on narrowing.
[bpt/emacs.git] / lisp / simple.el
index c813856..3240ede 100644 (file)
@@ -1,6 +1,6 @@
 ;;; simple.el --- basic editing commands for Emacs
 
 ;;; simple.el --- basic editing commands for Emacs
 
-;; Copyright (C) 1985-1987, 1993-201 Free Software Foundation, Inc.
+;; Copyright (C) 1985-1987, 1993-2012 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: internal
 
 ;; Maintainer: FSF
 ;; Keywords: internal
@@ -28,8 +28,6 @@
 
 ;;; Code:
 
 
 ;;; Code:
 
-(eval-when-compile (require 'cl))       ;For define-minor-mode.
-
 (declare-function widget-convert "wid-edit" (type &rest args))
 (declare-function shell-mode "shell" ())
 
 (declare-function widget-convert "wid-edit" (type &rest args))
 (declare-function shell-mode "shell" ())
 
@@ -321,9 +319,11 @@ select the source buffer."
 
 (define-minor-mode next-error-follow-minor-mode
   "Minor mode for compilation, occur and diff modes.
 
 (define-minor-mode next-error-follow-minor-mode
   "Minor mode for compilation, occur and diff modes.
+With a prefix argument ARG, enable mode if ARG is positive, and
+disable it otherwise.  If called from Lisp, enable mode if ARG is
+omitted or nil.
 When turned on, cursor motion in the compilation, grep, occur or diff
 When turned on, cursor motion in the compilation, grep, occur or diff
-buffer causes automatic display of the corresponding source code
-location."
+buffer causes automatic display of the corresponding source code location."
   :group 'next-error :init-value nil :lighter " Fol"
   (if (not next-error-follow-minor-mode)
       (remove-hook 'post-command-hook 'next-error-follow-mode-post-command-hook t)
   :group 'next-error :init-value nil :lighter " Fol"
   (if (not next-error-follow-minor-mode)
       (remove-hook 'post-command-hook 'next-error-follow-mode-post-command-hook t)
@@ -349,7 +349,8 @@ location."
 Other major modes are defined by comparison with this one."
   (interactive)
   (kill-all-local-variables)
 Other major modes are defined by comparison with this one."
   (interactive)
   (kill-all-local-variables)
-  (run-mode-hooks 'fundamental-mode-hook))
+  (unless delay-mode-hooks
+    (run-hooks 'after-change-major-mode-hook)))
 
 ;; Special major modes to view specially formatted data rather than files.
 
 
 ;; Special major modes to view specially formatted data rather than files.
 
@@ -814,7 +815,7 @@ instead of deleted."
   :type '(choice (const :tag "Delete active region" t)
                  (const :tag "Kill active region" kill)
                  (const :tag "Do ordinary deletion" nil))
   :type '(choice (const :tag "Delete active region" t)
                  (const :tag "Kill active region" kill)
                  (const :tag "Do ordinary deletion" nil))
-  :group 'editing
+  :group 'killing
   :version "24.1")
 
 (defun delete-backward-char (n &optional killflag)
   :version "24.1")
 
 (defun delete-backward-char (n &optional killflag)
@@ -877,6 +878,7 @@ KILLFLAG is set if N was explicitly specified."
 
 (defun mark-whole-buffer ()
   "Put point at beginning and mark at end of buffer.
 
 (defun mark-whole-buffer ()
   "Put point at beginning and mark at end of buffer.
+If narrowing is in effect, only uses the accessible part of the buffer.
 You probably should not use this function in Lisp programs;
 it is usually a mistake for a Lisp function to use any subroutine
 that uses or sets the mark."
 You probably should not use this function in Lisp programs;
 it is usually a mistake for a Lisp function to use any subroutine
 that uses or sets the mark."
@@ -889,16 +891,23 @@ that uses or sets the mark."
 ;; Counting lines, one way or another.
 
 (defun goto-line (line &optional buffer)
 ;; Counting lines, one way or another.
 
 (defun goto-line (line &optional buffer)
-  "Goto LINE, counting from line 1 at beginning of buffer.
-Normally, move point in the current buffer, and leave mark at the
-previous position.  With just \\[universal-argument] as argument,
-move point in the most recently selected other buffer, and switch to it.
+  "Go to LINE, counting from line 1 at beginning of buffer.
+If called interactively, a numeric prefix argument specifies
+LINE; without a numeric prefix argument, read LINE from the
+minibuffer.
+
+If optional argument BUFFER is non-nil, switch to that buffer and
+move to line LINE there.  If called interactively with \\[universal-argument]
+as argument, BUFFER is the most recently selected other buffer.
 
 
-If there's a number in the buffer at point, it is the default for LINE.
+Prior to moving point, this function sets the mark (without
+activating it), unless Transient Mark mode is enabled and the
+mark is already active.
 
 This function is usually the wrong thing to use in a Lisp program.
 What you probably want instead is something like:
 
 This function is usually the wrong thing to use in a Lisp program.
 What you probably want instead is something like:
-  (goto-char (point-min)) (forward-line (1- N))
+  (goto-char (point-min))
+  (forward-line (1- N))
 If at all possible, an even better solution is to use char counts
 rather than line counts."
   (interactive
 If at all possible, an even better solution is to use char counts
 rather than line counts."
   (interactive
@@ -945,28 +954,55 @@ rather than line counts."
       (forward-line (1- line)))))
 
 (defun count-words-region (start end)
       (forward-line (1- line)))))
 
 (defun count-words-region (start end)
-  "Count the number of words in the active region.
-If the region is not active, counts the number of words in the buffer."
-  (interactive (if (use-region-p) (list (region-beginning) (region-end))
-                 (list (point-min) (point-max))))
-  (let ((count 0))
-    (save-excursion
-      (save-restriction
-        (narrow-to-region start end)
-        (goto-char (point-min))
-        (while (forward-word 1)
-          (setq count (1+ count)))))
-    (when (called-interactively-p 'interactive)
-      (message "%s has %d words"
-               (if (use-region-p) "Region" "Buffer")
-               count))
-    count))
-
-(defun count-lines-region (start end)
-  "Print number of lines and characters in the region."
+  "Count the number of words in the region.
+If called interactively, print a message reporting the number of
+lines, words, and chars in the region.
+If called from Lisp, return the number of words between positions
+START and END."
   (interactive "r")
   (interactive "r")
-  (message "Region has %d lines, %d characters"
-          (count-lines start end) (- end start)))
+  (if (called-interactively-p 'any)
+      (count-words--message "Region" start end)
+    (count-words start end)))
+
+(defun count-words (start end)
+  "Count words between START and END.
+If called interactively, START and END are normally the start and
+end of the buffer; but if the region is active, START and END are
+the start and end of the region.  Print a message reporting the
+number of lines, words, and chars.
+
+If called from Lisp, return the number of words between START and
+END, without printing any message."
+  (interactive (list nil nil))
+  (cond ((not (called-interactively-p 'any))
+        (let ((words 0))
+          (save-excursion
+            (save-restriction
+              (narrow-to-region start end)
+              (goto-char (point-min))
+              (while (forward-word 1)
+                (setq words (1+ words)))))
+          words))
+       ((use-region-p)
+        (call-interactively 'count-words-region))
+       (t
+        (count-words--message
+         (if (= (point-max) (1+ (buffer-size)))
+             "Buffer"
+           "Narrowed part of buffer")
+         (point-min) (point-max)))))
+
+(defun count-words--message (str start end)
+  (let ((lines (count-lines start end))
+       (words (count-words start end))
+       (chars (- end start)))
+    (message "%s has %d line%s, %d word%s, and %d character%s."
+            str
+            lines (if (= lines 1) "" "s")
+            words (if (= words 1) "" "s")
+            chars (if (= chars 1) "" "s"))))
+
+(define-obsolete-function-alias 'count-lines-region 'count-words-region "24.1")
 
 (defun what-line ()
   "Print the current buffer line number and narrowed line number of point."
 
 (defun what-line ()
   "Print the current buffer line number and narrowed line number of point."
@@ -1032,6 +1068,23 @@ In addition, with prefix argument, show details about that character
 in *Help* buffer.  See also the command `describe-char'."
   (interactive "P")
   (let* ((char (following-char))
 in *Help* buffer.  See also the command `describe-char'."
   (interactive "P")
   (let* ((char (following-char))
+        (bidi-fixer
+         (cond ((memq char '(?\x202a ?\x202b ?\x202d ?\x202e))
+                ;; If the character is one of LRE, LRO, RLE, RLO, it
+                ;; will start a directional embedding, which could
+                ;; completely disrupt the rest of the line (e.g., RLO
+                ;; will display the rest of the line right-to-left).
+                ;; So we put an invisible PDF character after these
+                ;; characters, to end the embedding, which eliminates
+                ;; any effects on the rest of the line.
+                (propertize (string ?\x202c) 'invisible t))
+               ;; Strong right-to-left characters cause reordering of
+               ;; the following numerical characters which show the
+               ;; codepoint, so append LRM to countermand that.
+               ((memq (get-char-code-property char 'bidi-class) '(R AL))
+                (propertize (string ?\x200e) 'invisible t))
+               (t
+                "")))
         (beg (point-min))
         (end (point-max))
          (pos (point))
         (beg (point-min))
         (end (point-max))
          (pos (point))
@@ -1091,18 +1144,19 @@ in *Help* buffer.  See also the command `describe-char'."
            ;; We show the detailed information about CHAR.
            (describe-char (point)))
        (if (or (/= beg 1) (/= end (1+ total)))
            ;; We show the detailed information about CHAR.
            (describe-char (point)))
        (if (or (/= beg 1) (/= end (1+ total)))
-           (message "Char: %s %s point=%d of %d (%d%%) <%d-%d> column=%d%s"
+           (message "Char: %s%s %s point=%d of %d (%d%%) <%d-%d> column=%d%s"
                     (if (< char 256)
                         (single-key-description char)
                       (buffer-substring-no-properties (point) (1+ (point))))
                     (if (< char 256)
                         (single-key-description char)
                       (buffer-substring-no-properties (point) (1+ (point))))
+                    bidi-fixer
                     encoding-msg pos total percent beg end col hscroll)
                     encoding-msg pos total percent beg end col hscroll)
-         (message "Char: %s %s point=%d of %d (%d%%) column=%d%s"
+         (message "Char: %s%s %s point=%d of %d (%d%%) column=%d%s"
                   (if enable-multibyte-characters
                       (if (< char 128)
                           (single-key-description char)
                         (buffer-substring-no-properties (point) (1+ (point))))
                     (single-key-description char))
                   (if enable-multibyte-characters
                       (if (< char 128)
                           (single-key-description char)
                         (buffer-substring-no-properties (point) (1+ (point))))
                     (single-key-description char))
-                  encoding-msg pos total percent col hscroll))))))
+                  bidi-fixer encoding-msg pos total percent col hscroll))))))
 \f
 ;; Initialize read-expression-map.  It is defined at C level.
 (let ((m (make-sparse-keymap)))
 \f
 ;; Initialize read-expression-map.  It is defined at C level.
 (let ((m (make-sparse-keymap)))
@@ -1187,11 +1241,11 @@ this command arranges for all errors to enter the debugger."
       (push (eval eval-expression-arg lexical-binding) values)
     (let ((old-value (make-symbol "t")) new-value)
       ;; Bind debug-on-error to something unique so that we can
       (push (eval eval-expression-arg lexical-binding) values)
     (let ((old-value (make-symbol "t")) new-value)
       ;; Bind debug-on-error to something unique so that we can
-      ;; detect when evaled code changes it.
+      ;; detect when evalled code changes it.
       (let ((debug-on-error old-value))
        (push (eval eval-expression-arg lexical-binding) values)
        (setq new-value debug-on-error))
       (let ((debug-on-error old-value))
        (push (eval eval-expression-arg lexical-binding) values)
        (setq new-value debug-on-error))
-      ;; If evaled code has changed the value of debug-on-error,
+      ;; If evalled code has changed the value of debug-on-error,
       ;; propagate that change to the global binding.
       (unless (eq old-value new-value)
        (setq debug-on-error new-value))))
       ;; propagate that change to the global binding.
       (unless (eq old-value new-value)
        (setq debug-on-error new-value))))
@@ -1302,6 +1356,60 @@ to get different commands to edit and resubmit."
             "M-x ")
      obarray 'commandp t nil 'extended-command-history)))
 
             "M-x ")
      obarray 'commandp t nil 'extended-command-history)))
 
+(defcustom suggest-key-bindings t
+  "Non-nil means show the equivalent key-binding when M-x command has one.
+The value can be a length of time to show the message for.
+If the value is non-nil and not a number, we wait 2 seconds."
+  :group 'keyboard
+  :type '(choice (const :tag "off" nil)
+                 (integer :tag "time" 2)
+                 (other :tag "on")))
+
+(defun execute-extended-command (prefixarg &optional command-name)
+  ;; Based on Fexecute_extended_command in keyboard.c of Emacs.
+  ;; Aaron S. Hawley <aaron.s.hawley(at)gmail.com> 2009-08-24
+  "Read function name, then read its arguments and call it.
+
+To pass a numeric argument to the command you are invoking with, specify
+the numeric argument to this command.
+
+Noninteractively, the argument PREFIXARG is the prefix argument to
+give to the command you invoke, if it asks for an argument."
+  (interactive (list current-prefix-arg (read-extended-command)))
+  ;; Emacs<24 calling-convention was with a single `prefixarg' argument.
+  (if (null command-name) (setq command-name (read-extended-command)))
+  (let* ((function (and (stringp command-name) (intern-soft command-name)))
+         (binding (and suggest-key-bindings
+                      (not executing-kbd-macro)
+                      (where-is-internal function overriding-local-map t))))
+    (unless (commandp function)
+      (error "`%s' is not a valid command name" command-name))
+    (setq this-command function)
+    ;; Normally `real-this-command' should never be changed, but here we really
+    ;; want to pretend that M-x <cmd> RET is nothing more than a "key
+    ;; binding" for <cmd>, so the command the user really wanted to run is
+    ;; `function' and not `execute-extended-command'.  The difference is
+    ;; visible in cases such as M-x <cmd> RET and then C-x z (bug#11506).
+    (setq real-this-command function)
+    (let ((prefix-arg prefixarg))
+      (command-execute function 'record))
+    ;; If enabled, show which key runs this command.
+    (when binding
+      ;; But first wait, and skip the message if there is input.
+      (let* ((waited
+              ;; If this command displayed something in the echo area;
+              ;; wait a few seconds, then display our suggestion message.
+              (sit-for (cond
+                        ((zerop (length (current-message))) 0)
+                        ((numberp suggest-key-bindings) suggest-key-bindings)
+                        (t 2)))))
+        (when (and waited (not (consp unread-command-events)))
+          (with-temp-message
+              (format "You can run the command `%s' with %s"
+                      function (key-description binding))
+            (sit-for (if (numberp suggest-key-bindings)
+                         suggest-key-bindings
+                       2))))))))
 \f
 (defvar minibuffer-history nil
   "Default minibuffer history list.
 \f
 (defvar minibuffer-history nil
   "Default minibuffer history list.
@@ -1363,7 +1471,7 @@ See also `minibuffer-history-case-insensitive-variables'."
      (list (if (string= regexp "")
               (if minibuffer-history-search-history
                   (car minibuffer-history-search-history)
      (list (if (string= regexp "")
               (if minibuffer-history-search-history
                   (car minibuffer-history-search-history)
-                (error "No previous history search regexp"))
+                (user-error "No previous history search regexp"))
             regexp)
           (prefix-numeric-value current-prefix-arg))))
   (unless (zerop n)
             regexp)
           (prefix-numeric-value current-prefix-arg))))
   (unless (zerop n)
@@ -1389,9 +1497,9 @@ See also `minibuffer-history-case-insensitive-variables'."
        (setq prevpos pos)
        (setq pos (min (max 1 (+ pos (if (< n 0) -1 1))) (length history)))
        (when (= pos prevpos)
        (setq prevpos pos)
        (setq pos (min (max 1 (+ pos (if (< n 0) -1 1))) (length history)))
        (when (= pos prevpos)
-         (error (if (= pos 1)
-                    "No later matching history item"
-                  "No earlier matching history item")))
+         (user-error (if (= pos 1)
+                          "No later matching history item"
+                        "No earlier matching history item")))
        (setq match-string
              (if (eq minibuffer-history-sexp-flag (minibuffer-depth))
                  (let ((print-level nil))
        (setq match-string
              (if (eq minibuffer-history-sexp-flag (minibuffer-depth))
                  (let ((print-level nil))
@@ -1434,7 +1542,7 @@ makes the search case-sensitive."
      (list (if (string= regexp "")
               (if minibuffer-history-search-history
                   (car minibuffer-history-search-history)
      (list (if (string= regexp "")
               (if minibuffer-history-search-history
                   (car minibuffer-history-search-history)
-                (error "No previous history search regexp"))
+                (user-error "No previous history search regexp"))
             regexp)
           (prefix-numeric-value current-prefix-arg))))
   (previous-matching-history-element regexp (- n)))
             regexp)
           (prefix-numeric-value current-prefix-arg))))
   (previous-matching-history-element regexp (- n)))
@@ -1493,11 +1601,11 @@ The argument NABS specifies the absolute history position."
        (setq minibuffer-text-before-history
              (minibuffer-contents-no-properties)))
     (if (< nabs minimum)
        (setq minibuffer-text-before-history
              (minibuffer-contents-no-properties)))
     (if (< nabs minimum)
-       (if minibuffer-default
-           (error "End of defaults; no next item")
-         (error "End of history; no default available")))
+       (user-error (if minibuffer-default
+                        "End of defaults; no next item"
+                      "End of history; no default available")))
     (if (> nabs (length (symbol-value minibuffer-history-variable)))
     (if (> nabs (length (symbol-value minibuffer-history-variable)))
-       (error "Beginning of history; no preceding item"))
+       (user-error "Beginning of history; no preceding item"))
     (unless (memq last-command '(next-history-element
                                 previous-history-element))
       (let ((prompt-end (minibuffer-prompt-end)))
     (unless (memq last-command '(next-history-element
                                 previous-history-element))
       (let ((prompt-end (minibuffer-prompt-end)))
@@ -1552,7 +1660,7 @@ by the new completion."
      n)
     ;; next-matching-history-element always puts us at (point-min).
     ;; Move to the position we were at before changing the buffer contents.
      n)
     ;; next-matching-history-element always puts us at (point-min).
     ;; Move to the position we were at before changing the buffer contents.
-    ;; This is still sensical, because the text before point has not changed.
+    ;; This is still sensible, because the text before point has not changed.
     (goto-char point-at-start)))
 
 (defun previous-complete-history-element (n)
     (goto-char point-at-start)))
 
 (defun previous-complete-history-element (n)
@@ -1597,58 +1705,50 @@ Intended to be added to `minibuffer-setup-hook'."
 
 (defun minibuffer-history-isearch-search ()
   "Return the proper search function, for isearch in minibuffer history."
 
 (defun minibuffer-history-isearch-search ()
   "Return the proper search function, for isearch in minibuffer history."
-  (cond
-   (isearch-word
-    (if isearch-forward 'word-search-forward 'word-search-backward))
-   (t
-    (lambda (string bound noerror)
-      (let ((search-fun
-            ;; Use standard functions to search within minibuffer text
-             (cond
-              (isearch-regexp
-               (if isearch-forward 're-search-forward 're-search-backward))
-              (t
-               (if isearch-forward 'search-forward 'search-backward))))
-           found)
-       ;; Avoid lazy-highlighting matches in the minibuffer prompt when
-       ;; searching forward.  Lazy-highlight calls this lambda with the
-       ;; bound arg, so skip the minibuffer prompt.
-       (if (and bound isearch-forward (< (point) (minibuffer-prompt-end)))
-           (goto-char (minibuffer-prompt-end)))
-        (or
-        ;; 1. First try searching in the initial minibuffer text
-        (funcall search-fun string
-                 (if isearch-forward bound (minibuffer-prompt-end))
-                 noerror)
-        ;; 2. If the above search fails, start putting next/prev history
-        ;; elements in the minibuffer successively, and search the string
-        ;; in them.  Do this only when bound is nil (i.e. not while
-        ;; lazy-highlighting search strings in the current minibuffer text).
-        (unless bound
-          (condition-case nil
-              (progn
-                (while (not found)
-                  (cond (isearch-forward
-                         (next-history-element 1)
-                         (goto-char (minibuffer-prompt-end)))
-                        (t
-                         (previous-history-element 1)
-                         (goto-char (point-max))))
-                  (setq isearch-barrier (point) isearch-opoint (point))
-                  ;; After putting the next/prev history element, search
-                  ;; the string in them again, until next-history-element
-                  ;; or previous-history-element raises an error at the
-                  ;; beginning/end of history.
-                  (setq found (funcall search-fun string
-                                       (unless isearch-forward
-                                         ;; For backward search, don't search
-                                         ;; in the minibuffer prompt
-                                         (minibuffer-prompt-end))
-                                       noerror)))
-                ;; Return point of the new search result
-                (point))
-            ;; Return nil when next(prev)-history-element fails
-            (error nil)))))))))
+  (lambda (string bound noerror)
+    (let ((search-fun
+          ;; Use standard functions to search within minibuffer text
+          (isearch-search-fun-default))
+         found)
+      ;; Avoid lazy-highlighting matches in the minibuffer prompt when
+      ;; searching forward.  Lazy-highlight calls this lambda with the
+      ;; bound arg, so skip the minibuffer prompt.
+      (if (and bound isearch-forward (< (point) (minibuffer-prompt-end)))
+         (goto-char (minibuffer-prompt-end)))
+      (or
+       ;; 1. First try searching in the initial minibuffer text
+       (funcall search-fun string
+               (if isearch-forward bound (minibuffer-prompt-end))
+               noerror)
+       ;; 2. If the above search fails, start putting next/prev history
+       ;; elements in the minibuffer successively, and search the string
+       ;; in them.  Do this only when bound is nil (i.e. not while
+       ;; lazy-highlighting search strings in the current minibuffer text).
+       (unless bound
+        (condition-case nil
+            (progn
+              (while (not found)
+                (cond (isearch-forward
+                       (next-history-element 1)
+                       (goto-char (minibuffer-prompt-end)))
+                      (t
+                       (previous-history-element 1)
+                       (goto-char (point-max))))
+                (setq isearch-barrier (point) isearch-opoint (point))
+                ;; After putting the next/prev history element, search
+                ;; the string in them again, until next-history-element
+                ;; or previous-history-element raises an error at the
+                ;; beginning/end of history.
+                (setq found (funcall search-fun string
+                                     (unless isearch-forward
+                                       ;; For backward search, don't search
+                                       ;; in the minibuffer prompt
+                                       (minibuffer-prompt-end))
+                                     noerror)))
+              ;; Return point of the new search result
+              (point))
+          ;; Return nil when next(prev)-history-element fails
+          (error nil)))))))
 
 (defun minibuffer-history-isearch-message (&optional c-q-hack ellipsis)
   "Display the minibuffer history search prompt.
 
 (defun minibuffer-history-isearch-message (&optional c-q-hack ellipsis)
   "Display the minibuffer history search prompt.
@@ -1679,14 +1779,13 @@ Otherwise, it displays the standard isearch message returned from
   "Wrap the minibuffer history search when search fails.
 Move point to the first history element for a forward search,
 or to the last history element for a backward search."
   "Wrap the minibuffer history search when search fails.
 Move point to the first history element for a forward search,
 or to the last history element for a backward search."
-  (unless isearch-word
-    ;; When `minibuffer-history-isearch-search' fails on reaching the
-    ;; beginning/end of the history, wrap the search to the first/last
-    ;; minibuffer history element.
-    (if isearch-forward
-       (goto-history-element (length (symbol-value minibuffer-history-variable)))
-      (goto-history-element 0))
-    (setq isearch-success t))
+  ;; When `minibuffer-history-isearch-search' fails on reaching the
+  ;; beginning/end of the history, wrap the search to the first/last
+  ;; minibuffer history element.
+  (if isearch-forward
+      (goto-history-element (length (symbol-value minibuffer-history-variable)))
+    (goto-history-element 0))
+  (setq isearch-success t)
   (goto-char (if isearch-forward (minibuffer-prompt-end) (point-max))))
 
 (defun minibuffer-history-isearch-push-state ()
   (goto-char (if isearch-forward (minibuffer-prompt-end) (point-max))))
 
 (defun minibuffer-history-isearch-push-state ()
@@ -1843,8 +1942,8 @@ Some change-hooks test this variable to do something different.")
 Call `undo-start' to get ready to undo recent changes,
 then call `undo-more' one or more times to undo them."
   (or (listp pending-undo-list)
 Call `undo-start' to get ready to undo recent changes,
 then call `undo-more' one or more times to undo them."
   (or (listp pending-undo-list)
-      (error (concat "No further undo information"
-                    (and undo-in-region " for region"))))
+      (user-error (concat "No further undo information"
+                          (and undo-in-region " for region"))))
   (let ((undo-in-progress t))
     ;; Note: The following, while pulling elements off
     ;; `pending-undo-list' will call primitive change functions which
   (let ((undo-in-progress t))
     ;; Note: The following, while pulling elements off
     ;; `pending-undo-list' will call primitive change functions which
@@ -1870,7 +1969,7 @@ If BEG and END are specified, then only undo elements
 that apply to text between BEG and END are used; other undo elements
 are ignored.  If BEG and END are nil, all undo elements are used."
   (if (eq buffer-undo-list t)
 that apply to text between BEG and END are used; other undo elements
 are ignored.  If BEG and END are nil, all undo elements are used."
   (if (eq buffer-undo-list t)
-      (error "No undo information in this buffer"))
+      (user-error "No undo information in this buffer"))
   (setq pending-undo-list
        (if (and beg end (not (= beg end)))
            (undo-make-selective-list (min beg end) (max beg end))
   (setq pending-undo-list
        (if (and beg end (not (= beg end)))
            (undo-make-selective-list (min beg end) (max beg end))
@@ -2098,7 +2197,7 @@ of `history-length', which see.")
   "Switch used to have the shell execute its command line argument.")
 
 (defvar shell-command-default-error-buffer nil
   "Switch used to have the shell execute its command line argument.")
 
 (defvar shell-command-default-error-buffer nil
-  "*Buffer name for `shell-command' and `shell-command-on-region' error output.
+  "Buffer name for `shell-command' and `shell-command-on-region' error output.
 This buffer is used when `shell-command' or `shell-command-on-region'
 is run interactively.  A value of nil means that output to stderr and
 stdout will be intermixed in the output stream.")
 This buffer is used when `shell-command' or `shell-command-on-region'
 is run interactively.  A value of nil means that output to stderr and
 stdout will be intermixed in the output stream.")
@@ -2152,9 +2251,11 @@ to `shell-command-history'."
 (defun async-shell-command (command &optional output-buffer error-buffer)
   "Execute string COMMAND asynchronously in background.
 
 (defun async-shell-command (command &optional output-buffer error-buffer)
   "Execute string COMMAND asynchronously in background.
 
-Like `shell-command' but if COMMAND doesn't end in ampersand, adds `&'
-surrounded by whitespace and executes the command asynchronously.
+Like `shell-command', but adds `&' at the end of COMMAND
+to execute it asynchronously.
+
 The output appears in the buffer `*Async Shell Command*'.
 The output appears in the buffer `*Async Shell Command*'.
+That buffer is in shell mode.
 
 In Elisp, you will often be better served by calling `start-process'
 directly, since it offers more control and does not impose the use of a
 
 In Elisp, you will often be better served by calling `start-process'
 directly, since it offers more control and does not impose the use of a
@@ -2162,8 +2263,12 @@ shell (with its need to quote arguments)."
   (interactive
    (list
     (read-shell-command "Async shell command: " nil nil
   (interactive
    (list
     (read-shell-command "Async shell command: " nil nil
-                       (and buffer-file-name
-                            (file-relative-name buffer-file-name)))
+                       (let ((filename
+                              (cond
+                               (buffer-file-name)
+                               ((eq major-mode 'dired-mode)
+                                (dired-get-filename nil t)))))
+                         (and filename (file-relative-name filename))))
     current-prefix-arg
     shell-command-default-error-buffer))
   (unless (string-match "&[ \t]*\\'" command)
     current-prefix-arg
     shell-command-default-error-buffer))
   (unless (string-match "&[ \t]*\\'" command)
@@ -2174,9 +2279,10 @@ shell (with its need to quote arguments)."
   "Execute string COMMAND in inferior shell; display output, if any.
 With prefix argument, insert the COMMAND's output at point.
 
   "Execute string COMMAND in inferior shell; display output, if any.
 With prefix argument, insert the COMMAND's output at point.
 
-If COMMAND ends in ampersand, execute it asynchronously.
+If COMMAND ends in `&', execute it asynchronously.
 The output appears in the buffer `*Async Shell Command*'.
 The output appears in the buffer `*Async Shell Command*'.
-That buffer is in shell mode.
+That buffer is in shell mode.  You can also use
+`async-shell-command' that automatically adds `&'.
 
 Otherwise, COMMAND is executed synchronously.  The output appears in
 the buffer `*Shell Command Output*'.  If the output is short enough to
 
 Otherwise, COMMAND is executed synchronously.  The output appears in
 the buffer `*Shell Command Output*'.  If the output is short enough to
@@ -2379,7 +2485,7 @@ and only used if a buffer is displayed."
                                            1))
                                   1)))
                         ;; Don't use the echo area if the output buffer is
                                            1))
                                   1)))
                         ;; Don't use the echo area if the output buffer is
-                        ;; already dispayed in the selected frame.
+                        ;; already displayed in the selected frame.
                         (not (get-buffer-window (current-buffer))))
                    ;; Echo area
                    (goto-char (point-max))
                         (not (get-buffer-window (current-buffer))))
                    ;; Echo area
                    (goto-char (point-max))
@@ -2412,9 +2518,9 @@ COMMAND.
 To specify a coding system for converting non-ASCII characters
 in the input and output to the shell command, use \\[universal-coding-system-argument]
 before this command.  By default, the input (from the current buffer)
 To specify a coding system for converting non-ASCII characters
 in the input and output to the shell command, use \\[universal-coding-system-argument]
 before this command.  By default, the input (from the current buffer)
-is encoded in the same coding system that will be used to save the file,
-`buffer-file-coding-system'.  If the output is going to replace the region,
-then it is decoded from that same coding system.
+is encoded using coding-system specified by `process-coding-system-alist',
+falling back to `default-process-coding-system' if no match for COMMAND
+is found in `process-coding-system-alist'.
 
 The noninteractive arguments are START, END, COMMAND,
 OUTPUT-BUFFER, REPLACE, ERROR-BUFFER, and DISPLAY-ERROR-BUFFER.
 
 The noninteractive arguments are START, END, COMMAND,
 OUTPUT-BUFFER, REPLACE, ERROR-BUFFER, and DISPLAY-ERROR-BUFFER.
@@ -2625,13 +2731,13 @@ value passed."
 (defvar process-file-side-effects t
   "Whether a call of `process-file' changes remote files.
 
 (defvar process-file-side-effects t
   "Whether a call of `process-file' changes remote files.
 
-Per default, this variable is always set to `t', meaning that a
+By default, this variable is always set to `t', meaning that a
 call of `process-file' could potentially change any file on a
 remote host.  When set to `nil', a file handler could optimize
 call of `process-file' could potentially change any file on a
 remote host.  When set to `nil', a file handler could optimize
-its behaviour with respect to remote file attributes caching.
+its behavior with respect to remote file attribute caching.
 
 
-This variable should never be changed by `setq'.  Instead of, it
-shall be set only by let-binding.")
+You should only ever change this variable with a let-binding;
+never with `setq'.")
 
 (defun start-file-process (name buffer program &rest program-args)
   "Start a program in a subprocess.  Return the process object for it.
 
 (defun start-file-process (name buffer program &rest program-args)
   "Start a program in a subprocess.  Return the process object for it.
@@ -2675,47 +2781,50 @@ support pty association, if PROGRAM is nil."
   (tabulated-list-init-header))
 
 (defun list-processes--refresh ()
   (tabulated-list-init-header))
 
 (defun list-processes--refresh ()
-  "Recompute the list of processes for the Process List buffer."
+  "Recompute the list of processes for the Process List buffer.
+Also, delete any process that is exited or signaled."
   (setq tabulated-list-entries nil)
   (dolist (p (process-list))
   (setq tabulated-list-entries nil)
   (dolist (p (process-list))
-    (when (or (not process-menu-query-only)
-             (process-query-on-exit-flag p))
-      (let* ((buf (process-buffer p))
-            (type (process-type p))
-            (name (process-name p))
-            (status (symbol-name (process-status p)))
-            (buf-label (if (buffer-live-p buf)
-                           `(,(buffer-name buf)
-                             face link
-                             help-echo ,(concat "Visit buffer `"
-                                                (buffer-name buf) "'")
-                             follow-link t
-                             process-buffer ,buf
-                             action process-menu-visit-buffer)
-                         "--"))
-            (tty (or (process-tty-name p) "--"))
-            (cmd
-             (if (memq type '(network serial))
-                 (let ((contact (process-contact p t)))
-                   (if (eq type 'network)
-                       (format "(%s %s)"
-                               (if (plist-get contact :type)
-                                   "datagram"
-                                 "network")
-                               (if (plist-get contact :server)
-                                   (format "server on %s"
-                                           (plist-get contact :server))
-                                 (format "connection to %s"
-                                         (plist-get contact :host))))
-                     (format "(serial port %s%s)"
-                             (or (plist-get contact :port) "?")
-                             (let ((speed (plist-get contact :speed)))
-                               (if speed
-                                   (format " at %s b/s" speed)
-                                 "")))))
-               (mapconcat 'identity (process-command p) " "))))
-       (push (list p (vector name status buf-label tty cmd))
-             tabulated-list-entries)))))
+    (cond ((memq (process-status p) '(exit signal closed))
+          (delete-process p))
+         ((or (not process-menu-query-only)
+              (process-query-on-exit-flag p))
+          (let* ((buf (process-buffer p))
+                 (type (process-type p))
+                 (name (process-name p))
+                 (status (symbol-name (process-status p)))
+                 (buf-label (if (buffer-live-p buf)
+                                `(,(buffer-name buf)
+                                  face link
+                                  help-echo ,(concat "Visit buffer `"
+                                                     (buffer-name buf) "'")
+                                  follow-link t
+                                  process-buffer ,buf
+                                  action process-menu-visit-buffer)
+                              "--"))
+                 (tty (or (process-tty-name p) "--"))
+                 (cmd
+                  (if (memq type '(network serial))
+                      (let ((contact (process-contact p t)))
+                        (if (eq type 'network)
+                            (format "(%s %s)"
+                                    (if (plist-get contact :type)
+                                        "datagram"
+                                      "network")
+                                    (if (plist-get contact :server)
+                                        (format "server on %s"
+                                                (plist-get contact :server))
+                                      (format "connection to %s"
+                                              (plist-get contact :host))))
+                          (format "(serial port %s%s)"
+                                  (or (plist-get contact :port) "?")
+                                  (let ((speed (plist-get contact :speed)))
+                                    (if speed
+                                        (format " at %s b/s" speed)
+                                      "")))))
+                    (mapconcat 'identity (process-command p) " "))))
+            (push (list p (vector name status buf-label tty cmd))
+                  tabulated-list-entries))))))
 
 (defun process-menu-visit-buffer (button)
   (display-buffer (button-get button 'process-buffer)))
 
 (defun process-menu-visit-buffer (button)
   (display-buffer (button-get button 'process-buffer)))
@@ -2876,28 +2985,46 @@ These commands include \\[set-mark-command] and \\[start-kbd-macro]."
 \f
 
 (defvar filter-buffer-substring-functions nil
 \f
 
 (defvar filter-buffer-substring-functions nil
-  "Wrapper hook around `filter-buffer-substring'.
-The functions on this special hook are called with 4 arguments:
-  NEXT-FUN BEG END DELETE
-NEXT-FUN is a function of 3 arguments (BEG END DELETE)
-that performs the default operation.  The other 3 arguments are like
-the ones passed to `filter-buffer-substring'.")
+  "This variable is a wrapper hook around `filter-buffer-substring'.
+Each member of the hook should be a function accepting four arguments:
+\(FUN BEG END DELETE), where FUN is itself a function of three arguments
+\(BEG END DELETE).  The arguments BEG, END, and DELETE are the same
+as those of `filter-buffer-substring' in each case.
+
+The first hook function to be called receives a FUN equivalent
+to the default operation of `filter-buffer-substring',
+i.e. one that returns the buffer-substring between BEG and
+END (processed by any `buffer-substring-filters').  Normally,
+the hook function will call FUN and then do its own processing
+of the result.  The next hook function receives a FUN equivalent
+to the previous hook function, calls it, and does its own
+processing, and so on.  The overall result is that of all hook
+functions acting in sequence.
+
+Any hook may choose not to call FUN though, in which case it
+effectively replaces the default behavior with whatever it chooses.
+Of course, a later hook function may do the same thing.")
 
 (defvar buffer-substring-filters nil
   "List of filter functions for `filter-buffer-substring'.
 Each function must accept a single argument, a string, and return
 a string.  The buffer substring is passed to the first function
 in the list, and the return value of each function is passed to
 
 (defvar buffer-substring-filters nil
   "List of filter functions for `filter-buffer-substring'.
 Each function must accept a single argument, a string, and return
 a string.  The buffer substring is passed to the first function
 in the list, and the return value of each function is passed to
-the next.  The return value of the last function is used as the
-return value of `filter-buffer-substring'.
+the next.  The final result (if `buffer-substring-filters' is
+nil, this is the unfiltered buffer-substring) is passed to the
+first function on `filter-buffer-substring-functions'.
 
 
-If this variable is nil, no filtering is performed.")
+As a special convention, point is set to the start of the buffer text
+being operated on (i.e., the first argument of `filter-buffer-substring')
+before these functions are called.")
 (make-obsolete-variable 'buffer-substring-filters
                         'filter-buffer-substring-functions "24.1")
 
 (defun filter-buffer-substring (beg end &optional delete)
   "Return the buffer substring between BEG and END, after filtering.
 (make-obsolete-variable 'buffer-substring-filters
                         'filter-buffer-substring-functions "24.1")
 
 (defun filter-buffer-substring (beg end &optional delete)
   "Return the buffer substring between BEG and END, after filtering.
-The filtering is performed by `filter-buffer-substring-functions'.
+The wrapper hook `filter-buffer-substring-functions' performs
+the actual filtering.  The obsolete variable `buffer-substring-filters'
+is also consulted.  If both of these are nil, no filtering is done.
 
 If DELETE is non-nil, the text between BEG and END is deleted
 from the buffer.
 
 If DELETE is non-nil, the text between BEG and END is deleted
 from the buffer.
@@ -2926,41 +3053,43 @@ be copied into other buffers."
 
 (defvar interprogram-cut-function nil
   "Function to call to make a killed region available to other programs.
 
 (defvar interprogram-cut-function nil
   "Function to call to make a killed region available to other programs.
+Most window systems provide a facility for cutting and pasting
+text between different programs, such as the clipboard on X and
+MS-Windows, or the pasteboard on Nextstep/Mac OS.
 
 
-Most window systems provide some sort of facility for cutting and
-pasting text between the windows of different programs.
-This variable holds a function that Emacs calls whenever text
-is put in the kill ring, to make the new kill available to other
-programs.
-
-The function takes one argument, TEXT, which is a string containing
-the text which should be made available.")
+This variable holds a function that Emacs calls whenever text is
+put in the kill ring, to make the new kill available to other
+programs.  The function takes one argument, TEXT, which is a
+string containing the text which should be made available.")
 
 (defvar interprogram-paste-function nil
   "Function to call to get text cut from other programs.
 
 (defvar interprogram-paste-function nil
   "Function to call to get text cut from other programs.
-
-Most window systems provide some sort of facility for cutting and
-pasting text between the windows of different programs.
-This variable holds a function that Emacs calls to obtain
-text that other programs have provided for pasting.
-
-The function should be called with no arguments.  If the function
-returns nil, then no other program has provided such text, and the top
-of the Emacs kill ring should be used.  If the function returns a
-string, then the caller of the function \(usually `current-kill')
-should put this string in the kill ring as the latest kill.
-
-This function may also return a list of strings if the window
+Most window systems provide a facility for cutting and pasting
+text between different programs, such as the clipboard on X and
+MS-Windows, or the pasteboard on Nextstep/Mac OS.
+
+This variable holds a function that Emacs calls to obtain text
+that other programs have provided for pasting.  The function is
+called with no arguments.  If no other program has provided text
+to paste, the function should return nil (in which case the
+caller, usually `current-kill', should use the top of the Emacs
+kill ring).  If another program has provided text to paste, the
+function should return that text as a string (in which case the
+caller should put this string in the kill ring as the latest
+kill).
+
+The function may also return a list of strings if the window
 system supports multiple selections.  The first string will be
 system supports multiple selections.  The first string will be
-used as the pasted text, but the other will be placed in the
-kill ring for easy access via `yank-pop'.
-
-Note that the function should return a string only if a program other
-than Emacs has provided a string for pasting; if Emacs provided the
-most recent string, the function should return nil.  If it is
-difficult to tell whether Emacs or some other program provided the
-current string, it is probably good enough to return nil if the string
-is equal (according to `string=') to the last text Emacs provided.")
+used as the pasted text, but the other will be placed in the kill
+ring for easy access via `yank-pop'.
+
+Note that the function should return a string only if a program
+other than Emacs has provided a string for pasting; if Emacs
+provided the most recent string, the function should return nil.
+If it is difficult to tell whether Emacs or some other program
+provided the current string, it is probably good enough to return
+nil if the string is equal (according to `string=') to the last
+text Emacs provided.")
 \f
 
 
 \f
 
 
@@ -2996,7 +3125,8 @@ before the Emacs kill and one can still paste it using \\[yank] \\[yank-pop]."
   :version "23.2")
 
 (defcustom kill-do-not-save-duplicates nil
   :version "23.2")
 
 (defcustom kill-do-not-save-duplicates nil
-  "Do not add a new string to `kill-ring' when it is the same as the last one."
+  "Do not add a new string to `kill-ring' if it duplicates the last one.
+The comparison is done using `equal-including-properties'."
   :type 'boolean
   :group 'killing
   :version "23.2")
   :type 'boolean
   :group 'killing
   :version "23.2")
@@ -3024,7 +3154,10 @@ argument should still be a \"useful\" string for such uses."
        (signal 'args-out-of-range
                (list string "yank-handler specified for empty string"))))
   (unless (and kill-do-not-save-duplicates
        (signal 'args-out-of-range
                (list string "yank-handler specified for empty string"))))
   (unless (and kill-do-not-save-duplicates
-              (equal string (car kill-ring)))
+              ;; Due to text properties such as 'yank-handler that
+              ;; can alter the contents to yank, comparison using
+              ;; `equal' is unsafe.
+              (equal-including-properties string (car kill-ring)))
     (if (fboundp 'menu-bar-update-yank-menu)
        (menu-bar-update-yank-menu string (and replace (car kill-ring)))))
   (when save-interprogram-paste-before-kill
     (if (fboundp 'menu-bar-update-yank-menu)
        (menu-bar-update-yank-menu string (and replace (car kill-ring)))))
   (when save-interprogram-paste-before-kill
@@ -3035,10 +3168,10 @@ argument should still be a \"useful\" string for such uses."
                       (nreverse interprogram-paste)
                     (list interprogram-paste)))
          (unless (and kill-do-not-save-duplicates
                       (nreverse interprogram-paste)
                     (list interprogram-paste)))
          (unless (and kill-do-not-save-duplicates
-                      (equal s (car kill-ring)))
+                      (equal-including-properties s (car kill-ring)))
            (push s kill-ring))))))
   (unless (and kill-do-not-save-duplicates
            (push s kill-ring))))))
   (unless (and kill-do-not-save-duplicates
-              (equal string (car kill-ring)))
+              (equal-including-properties string (car kill-ring)))
     (if (and replace kill-ring)
        (setcar kill-ring string)
       (push string kill-ring)
     (if (and replace kill-ring)
        (setcar kill-ring string)
       (push string kill-ring)
@@ -3062,7 +3195,10 @@ If `interprogram-cut-function' is set, pass the resulting kill to it."
 (set-advertised-calling-convention 'kill-append '(string before-p) "23.3")
 
 (defcustom yank-pop-change-selection nil
 (set-advertised-calling-convention 'kill-append '(string before-p) "23.3")
 
 (defcustom yank-pop-change-selection nil
-  "If non-nil, rotating the kill ring changes the window system selection."
+  "Whether rotating the kill ring changes the window system selection.
+If non-nil, whenever the kill ring is rotated (usually via the
+`yank-pop' command), Emacs also calls `interprogram-cut-function'
+to copy the new kill to the window system selection."
   :type 'boolean
   :group 'killing
   :version "23.1")
   :type 'boolean
   :group 'killing
   :version "23.1")
@@ -3117,10 +3253,6 @@ move the yanking point; just return the Nth kill forward."
   :type 'boolean
   :group 'killing)
 
   :type 'boolean
   :group 'killing)
 
-(put 'text-read-only 'error-conditions
-     '(text-read-only buffer-read-only error))
-(put 'text-read-only 'error-message (purecopy "Text is read-only"))
-
 (defun kill-region (beg end &optional yank-handler)
   "Kill (\"cut\") text between point and mark.
 This deletes the text from the buffer and saves it in the kill ring.
 (defun kill-region (beg end &optional yank-handler)
   "Kill (\"cut\") text between point and mark.
 This deletes the text from the buffer and saves it in the kill ring.
@@ -3397,8 +3529,10 @@ and KILLP is t if a prefix arg was specified."
                      ((eq backward-delete-char-untabify-method 'all)
                       " \t\n\r")))
          (n (if skip
                      ((eq backward-delete-char-untabify-method 'all)
                       " \t\n\r")))
          (n (if skip
-                (let ((wh (- (point) (save-excursion (skip-chars-backward skip)
-                                                     (point)))))
+                (let* ((oldpt (point))
+                       (wh (- oldpt (save-excursion
+                                      (skip-chars-backward skip)
+                                      (constrain-to-field nil oldpt)))))
                   (+ arg (if (zerop wh) 0 (1- wh))))
               arg)))
     ;; Avoid warning about delete-backward-char
                   (+ arg (if (zerop wh) 0 (1- wh))))
               arg)))
     ;; Avoid warning about delete-backward-char
@@ -3408,20 +3542,20 @@ and KILLP is t if a prefix arg was specified."
   "Kill up to and including ARGth occurrence of CHAR.
 Case is ignored if `case-fold-search' is non-nil in the current buffer.
 Goes backward if ARG is negative; error if CHAR not found."
   "Kill up to and including ARGth occurrence of CHAR.
 Case is ignored if `case-fold-search' is non-nil in the current buffer.
 Goes backward if ARG is negative; error if CHAR not found."
-  (interactive "p\ncZap to char: ")
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                    (read-char "Zap to char: " t)))
   ;; Avoid "obsolete" warnings for translation-table-for-input.
   (with-no-warnings
     (if (char-table-p translation-table-for-input)
        (setq char (or (aref translation-table-for-input char) char))))
   (kill-region (point) (progn
                         (search-forward (char-to-string char) nil nil arg)
   ;; Avoid "obsolete" warnings for translation-table-for-input.
   (with-no-warnings
     (if (char-table-p translation-table-for-input)
        (setq char (or (aref translation-table-for-input char) char))))
   (kill-region (point) (progn
                         (search-forward (char-to-string char) nil nil arg)
-;                       (goto-char (if (> arg 0) (1- (point)) (1+ (point))))
                         (point))))
 
 ;; kill-line and its subroutines.
 
 (defcustom kill-whole-line nil
                         (point))))
 
 ;; kill-line and its subroutines.
 
 (defcustom kill-whole-line nil
-  "If non-nil, `kill-line' with no arg at beg of line kills the whole line."
+  "If non-nil, `kill-line' with no arg at start of line kills the whole line."
   :type 'boolean
   :group 'killing)
 
   :type 'boolean
   :group 'killing)
 
@@ -3609,7 +3743,8 @@ If ARG is zero, move to the beginning of the current line."
                        (assq prop buffer-invisibility-spec))))))
     (skip-chars-forward "^\n")
     (if (get-text-property (point) 'invisible)
                        (assq prop buffer-invisibility-spec))))))
     (skip-chars-forward "^\n")
     (if (get-text-property (point) 'invisible)
-       (goto-char (next-single-property-change (point) 'invisible))
+       (goto-char (or (next-single-property-change (point) 'invisible)
+                      (point-max)))
       (goto-char (next-overlay-change (point))))
     (end-of-line)))
 \f
       (goto-char (next-overlay-change (point))))
     (end-of-line)))
 \f
@@ -3713,10 +3848,18 @@ a mistake; see the documentation of `set-mark'."
     (signal 'mark-inactive nil)))
 
 (defsubst deactivate-mark (&optional force)
     (signal 'mark-inactive nil)))
 
 (defsubst deactivate-mark (&optional force)
-  "Deactivate the mark by setting `mark-active' to nil.
-Unless FORCE is non-nil, this function does nothing if Transient
-Mark mode is disabled.
-This function also runs `deactivate-mark-hook'."
+  "Deactivate the mark.
+If Transient Mark mode is disabled, this function normally does
+nothing; but if FORCE is non-nil, it deactivates the mark anyway.
+
+Deactivating the mark sets `mark-active' to nil, updates the
+primary selection according to `select-active-regions', and runs
+`deactivate-mark-hook'.
+
+If Transient Mark mode was temporarily enabled, reset the value
+of the variable `transient-mark-mode'; if this causes Transient
+Mark mode to be disabled, don't change `mark-active' to nil or
+run `deactivate-mark-hook'."
   (when (or transient-mark-mode force)
     (when (and (if (eq select-active-regions 'only)
                   (eq (car-safe transient-mark-mode) 'only)
   (when (or transient-mark-mode force)
     (when (and (if (eq select-active-regions 'only)
                   (eq (car-safe transient-mark-mode) 'only)
@@ -3729,7 +3872,11 @@ This function also runs `deactivate-mark-hook'."
       (cond (saved-region-selection
             (x-set-selection 'PRIMARY saved-region-selection)
             (setq saved-region-selection nil))
       (cond (saved-region-selection
             (x-set-selection 'PRIMARY saved-region-selection)
             (setq saved-region-selection nil))
-           ((/= (region-beginning) (region-end))
+           ;; If another program has acquired the selection, region
+           ;; deactivation should not clobber it (Bug#11772).
+           ((and (/= (region-beginning) (region-end))
+                 (or (x-selection-owner-p 'PRIMARY)
+                     (null (x-selection-exists-p 'PRIMARY))))
             (x-set-selection 'PRIMARY
                              (buffer-substring-no-properties
                               (region-beginning)
             (x-set-selection 'PRIMARY
                              (buffer-substring-no-properties
                               (region-beginning)
@@ -4058,13 +4205,15 @@ its earlier value."
 
 (define-minor-mode transient-mark-mode
   "Toggle Transient Mark mode.
 
 (define-minor-mode transient-mark-mode
   "Toggle Transient Mark mode.
-With ARG, turn Transient Mark mode on if ARG is positive, off otherwise.
+With a prefix argument ARG, enable Transient Mark mode if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+Transient Mark mode if ARG is omitted or nil.
 
 
-In Transient Mark mode, when the mark is active, the region is highlighted.
-Changing the buffer \"deactivates\" the mark.
-So do certain other operations that set the mark
-but whose main purpose is something else--for example,
-incremental search, \\[beginning-of-buffer], and \\[end-of-buffer].
+Transient Mark mode is a global minor mode.  When enabled, the
+region is highlighted whenever the mark is active.  The mark is
+\"deactivated\" by changing the buffer, and after certain other
+operations that set the mark but whose main purpose is something
+else--for example, incremental search, \\[beginning-of-buffer], and \\[end-of-buffer].
 
 You can also deactivate the mark by typing \\[keyboard-quit] or
 \\[keyboard-escape-quit].
 
 You can also deactivate the mark by typing \\[keyboard-quit] or
 \\[keyboard-escape-quit].
@@ -4245,8 +4394,8 @@ into account variable-width characters and line continuation.
 If nil, `line-move' moves point by logical lines.
 A non-nil setting of `goal-column' overrides the value of this variable
 and forces movement by logical lines.
 If nil, `line-move' moves point by logical lines.
 A non-nil setting of `goal-column' overrides the value of this variable
 and forces movement by logical lines.
-Disabling `auto-hscroll-mode' also overrides forces movement by logical
-lines when the window is horizontally scrolled."
+A window that is  horizontally scrolled also forces movement by logical
+lines."
   :type 'boolean
   :group 'editing-basics
   :version "23.1")
   :type 'boolean
   :group 'editing-basics
   :version "23.1")
@@ -4292,7 +4441,7 @@ lines when the window is horizontally scrolled."
          (when (> rbot 0)
            (set-window-vscroll nil (+ vs (min rbot (frame-char-height))) t)))
         ;; If cursor just entered the bottom scroll margin, move forward,
          (when (> rbot 0)
            (set-window-vscroll nil (+ vs (min rbot (frame-char-height))) t)))
         ;; If cursor just entered the bottom scroll margin, move forward,
-        ;; but also vscroll one line so redisplay wont recenter.
+        ;; but also vscroll one line so redisplay won't recenter.
         ((and (> vpos 0)
               (= py (min (- (window-text-height) scroll-margin 1)
                          (1- vpos))))
         ((and (> vpos 0)
               (= py (min (- (window-text-height) scroll-margin 1)
                          (1- vpos))))
@@ -4315,25 +4464,25 @@ lines when the window is horizontally scrolled."
 ;; a cleaner solution to the problem of making C-n do something
 ;; useful given a tall image.
 (defun line-move (arg &optional noerror to-end try-vscroll)
 ;; a cleaner solution to the problem of making C-n do something
 ;; useful given a tall image.
 (defun line-move (arg &optional noerror to-end try-vscroll)
-  (unless (and auto-window-vscroll try-vscroll
-              ;; Only vscroll for single line moves
-              (= (abs arg) 1)
-              ;; But don't vscroll in a keyboard macro.
-              (not defining-kbd-macro)
-              (not executing-kbd-macro)
-              (line-move-partial arg noerror to-end))
-    (set-window-vscroll nil 0 t)
-    (if (and line-move-visual
-            ;; Display-based column are incompatible with goal-column.
-            (not goal-column)
-            ;; When auto-hscroll-mode is turned off and the text in
-            ;; the window is scrolled to the left, display-based
-            ;; motion doesn't make sense (because each logical line
-            ;; occupies exactly one screen line).
-            (not (and (null auto-hscroll-mode)
-                      (> (window-hscroll) 0))))
-       (line-move-visual arg noerror)
-      (line-move-1 arg noerror to-end))))
+  (if noninteractive
+      (forward-line arg)
+    (unless (and auto-window-vscroll try-vscroll
+                ;; Only vscroll for single line moves
+                (= (abs arg) 1)
+                ;; But don't vscroll in a keyboard macro.
+                (not defining-kbd-macro)
+                (not executing-kbd-macro)
+                (line-move-partial arg noerror to-end))
+      (set-window-vscroll nil 0 t)
+      (if (and line-move-visual
+              ;; Display-based column are incompatible with goal-column.
+              (not goal-column)
+              ;; When the text in the window is scrolled to the left,
+              ;; display-based motion doesn't make sense (because each
+              ;; logical line occupies exactly one screen line).
+              (not (> (window-hscroll) 0)))
+         (line-move-visual arg noerror)
+       (line-move-1 arg noerror to-end)))))
 
 ;; Display-based alternative to line-move-1.
 ;; Arg says how many lines to move.  The value is t if we can move the
 
 ;; Display-based alternative to line-move-1.
 ;; Arg says how many lines to move.  The value is t if we can move the
@@ -4691,7 +4840,7 @@ To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
        (let ((line-move-visual nil))
          (line-move (1- arg) t)))
 
        (let ((line-move-visual nil))
          (line-move (1- arg) t)))
 
-    ;; Move to beginning-of-line, ignoring fields and invisibles.
+    ;; Move to beginning-of-line, ignoring fields and invisible text.
     (skip-chars-backward "^\n")
     (while (and (not (bobp)) (invisible-p (1- (point))))
       (goto-char (previous-char-property-change (point)))
     (skip-chars-backward "^\n")
     (while (and (not (bobp)) (invisible-p (1- (point))))
       (goto-char (previous-char-property-change (point)))
@@ -4878,8 +5027,15 @@ other purposes."
 (defvar visual-line--saved-state nil)
 
 (define-minor-mode visual-line-mode
 (defvar visual-line--saved-state nil)
 
 (define-minor-mode visual-line-mode
-  "Redefine simple editing commands to act on visual lines, not logical lines.
-This also turns on `word-wrap' in the buffer."
+  "Toggle visual line based editing (Visual Line mode).
+With a prefix argument ARG, enable Visual Line mode if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+the mode if ARG is omitted or nil.
+
+When Visual Line mode is enabled, `word-wrap' is turned on in
+this buffer, and simple editing commands are redefined to act on
+visual lines, not logical lines.  See Info node `Visual Line
+Mode' for details."
   :keymap visual-line-mode-map
   :group 'visual-line
   :lighter " Wrap"
   :keymap visual-line-mode-map
   :group 'visual-line
   :lighter " Wrap"
@@ -5226,7 +5382,7 @@ Returns t if it really did any work."
       t)))
 
 (defvar comment-line-break-function 'comment-indent-new-line
       t)))
 
 (defvar comment-line-break-function 'comment-indent-new-line
-  "*Mode-specific function which line breaks and continues a comment.
+  "Mode-specific function which line breaks and continues a comment.
 This function is called during auto-filling when a comment syntax
 is defined.
 The function should take a single optional argument, which is a flag
 This function is called during auto-filling when a comment syntax
 is defined.
 The function should take a single optional argument, which is a flag
@@ -5273,17 +5429,23 @@ Some major modes set this.")
 (put 'auto-fill-function 'safe-local-variable 'null)
 
 (define-minor-mode auto-fill-mode
 (put 'auto-fill-function 'safe-local-variable 'null)
 
 (define-minor-mode auto-fill-mode
-  "Toggle Auto Fill mode.
-With ARG, turn Auto Fill mode on if and only if ARG is positive.
-In Auto Fill mode, inserting a space at a column beyond `current-fill-column'
-automatically breaks the line at a previous space.
+  "Toggle automatic line breaking (Auto Fill mode).
+With a prefix argument ARG, enable Auto Fill mode if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+the mode if ARG is omitted or nil.
+
+When Auto Fill mode is enabled, inserting a space at a column
+beyond `current-fill-column' automatically breaks the line at a
+previous space.
 
 When `auto-fill-mode' is on, the `auto-fill-function' variable is
 non-`nil'.
 
 The value of `normal-auto-fill-function' specifies the function to use
 for `auto-fill-function' when turning Auto Fill mode on."
 
 When `auto-fill-mode' is on, the `auto-fill-function' variable is
 non-`nil'.
 
 The value of `normal-auto-fill-function' specifies the function to use
 for `auto-fill-function' when turning Auto Fill mode on."
-  :variable (eq auto-fill-function normal-auto-fill-function))
+  :variable (auto-fill-function
+             . (lambda (v) (setq auto-fill-function
+                            (if v normal-auto-fill-function)))))
 
 ;; This holds a document string used to document auto-fill-mode.
 (defun auto-fill-function ()
 
 ;; This holds a document string used to document auto-fill-mode.
 (defun auto-fill-function ()
@@ -5384,36 +5546,46 @@ if long lines are truncated."
   "The string displayed in the mode line when in binary overwrite mode.")
 
 (define-minor-mode overwrite-mode
   "The string displayed in the mode line when in binary overwrite mode.")
 
 (define-minor-mode overwrite-mode
-  "Toggle overwrite mode.
-With prefix argument ARG, turn overwrite mode on if ARG is positive,
-otherwise turn it off.  In overwrite mode, printing characters typed
-in replace existing text on a one-for-one basis, rather than pushing
-it to the right.  At the end of a line, such characters extend the line.
-Before a tab, such characters insert until the tab is filled in.
-\\[quoted-insert] still inserts characters in overwrite mode; this
-is supposed to make it easier to insert characters when necessary."
-  :variable (eq overwrite-mode 'overwrite-mode-textual))
+  "Toggle Overwrite mode.
+With a prefix argument ARG, enable Overwrite mode if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+the mode if ARG is omitted or nil.
+
+When Overwrite mode is enabled, printing characters typed in
+replace existing text on a one-for-one basis, rather than pushing
+it to the right.  At the end of a line, such characters extend
+the line.  Before a tab, such characters insert until the tab is
+filled in.  \\[quoted-insert] still inserts characters in
+overwrite mode; this is supposed to make it easier to insert
+characters when necessary."
+  :variable (overwrite-mode
+             . (lambda (v) (setq overwrite-mode (if v 'overwrite-mode-textual)))))
 
 (define-minor-mode binary-overwrite-mode
 
 (define-minor-mode binary-overwrite-mode
-  "Toggle binary overwrite mode.
-With prefix argument ARG, turn binary overwrite mode on if ARG is
-positive, otherwise turn it off.  In binary overwrite mode, printing
-characters typed in replace existing text.  Newlines are not treated
-specially, so typing at the end of a line joins the line to the next,
-with the typed character between them.  Typing before a tab character
-simply replaces the tab with the character typed.  \\[quoted-insert]
-replaces the text at the cursor, just as ordinary typing characters do.
-
-Note that binary overwrite mode is not its own minor mode; it is a
-specialization of overwrite mode, entered by setting the
+  "Toggle Binary Overwrite mode.
+With a prefix argument ARG, enable Binary Overwrite mode if ARG
+is positive, and disable it otherwise.  If called from Lisp,
+enable the mode if ARG is omitted or nil.
+
+When Binary Overwrite mode is enabled, printing characters typed
+in replace existing text.  Newlines are not treated specially, so
+typing at the end of a line joins the line to the next, with the
+typed character between them.  Typing before a tab character
+simply replaces the tab with the character typed.
+\\[quoted-insert] replaces the text at the cursor, just as
+ordinary typing characters do.
+
+Note that Binary Overwrite mode is not its own minor mode; it is
+a specialization of overwrite mode, entered by setting the
 `overwrite-mode' variable to `overwrite-mode-binary'."
 `overwrite-mode' variable to `overwrite-mode-binary'."
-  :variable (eq overwrite-mode 'overwrite-mode-binary))
+  :variable (overwrite-mode
+             . (lambda (v) (setq overwrite-mode (if v 'overwrite-mode-binary)))))
 
 (define-minor-mode line-number-mode
 
 (define-minor-mode line-number-mode
-  "Toggle Line Number mode.
-With ARG, turn Line Number mode on if ARG is positive, otherwise
-turn it off.  When Line Number mode is enabled, the line number
-appears in the mode line.
+  "Toggle line number display in the mode line (Line Number mode).
+With a prefix argument ARG, enable Line Number mode if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+the mode if ARG is omitted or nil.
 
 Line numbers do not appear for very large buffers and buffers
 with very long lines; see variables `line-number-display-limit'
 
 Line numbers do not appear for very large buffers and buffers
 with very long lines; see variables `line-number-display-limit'
@@ -5421,22 +5593,27 @@ and `line-number-display-limit-width'."
   :init-value t :global t :group 'mode-line)
 
 (define-minor-mode column-number-mode
   :init-value t :global t :group 'mode-line)
 
 (define-minor-mode column-number-mode
-  "Toggle Column Number mode.
-With ARG, turn Column Number mode on if ARG is positive,
-otherwise turn it off.  When Column Number mode is enabled, the
-column number appears in the mode line."
+  "Toggle column number display in the mode line (Column Number mode).
+With a prefix argument ARG, enable Column Number mode if ARG is
+positive, and disable it otherwise.
+
+If called from Lisp, enable the mode if ARG is omitted or nil."
   :global t :group 'mode-line)
 
 (define-minor-mode size-indication-mode
   :global t :group 'mode-line)
 
 (define-minor-mode size-indication-mode
-  "Toggle Size Indication mode.
-With ARG, turn Size Indication mode on if ARG is positive,
-otherwise turn it off.  When Size Indication mode is enabled, the
-size of the accessible part of the buffer appears in the mode line."
+  "Toggle buffer size display in the mode line (Size Indication mode).
+With a prefix argument ARG, enable Size Indication mode if ARG is
+positive, and disable it otherwise.
+
+If called from Lisp, enable the mode if ARG is omitted or nil."
   :global t :group 'mode-line)
 
 (define-minor-mode auto-save-mode
   :global t :group 'mode-line)
 
 (define-minor-mode auto-save-mode
-  "Toggle auto-saving of contents of current buffer.
-With prefix argument ARG, turn auto-saving on if positive, else off."
+  "Toggle auto-saving in the current buffer (Auto Save mode).
+With a prefix argument ARG, enable Auto Save mode if ARG is
+positive, and disable it otherwise.
+
+If called from Lisp, enable the mode if ARG is omitted or nil."
   :variable ((and buffer-auto-save-file-name
                   ;; If auto-save is off because buffer has shrunk,
                   ;; then toggling should turn it on.
   :variable ((and buffer-auto-save-file-name
                   ;; If auto-save is off because buffer has shrunk,
                   ;; then toggling should turn it on.
@@ -5650,7 +5827,7 @@ At top-level, as an editor command, this simply beeps."
 (defvar buffer-quit-function nil
   "Function to call to \"quit\" the current buffer, or nil if none.
 \\[keyboard-escape-quit] calls this function when its more local actions
 (defvar buffer-quit-function nil
   "Function to call to \"quit\" the current buffer, or nil if none.
 \\[keyboard-escape-quit] calls this function when its more local actions
-\(such as cancelling a prefix argument, minibuffer or region) do not apply.")
+\(such as canceling a prefix argument, minibuffer or region) do not apply.")
 
 (defun keyboard-escape-quit ()
   "Exit the current \"mode\" (in a generalized sense of the word).
 
 (defun keyboard-escape-quit ()
   "Exit the current \"mode\" (in a generalized sense of the word).
@@ -5717,8 +5894,8 @@ Valid values include:
   `mh-e-user-agent'     -- use the Emacs interface to the MH mail system.
                            See Info node `(mh-e)'.
   `gnus-user-agent'     -- like `message-user-agent', but with Gnus
   `mh-e-user-agent'     -- use the Emacs interface to the MH mail system.
                            See Info node `(mh-e)'.
   `gnus-user-agent'     -- like `message-user-agent', but with Gnus
-                           paraphernalia, particularly the Gcc: header for
-                           archiving.
+                           paraphernalia if Gnus is running, particularly
+                           the Gcc: header for archiving.
 
 Additional valid symbols may be available; check with the author of
 your package for details.  The function should return non-nil if it
 
 Additional valid symbols may be available; check with the author of
 your package for details.  The function should return non-nil if it
@@ -5871,7 +6048,7 @@ in the definition is used to check that VALUE is valid.
 With a prefix argument, set VARIABLE to VALUE buffer-locally."
   (interactive
    (let* ((default-var (variable-at-point))
 With a prefix argument, set VARIABLE to VALUE buffer-locally."
   (interactive
    (let* ((default-var (variable-at-point))
-          (var (if (user-variable-p default-var)
+          (var (if (custom-variable-p default-var)
                   (read-variable (format "Set variable (default %s): " default-var)
                                  default-var)
                 (read-variable "Set variable: ")))
                   (read-variable (format "Set variable (default %s): " default-var)
                                  default-var)
                 (read-variable "Set variable: ")))
@@ -5961,7 +6138,7 @@ of the text to replace.  If END is nil, point is used instead.")
 
 (defvar completion-list-insert-choice-function #'completion--replace
   "Function to use to insert the text chosen in *Completions*.
 
 (defvar completion-list-insert-choice-function #'completion--replace
   "Function to use to insert the text chosen in *Completions*.
-Called with 3 arguments (BEG END TEXT), it should replace the text
+Called with three arguments (BEG END TEXT), it should replace the text
 between BEG and END with TEXT.  Expected to be set buffer-locally
 in the *Completions* buffer.")
 
 between BEG and END with TEXT.  Expected to be set buffer-locally
 in the *Completions* buffer.")
 
@@ -6047,21 +6224,11 @@ With prefix argument N, move N items (negative N means move backward)."
                (setq beg (previous-single-property-change beg 'mouse-face))
                (setq end (or (next-single-property-change end 'mouse-face)
                              (point-max)))
                (setq beg (previous-single-property-change beg 'mouse-face))
                (setq end (or (next-single-property-change end 'mouse-face)
                              (point-max)))
-               (buffer-substring-no-properties beg end))))
-          (owindow (selected-window)))
+               (buffer-substring-no-properties beg end)))))
 
       (unless (buffer-live-p buffer)
         (error "Destination buffer is dead"))
 
       (unless (buffer-live-p buffer)
         (error "Destination buffer is dead"))
-      (select-window (posn-window (event-start event)))
-      (if (and (one-window-p t 'selected-frame)
-              (window-dedicated-p (selected-window)))
-         ;; This is a special buffer's frame
-         (iconify-frame (selected-frame))
-       (or (window-dedicated-p (selected-window))
-           (bury-buffer)))
-      (select-window
-       (or (get-buffer-window buffer 0)
-           owindow))
+      (quit-window nil (posn-window (event-start event)))
 
       (with-current-buffer buffer
         (choose-completion-string
 
       (with-current-buffer buffer
         (choose-completion-string
@@ -6155,7 +6322,7 @@ BASE-POSITION, says where to insert the completion."
               choice buffer base-position nil)
         ;; This remove-text-properties should be unnecessary since `choice'
         ;; comes from buffer-substring-no-properties.
               choice buffer base-position nil)
         ;; This remove-text-properties should be unnecessary since `choice'
         ;; comes from buffer-substring-no-properties.
-        ;;(remove-text-properties 0 (lenth choice) '(mouse-face nil) choice)
+        ;;(remove-text-properties 0 (length choice) '(mouse-face nil) choice)
        ;; Insert the completion into the buffer where it was requested.
         (funcall (or insert-function completion-list-insert-choice-function)
                  (or (car base-position) (point))
        ;; Insert the completion into the buffer where it was requested.
         (funcall (or insert-function completion-list-insert-choice-function)
                  (or (car base-position) (point))
@@ -6198,7 +6365,7 @@ Use \\<completion-list-mode-map>\\[mouse-choose-completion] to select one\
   "Finish setup of the completions buffer.
 Called from `temp-buffer-show-hook'."
   (when (eq major-mode 'completion-list-mode)
   "Finish setup of the completions buffer.
 Called from `temp-buffer-show-hook'."
   (when (eq major-mode 'completion-list-mode)
-    (toggle-read-only 1)))
+    (setq buffer-read-only t)))
 
 (add-hook 'temp-buffer-show-hook 'completion-list-mode-finish)
 
 
 (add-hook 'temp-buffer-show-hook 'completion-list-mode-finish)
 
@@ -6606,8 +6773,9 @@ call `normal-erase-is-backspace-mode' (which see) instead."
 
 (define-minor-mode normal-erase-is-backspace-mode
   "Toggle the Erase and Delete mode of the Backspace and Delete keys.
 
 (define-minor-mode normal-erase-is-backspace-mode
   "Toggle the Erase and Delete mode of the Backspace and Delete keys.
-
-With numeric ARG, turn the mode on if and only if ARG is positive.
+With a prefix argument ARG, enable this feature if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+the mode if ARG is omitted or nil.
 
 On window systems, when this mode is on, Delete is mapped to C-d
 and Backspace is mapped to DEL; when this mode is off, both
 
 On window systems, when this mode is on, Delete is mapped to C-d
 and Backspace is mapped to DEL; when this mode is off, both
@@ -6634,8 +6802,10 @@ probably not turn on this mode on a text-only terminal if you don't
 have both Backspace, Delete and F1 keys.
 
 See also `normal-erase-is-backspace'."
 have both Backspace, Delete and F1 keys.
 
 See also `normal-erase-is-backspace'."
-  :variable (eq (terminal-parameter
-                 nil 'normal-erase-is-backspace) 1)
+  :variable ((eq (terminal-parameter nil 'normal-erase-is-backspace) 1)
+             . (lambda (v)
+                 (setf (terminal-parameter nil 'normal-erase-is-backspace)
+                       (if v 1 0))))
   (let ((enabled (eq 1 (terminal-parameter
                         nil 'normal-erase-is-backspace))))
 
   (let ((enabled (eq 1 (terminal-parameter
                         nil 'normal-erase-is-backspace))))
 
@@ -6681,13 +6851,13 @@ See also `normal-erase-is-backspace'."
   "Saved value of `buffer-invisibility-spec' when Visible mode is on.")
 
 (define-minor-mode visible-mode
   "Saved value of `buffer-invisibility-spec' when Visible mode is on.")
 
 (define-minor-mode visible-mode
-  "Toggle Visible mode.
-With argument ARG turn Visible mode on if ARG is positive, otherwise
-turn it off.
+  "Toggle making all invisible text temporarily visible (Visible mode).
+With a prefix argument ARG, enable Visible mode if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+the mode if ARG is omitted or nil.
 
 
-Enabling Visible mode makes all invisible text temporarily visible.
-Disabling Visible mode turns off that effect.  Visible mode works by
-saving the value of `buffer-invisibility-spec' and setting it to nil."
+This mode works by saving the value of `buffer-invisibility-spec'
+and setting it to nil."
   :lighter " Vis"
   :group 'editing-basics
   (when (local-variable-p 'vis-mode-saved-buffer-invisibility-spec)
   :lighter " Vis"
   :group 'editing-basics
   (when (local-variable-p 'vis-mode-saved-buffer-invisibility-spec)