Merge from gnus--rel--5.10
[bpt/emacs.git] / lisp / simple.el
index 93f6329..c064bbc 100644 (file)
@@ -1,7 +1,7 @@
 ;;; simple.el --- basic editing commands for Emacs
 
 ;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-;;   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+;;   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: internal
@@ -52,25 +52,68 @@ wait this many seconds after Emacs becomes idle before doing an update."
   "Highlight (un)matching of parens and expressions."
   :group 'matching)
 
+(defun get-next-valid-buffer (list &optional buffer visible-ok frame)
+  "Search LIST for a valid buffer to display in FRAME.
+Return nil when all buffers in LIST are undesirable for display,
+otherwise return the first suitable buffer in LIST.
+
+Buffers not visible in windows are preferred to visible buffers,
+unless VISIBLE-OK is non-nil.
+If the optional argument FRAME is nil, it defaults to the selected frame.
+If BUFFER is non-nil, ignore occurrences of that buffer in LIST."
+  ;; This logic is more or less copied from other-buffer.
+  (setq frame (or frame (selected-frame)))
+  (let ((pred (frame-parameter frame 'buffer-predicate))
+       found buf)
+    (while (and (not found) list)
+      (setq buf (car list))
+      (if (and (not (eq buffer buf))
+              (buffer-live-p buf)
+              (or (null pred) (funcall pred buf))
+              (not (eq (aref (buffer-name buf) 0) ?\s))
+              (or visible-ok (null (get-buffer-window buf 'visible))))
+         (setq found buf)
+       (setq list (cdr list))))
+    (car list)))
+
+(defun last-buffer (&optional buffer visible-ok frame)
+  "Return the last non-hidden displayable buffer in the buffer list.
+If BUFFER is non-nil, last-buffer will ignore that buffer.
+Buffers not visible in windows are preferred to visible buffers,
+unless optional argument VISIBLE-OK is non-nil.
+If the optional third argument FRAME is non-nil, use that frame's
+buffer list instead of the selected frame's buffer list.
+If no other buffer exists, the buffer `*scratch*' is returned."
+  (setq frame (or frame (selected-frame)))
+  (or (get-next-valid-buffer (frame-parameter frame 'buried-buffer-list)
+                            buffer visible-ok frame)
+      (get-next-valid-buffer (nreverse (buffer-list frame))
+                            buffer visible-ok frame)
+      (progn
+       (set-buffer-major-mode (get-buffer-create "*scratch*"))
+       (get-buffer "*scratch*"))))
+
 (defun next-buffer ()
   "Switch to the next buffer in cyclic order."
   (interactive)
-  (let ((buffer (current-buffer)))
-    (switch-to-buffer (other-buffer buffer))
-    (bury-buffer buffer)))
-
-(defun prev-buffer ()
+  (let ((buffer (current-buffer))
+       (bbl (frame-parameter nil 'buried-buffer-list)))
+    (switch-to-buffer (other-buffer buffer t))
+    (bury-buffer buffer)
+    (set-frame-parameter nil 'buried-buffer-list
+                        (cons buffer (delq buffer bbl)))))
+
+(defun previous-buffer ()
   "Switch to the previous buffer in cyclic order."
   (interactive)
-  (let ((list (nreverse (buffer-list)))
-       found)
-    (while (and (not found) list)
-      (let ((buffer (car list)))
-       (if (and (not (get-buffer-window buffer))
-                (not (string-match "\\` " (buffer-name buffer))))
-           (setq found buffer)))
-      (setq list (cdr list)))
-    (switch-to-buffer found)))
+  (let ((buffer (last-buffer (current-buffer) t))
+       (bbl (frame-parameter nil 'buried-buffer-list)))
+    (switch-to-buffer buffer)
+    ;; Clean up buried-buffer-list up to and including the chosen buffer.
+    (while (and bbl (not (eq (car bbl) buffer)))
+      (setq bbl (cdr bbl)))
+    (set-frame-parameter nil 'buried-buffer-list bbl)))
+
 \f
 ;;; next-error support framework
 
@@ -85,29 +128,29 @@ wait this many seconds after Emacs becomes idle before doing an update."
   :group 'next-error
   :version "22.1")
 
-(defcustom next-error-highlight 0.1
+(defcustom next-error-highlight 0.5
   "*Highlighting of locations in selected source buffers.
 If number, highlight the locus in `next-error' face for given time in seconds.
-If t, use persistent overlays fontified in `next-error' face.
+If t, highlight the locus indefinitely until some other locus replaces it.
 If nil, don't highlight the locus in the source buffer.
 If `fringe-arrow', indicate the locus by the fringe arrow."
-  :type '(choice (number :tag "Delay")
-                 (const :tag "Persistent overlay" t)
+  :type '(choice (number :tag "Highlight for specified time")
+                 (const :tag "Semipermanent highlighting" t)
                  (const :tag "No highlighting" nil)
-                 (const :tag "Fringe arrow" 'fringe-arrow))
+                 (const :tag "Fringe arrow" fringe-arrow))
   :group 'next-error
   :version "22.1")
 
-(defcustom next-error-highlight-no-select 0.1
-  "*Highlighting of locations in non-selected source buffers.
+(defcustom next-error-highlight-no-select 0.5
+  "*Highlighting of locations in `next-error-no-select'.
 If number, highlight the locus in `next-error' face for given time in seconds.
-If t, use persistent overlays fontified in `next-error' face.
+If t, highlight the locus indefinitely until some other locus replaces it.
 If nil, don't highlight the locus in the source buffer.
 If `fringe-arrow', indicate the locus by the fringe arrow."
-  :type '(choice (number :tag "Delay")
-                 (const :tag "Persistent overlay" t)
+  :type '(choice (number :tag "Highlight for specified time")
+                 (const :tag "Semipermanent highlighting" t)
                  (const :tag "No highlighting" nil)
-                 (const :tag "Fringe arrow" 'fringe-arrow))
+                 (const :tag "Fringe arrow" fringe-arrow))
   :group 'next-error
   :version "22.1")
 
@@ -153,7 +196,7 @@ The function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffer
 that normally would not qualify.  If it returns t, the buffer
 in question is treated as usable.
 
-The function EXTRA-TEST-EXCLUSIVE, if non-nil is called in each buffer
+The function EXTRA-TEST-EXCLUSIVE, if non-nil, is called in each buffer
 that would normally be considered usable.  If it returns nil,
 that buffer is rejected."
   (and (buffer-name buffer)            ;First make sure it's live.
@@ -172,6 +215,7 @@ that buffer is rejected."
                                         extra-test-inclusive
                                         extra-test-exclusive)
   "Return a `next-error' capable buffer.
+
 If AVOID-CURRENT is non-nil, treat the current buffer
 as an absolute last resort only.
 
@@ -179,7 +223,7 @@ The function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffer
 that normally would not qualify.  If it returns t, the buffer
 in question is treated as usable.
 
-The function EXTRA-TEST-EXCLUSIVE, if non-nil is called in each buffer
+The function EXTRA-TEST-EXCLUSIVE, if non-nil, is called in each buffer
 that would normally be considered usable.  If it returns nil,
 that buffer is rejected."
   (or
@@ -855,7 +899,9 @@ and the greater of them is not at the start of a line."
 
 (defun line-number-at-pos (&optional pos)
   "Return (narrowed) buffer line number at position POS.
-If POS is nil, use current buffer location."
+If POS is nil, use current buffer location.
+Counting starts at (point-min), so the value refers
+to the contents of the accessible portion of the buffer."
   (let ((opoint (or pos (point))) start)
     (save-excursion
       (goto-char (point-min))
@@ -951,12 +997,11 @@ in *Help* buffer.  See also the command `describe-char'."
                     (single-key-description char))
                   encoding-msg pos total percent col hscroll))))))
 \f
-(defvar read-expression-map
-  (let ((m (make-sparse-keymap)))
-    (define-key m "\M-\t" 'lisp-complete-symbol)
-    (set-keymap-parent m minibuffer-local-map)
-    m)
-  "Minibuffer keymap used for reading Lisp expressions.")
+;; Initialize read-expression-map.  It is defined at C level.
+(let ((m (make-sparse-keymap)))
+  (define-key m "\M-\t" 'lisp-complete-symbol)
+  (set-keymap-parent m minibuffer-local-map)
+  (setq read-expression-map m))
 
 (defvar read-expression-history nil)
 
@@ -999,14 +1044,17 @@ display the result of expression evaluation."
           (format " (#o%o, #x%x)" value value)))))
 
 ;; We define this, rather than making `eval' interactive,
-;; for the sake of completion of names like eval-region, eval-current-buffer.
+;; for the sake of completion of names like eval-region, eval-buffer.
 (defun eval-expression (eval-expression-arg
                        &optional eval-expression-insert-value)
   "Evaluate EVAL-EXPRESSION-ARG and print value in the echo area.
 Value is also consed on to front of the variable `values'.
 Optional argument EVAL-EXPRESSION-INSERT-VALUE, if non-nil, means
 insert the result into the current buffer instead of printing it in
-the echo area."
+the echo area.
+
+If `eval-expression-debug-on-error' is non-nil, which is the default,
+this command arranges for all errors to enter the debugger."
   (interactive
    (list (read-from-minibuffer "Eval: "
                               nil read-expression-map t
@@ -1106,10 +1154,10 @@ except when an alternate history list is specified.")
   "Control whether history list elements are expressions or strings.
 If the value of this variable equals current minibuffer depth,
 they are expressions; otherwise they are strings.
-\(That convention is designed to do the right thing fora
+\(That convention is designed to do the right thing for
 recursive uses of the minibuffer.)")
 (setq minibuffer-history-variable 'minibuffer-history)
-(setq minibuffer-history-position nil)
+(setq minibuffer-history-position nil)  ;; Defvar is in C code.
 (defvar minibuffer-history-search-history nil)
 
 (defvar minibuffer-text-before-history nil
@@ -1234,7 +1282,8 @@ makes the search case-sensitive."
 (defvar minibuffer-temporary-goal-position nil)
 
 (defun next-history-element (n)
-  "Insert the next element of the minibuffer history into the minibuffer."
+  "Puts next element of the minibuffer history in the minibuffer.
+With argument N, it uses the Nth following element."
   (interactive "p")
   (or (zerop n)
       (let ((narg (- minibuffer-history-position n))
@@ -1277,7 +1326,8 @@ makes the search case-sensitive."
        (goto-char (or minibuffer-temporary-goal-position (point-max))))))
 
 (defun previous-history-element (n)
-  "Inserts the previous element of the minibuffer history into the minibuffer."
+  "Puts previous element of the minibuffer history in the minibuffer.
+With argument N, it uses the Nth previous element."
   (interactive "p")
   (next-history-element (- n)))
 
@@ -1450,8 +1500,7 @@ 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 transient-mark-mode mark-active
-                          " for region"))))
+                    (and undo-in-region " for region"))))
   (let ((undo-in-progress t))
     (setq pending-undo-list (primitive-undo n pending-undo-list))
     (if (null pending-undo-list)
@@ -1598,12 +1647,12 @@ is not *inside* the region START...END."
        ((null (car undo-elt))
         ;; (nil PROPERTY VALUE BEG . END)
         (let ((tail (nthcdr 3 undo-elt)))
-          (not (or (< (car tail) end)
-                   (> (cdr tail) start)))))
+          (and (< (car tail) end)
+               (> (cdr tail) start))))
        ((integerp (car undo-elt))
         ;; (BEGIN . END)
-        (not (or (< (car undo-elt) end)
-                 (> (cdr undo-elt) start))))))
+        (and (< (car undo-elt) end)
+             (> (cdr undo-elt) start)))))
 
 ;; Return the first affected buffer position and the delta for an undo element
 ;; delta is defined as the change in subsequent buffer positions if we *did*
@@ -1620,12 +1669,12 @@ is not *inside* the region START...END."
             '(0 . 0)))
     '(0 . 0)))
 
-(defcustom undo-ask-before-discard t
+(defcustom undo-ask-before-discard nil
   "If non-nil ask about discarding undo info for the current command.
 Normally, Emacs discards the undo info for the current command if
 it exceeds `undo-outer-limit'.  But if you set this option
 non-nil, it asks in the echo area whether to discard the info.
-If you answer no, there a slight risk that Emacs might crash, so
+If you answer no, there is a slight risk that Emacs might crash, so
 only do it if you really want to undo the command.
 
 This option is mainly intended for debugging.  You have to be
@@ -1662,7 +1711,7 @@ This variable only matters if `undo-ask-before-discard' is non-nil.")
        ;; but we don't want to ask the question again.
        (setq undo-extra-outer-limit (+ size 50000))
        (if (let (use-dialog-box track-mouse executing-kbd-macro )
-             (yes-or-no-p (format "Buffer %s undo info is %d bytes long; discard it? "
+             (yes-or-no-p (format "Buffer `%s' undo info is %d bytes long; discard it? "
                                   (buffer-name) size)))
            (progn (setq buffer-undo-list nil)
                   (setq undo-extra-outer-limit nil)
@@ -1670,7 +1719,7 @@ This variable only matters if `undo-ask-before-discard' is non-nil.")
          nil))
     (display-warning '(undo discard-info)
                     (concat
-                     (format "Buffer %s undo info was %d bytes long.\n"
+                     (format "Buffer `%s' undo info was %d bytes long.\n"
                              (buffer-name) size)
                      "The undo info was discarded because it exceeded \
 `undo-outer-limit'.
@@ -1857,11 +1906,14 @@ the contents are inserted into the buffer anyway.
 
 Optional arguments NOT-THIS-WINDOW and FRAME are as for `display-buffer',
 and only used if a buffer is displayed."
-  (cond ((and (stringp message) (not (string-match "\n" message)))
+  (cond ((and (stringp message)
+             (not (string-match "\n" message))
+             (<= (length message) (frame-width)))
         ;; Trivial case where we can use the echo area
         (message "%s" message))
        ((and (stringp message)
-             (= (string-match "\n" message) (1- (length message))))
+             (= (string-match "\n" message) (1- (length message)))
+             (<= (1- (length message)) (frame-width)))
         ;; Trivial case where we can just remove single trailing newline
         (message "%s" (substring message 0 (1- (length message)))))
        (t
@@ -1878,7 +1930,7 @@ and only used if a buffer is displayed."
           (let ((lines
                  (if (= (buffer-size) 0)
                      0
-                   (count-lines (point-min) (point-max)))))
+                   (count-screen-lines nil nil nil (minibuffer-window)))))
             (cond ((= lines 0))
                   ((and (or (<= lines 1)
                             (<= lines
@@ -2282,7 +2334,7 @@ return value of `filter-buffer-substring'.
 
 If this variable is nil, no filtering is performed.")
 
-(defun filter-buffer-substring (beg end &optional delete)
+(defun filter-buffer-substring (beg end &optional delete noprops)
   "Return the buffer substring between BEG and END, after filtering.
 The buffer substring is passed through each of the filter
 functions in `buffer-substring-filters', and the value from the
@@ -2292,21 +2344,36 @@ is nil, the buffer substring is returned unaltered.
 If DELETE is non-nil, the text between BEG and END is deleted
 from the buffer.
 
+If NOPROPS is non-nil, final string returned does not include
+text properties, while the string passed to the filters still
+includes text properties from the buffer text.
+
 Point is temporarily set to BEG before calling
 `buffer-substring-filters', in case the functions need to know
 where the text came from.
 
-This function should be used instead of `buffer-substring' or
-`delete-and-extract-region' when you want to allow filtering to
-take place.  For example, major or minor modes can use
-`buffer-substring-filters' to extract characters that are special
-to a buffer, and should not be copied into other buffers."
-  (save-excursion
-    (goto-char beg)
-    (let ((string (if delete (delete-and-extract-region beg end)
-                    (buffer-substring beg end))))
-      (dolist (filter buffer-substring-filters string)
-        (setq string (funcall filter string))))))
+This function should be used instead of `buffer-substring',
+`buffer-substring-no-properties', or `delete-and-extract-region'
+when you want to allow filtering to take place.  For example,
+major or minor modes can use `buffer-substring-filters' to
+extract characters that are special to a buffer, and should not
+be copied into other buffers."
+  (cond
+   ((or delete buffer-substring-filters)
+    (save-excursion
+      (goto-char beg)
+      (let ((string (if delete (delete-and-extract-region beg end)
+                     (buffer-substring beg end))))
+       (dolist (filter buffer-substring-filters)
+         (setq string (funcall filter string)))
+       (if noprops
+           (set-text-properties 0 (length string) nil string))
+       string)))
+   (noprops
+    (buffer-substring-no-properties beg end))
+   (t
+    (buffer-substring beg end))))
+
 
 ;;;; Window system cut and paste hooks.
 
@@ -2459,8 +2526,8 @@ yanking point; just return the Nth kill forward."
 (put 'text-read-only 'error-message "Text is read-only")
 
 (defun kill-region (beg end &optional yank-handler)
-  "Kill between point and mark.
-The text is deleted but saved in the kill ring.
+  "Kill (\"cut\") text between point and mark.
+This deletes the text from the buffer and saves it in the kill ring.
 The command \\[yank] can retrieve it from there.
 \(If you want to kill and then yank immediately, use \\[kill-ring-save].)
 
@@ -2482,7 +2549,11 @@ to make one entry in the kill ring.
 In Lisp code, optional third arg YANK-HANDLER, if non-nil,
 specifies the yank-handler text property to be set on the killed
 text.  See `insert-for-yank'."
-  (interactive "r")
+  ;; Pass point first, then mark, because the order matters
+  ;; when calling kill-append.
+  (interactive (list (point) (mark)))
+  (unless (and beg end)
+    (error "The mark is not set now, so there is no region"))
   (condition-case nil
       (let ((string (filter-buffer-substring beg end t)))
        (when string                    ;STRING is nil if BEG = END
@@ -2586,7 +2657,7 @@ The argument is used for internal purposes; do not supply one."
 ;; This is actually used in subr.el but defcustom does not work there.
 (defcustom yank-excluded-properties
   '(read-only invisible intangible field mouse-face help-echo local-map keymap
-    yank-handler follow-link)
+    yank-handler follow-link fontified)
   "*Text properties to discard when yanking.
 The value should be a list of text properties to discard or t,
 which means to discard all text properties."
@@ -2643,7 +2714,7 @@ doc string for `insert-for-yank-1', which see."
   nil)
 
 (defun yank (&optional arg)
-  "Reinsert the last stretch of killed text.
+  "Reinsert (\"paste\") the last stretch of killed text.
 More precisely, reinsert the stretch of killed text most recently
 killed OR yanked.  Put point at end, and set mark at beginning.
 With just \\[universal-argument] as argument, same but put point at beginning (and mark at end).
@@ -2654,7 +2725,7 @@ When this command inserts killed text into the buffer, it honors
 `yank-excluded-properties' and `yank-handler' as described in the
 doc string for `insert-for-yank-1', which see.
 
-See also the command \\[yank-pop]."
+See also the command `yank-pop' (\\[yank-pop])."
   (interactive "*P")
   (setq yank-window-start (window-start))
   ;; If we don't get all the way thru, make last-command indicate that
@@ -3025,10 +3096,12 @@ it is possible that the region may have changed")
   "Hook run when the mark becomes inactive.")
 
 (defun mark (&optional force)
-  "Return this buffer's mark value as integer; error if mark inactive.
-If optional argument FORCE is non-nil, access the mark value
-even if the mark is not currently active, and return nil
-if there is no mark at all.
+  "Return this buffer's mark value as integer, or nil if never set.
+
+In Transient Mark mode, this function signals an error if
+the mark is not active.  However, if `mark-even-if-inactive' is non-nil,
+or the argument FORCE is non-nil, it disregards whether the mark
+is active, and returns an integer or nil in the usual way.
 
 If you are using this in an editing command, you are most likely making
 a mistake; see the documentation of `set-mark'."
@@ -3139,13 +3212,17 @@ for mark off the local mark ring \(this does not affect the global
 mark ring\).  Use \\[pop-global-mark] to jump to a mark off the global
 mark ring \(see `pop-global-mark'\).
 
-Repeating the \\[set-mark-command] command without the prefix jumps to
-the next position off the local (or global) mark ring.
+If `set-mark-command-repeat-pop' is non-nil, repeating
+the \\[set-mark-command] command with no prefix pops the next position
+off the local (or global) mark ring and jumps there.
 
 With a double \\[universal-argument] prefix argument, e.g. \\[universal-argument] \
 \\[universal-argument] \\[set-mark-command], unconditionally
 set mark where point is.
 
+Setting the mark also sets the \"region\", which is the closest
+equivalent in Emacs to what some editors call the \"selection\".
+
 Novice Emacs Lisp programmers often try to use the mark for the wrong
 purposes.  See the documentation of `set-mark' for more information."
   (interactive "P")
@@ -3398,6 +3475,63 @@ Outline mode sets this."
       (or (memq prop buffer-invisibility-spec)
          (assq prop buffer-invisibility-spec)))))
 
+;; Returns non-nil if partial move was done.
+(defun line-move-partial (arg noerror to-end)
+  (if (< arg 0)
+      ;; Move backward (up).
+      ;; If already vscrolled, reduce vscroll
+      (let ((vs (window-vscroll nil t)))
+       (when (> vs (frame-char-height))
+         (set-window-vscroll nil (- vs (frame-char-height)) t)))
+
+    ;; Move forward (down).
+    (let* ((lh (window-line-height -1))
+          (vpos (nth 1 lh))
+          (ypos (nth 2 lh))
+          (rbot (nth 3 lh))
+          ppos py vs)
+      (when (or (null lh)
+               (>= rbot (frame-char-height))
+               (<= ypos (- (frame-char-height))))
+       (unless lh
+         (let ((wend (pos-visible-in-window-p t nil t)))
+           (setq rbot (nth 3 wend)
+                 vpos (nth 5 wend))))
+       (cond
+        ;; If last line of window is fully visible, move forward.
+        ((or (null rbot) (= rbot 0))
+         nil)
+        ;; If cursor is not in the bottom scroll margin, move forward.
+        ((and (> vpos 0)
+              (< (setq py
+                       (or (nth 1 (window-line-height))
+                           (let ((ppos (posn-at-point)))
+                             (cdr (or (posn-actual-col-row ppos)
+                                      (posn-col-row ppos))))))
+                 (min (- (window-text-height) scroll-margin 1) (1- vpos))))
+         nil)
+        ;; When already vscrolled, we vscroll some more if we can,
+        ;; or clear vscroll and move forward at end of tall image.
+        ((> (setq vs (window-vscroll nil t)) 0)
+         (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.
+        ((and (> vpos 0)
+              (= py (min (- (window-text-height) scroll-margin 1)
+                         (1- vpos))))
+         (set-window-vscroll nil (frame-char-height) t)
+         (line-move-1 arg noerror to-end)
+         t)
+        ;; If there are lines above the last line, scroll-up one line.
+        ((> vpos 0)
+         (scroll-up 1)
+         t)
+        ;; Finally, start vscroll.
+        (t
+         (set-window-vscroll nil (frame-char-height) t)))))))
+
+
 ;; This is like line-move-1 except that it also performs
 ;; vertical scrolling of tall images if appropriate.
 ;; That is not really a clean thing to do, since it mixes
@@ -3405,37 +3539,14 @@ Outline mode sets this."
 ;; 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)
-  (if (and auto-window-vscroll try-vscroll
-          ;; But don't vscroll in a keyboard macro.
-          (not defining-kbd-macro)
-          (not executing-kbd-macro))
-      (let ((forward (> arg 0))
-           (part (nth 2 (pos-visible-in-window-p (point) nil t))))
-       (if (and (consp part)
-                (> (if forward (cdr part) (car part)) 0))
-           (set-window-vscroll nil
-                               (if forward
-                                   (+ (window-vscroll nil t)
-                                      (min (cdr part)
-                                           (* (frame-char-height) arg)))
-                                 (max 0
-                                      (- (window-vscroll nil t)
-                                         (min (car part)
-                                              (* (frame-char-height) (- arg))))))
-                               t)
-         (set-window-vscroll nil 0)
-         (when (line-move-1 arg noerror to-end)
-           (when (not forward)
-             ;; Update display before calling pos-visible-in-window-p,
-             ;; because it depends on window-start being up-to-date.
-             (sit-for 0)
-             ;; If the current line is partly hidden at the bottom,
-             ;; scroll it partially up so as to unhide the bottom.
-             (if (and (setq part (nth 2 (pos-visible-in-window-p
-                                         (line-beginning-position) nil t)))
-                      (> (cdr part) 0))
-                 (set-window-vscroll nil (cdr part) t)))
-           t)))
+  (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)
     (line-move-1 arg noerror to-end)))
 
 ;; This is the guts of next-line and previous-line.
@@ -3446,7 +3557,7 @@ Outline mode sets this."
   ;; for intermediate positions.
   (let ((inhibit-point-motion-hooks t)
        (opoint (point))
-       (forward (> arg 0)))
+       (orig-arg arg))
     (unwind-protect
        (progn
          (if (not (memq last-command '(next-line previous-line)))
@@ -3454,7 +3565,7 @@ Outline mode sets this."
                    (if (and track-eol (eolp)
                             ;; Don't count beg of empty line as end of line
                             ;; unless we just did explicit end-of-line.
-                            (or (not (bolp)) (eq last-command 'end-of-line)))
+                            (or (not (bolp)) (eq last-command 'move-end-of-line)))
                        9999
                      (current-column))))
 
@@ -3479,14 +3590,18 @@ Outline mode sets this."
                              'end-of-buffer)
                            nil)))
            ;; Move by arg lines, but ignore invisible ones.
-           (let (done)
+           (let (done line-end)
              (while (and (> arg 0) (not done))
                ;; If the following character is currently invisible,
                ;; skip all characters with that same `invisible' property value.
                (while (and (not (eobp)) (line-move-invisible-p (point)))
                  (goto-char (next-char-property-change (point))))
-               ;; Now move a line.
-               (end-of-line)
+               ;; Move a line.
+               ;; We don't use `end-of-line', since we want to escape
+               ;; from field boundaries ocurring exactly at point.
+               (let ((inhibit-field-text-motion t))
+                 (setq line-end (line-end-position)))
+               (goto-char (constrain-to-field line-end (point) t t))
                ;; If there's no invisibility here, move over the newline.
                (cond
                 ((eobp)
@@ -3509,7 +3624,14 @@ Outline mode sets this."
              ;; The logic of this is the same as the loop above,
              ;; it just goes in the other direction.
              (while (and (< arg 0) (not done))
-               (beginning-of-line)
+               ;; For completely consistency with the forward-motion
+               ;; case, we should call beginning-of-line here.
+               ;; However, if point is inside a field and on a
+               ;; continued line, the call to (vertical-motion -1)
+               ;; below won't move us back far enough; then we return
+               ;; to the same column in line-move-finish, and point
+               ;; gets stuck -- cyd
+               (forward-line 0)
                (cond
                 ((bobp)
                  (if (not noerror)
@@ -3544,7 +3666,7 @@ Outline mode sets this."
             (beginning-of-line))
            (t
             (line-move-finish (or goal-column temporary-goal-column)
-                              opoint forward))))))
+                              opoint (> orig-arg 0)))))))
 
 (defun line-move-finish (column opoint forward)
   (let ((repeat t))
@@ -3553,6 +3675,7 @@ Outline mode sets this."
       (setq repeat nil)
 
       (let (new
+           (old (point))
            (line-beg (save-excursion (beginning-of-line) (point)))
            (line-end
             ;; Compute the end of the line
@@ -3567,13 +3690,29 @@ Outline mode sets this."
 
        ;; Move to the desired column.
        (line-move-to-column column)
+
+       ;; Corner case: suppose we start out in a field boundary in
+       ;; the middle of a continued line.  When we get to
+       ;; line-move-finish, point is at the start of a new *screen*
+       ;; line but the same text line; then line-move-to-column would
+       ;; move us backwards. Test using C-n with point on the "x" in
+       ;;   (insert "a" (propertize "x" 'field t) (make-string 89 ?y))
+       (and forward
+            (< (point) old)
+            (goto-char old))
+
        (setq new (point))
 
        ;; Process intangibility within a line.
-       ;; Move to the chosen destination position from above,
-       ;; with intangibility processing enabled.
-
-       (goto-char (point-min))
+       ;; With inhibit-point-motion-hooks bound to nil, a call to
+       ;; goto-char moves point past intangible text.
+
+       ;; However, inhibit-point-motion-hooks controls both the
+       ;; intangibility and the point-entered/point-left hooks.  The
+       ;; following hack avoids calling the point-* hooks
+       ;; unnecessarily.  Note that we move *forward* past intangible
+       ;; text when the initial and final points are the same.
+       (goto-char new)
        (let ((inhibit-point-motion-hooks nil))
          (goto-char new)
 
@@ -3601,8 +3740,15 @@ Outline mode sets this."
        (goto-char opoint)
        (let ((inhibit-point-motion-hooks nil))
          (goto-char
-          (constrain-to-field new opoint nil t
-                              'inhibit-line-move-field-capture)))
+          ;; Ignore field boundaries if the initial and final
+          ;; positions have the same `field' property, even if the
+          ;; fields are non-contiguous.  This seems to be "nicer"
+          ;; behavior in many situations.
+          (if (eq (get-char-property new 'field)
+                  (get-char-property opoint 'field))
+              new
+            (constrain-to-field new opoint t t
+                                'inhibit-line-move-field-capture))))
 
        ;; If all this moved us to a different line,
        ;; retry everything within that new line.
@@ -3643,15 +3789,13 @@ and `current-column' to be able to ignore invisible text."
            (goto-char (previous-char-property-change (point) line-beg))))))))
 
 (defun move-end-of-line (arg)
-  "Move point to end of current line.
+  "Move point to end of current line as displayed.
+\(If there's an image in the line, this disregards newlines
+which are part of the text that the image rests on.)
+
 With argument ARG not nil or 1, move forward ARG - 1 lines first.
 If point reaches the beginning or end of buffer, it stops there.
-To ignore intangibility, bind `inhibit-point-motion-hooks' to t.
-
-This command does not move point across a field boundary unless doing so
-would move beyond there to a different line; if ARG is nil or 1, and
-point starts at a field boundary, point does not move.  To ignore field
-boundaries bind `inhibit-field-text-motion' to t."
+To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
   (interactive "p")
   (or arg (setq arg 1))
   (let (done)
@@ -3679,24 +3823,46 @@ boundaries bind `inhibit-field-text-motion' to t."
            (setq done t)))))))
 
 (defun move-beginning-of-line (arg)
-  "Move point to beginning of current display line.
+  "Move point to beginning of current line as displayed.
+\(If there's an image in the line, this disregards newlines
+which are part of the text that the image rests on.)
+
 With argument ARG not nil or 1, move forward ARG - 1 lines first.
 If point reaches the beginning or end of buffer, it stops there.
-To ignore intangibility, bind `inhibit-point-motion-hooks' to t.
-
-This command does not move point across a field boundary unless doing so
-would move beyond there to a different line; if ARG is nil or 1, and
-point starts at a field boundary, point does not move.  To ignore field
-boundaries bind `inhibit-field-text-motion' to t."
+To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
   (interactive "p")
   (or arg (setq arg 1))
-  (if (/= arg 1)
-      (line-move (1- arg) t))
-  (beginning-of-line 1)
-  (let ((orig (point)))
-    (vertical-motion 0)
-    (if (/= orig (point))
-       (goto-char (constrain-to-field (point) orig (/= arg 1) t nil)))))
+
+  (let ((orig (point))
+       start first-vis first-vis-field-value)
+
+    ;; Move by lines, if ARG is not 1 (the default).
+    (if (/= arg 1)
+       (line-move (1- arg) t))
+
+    ;; Move to beginning-of-line, ignoring fields and invisibles.
+    (skip-chars-backward "^\n")
+    (while (and (not (bobp)) (line-move-invisible-p (1- (point))))
+      (goto-char (previous-char-property-change (point)))
+      (skip-chars-backward "^\n"))
+    (setq start (point))
+
+    ;; Now find first visible char in the line
+    (while (and (not (eobp)) (line-move-invisible-p (point)))
+      (goto-char (next-char-property-change (point))))
+    (setq first-vis (point))
+
+    ;; See if fields would stop us from reaching FIRST-VIS.
+    (setq first-vis-field-value
+         (constrain-to-field first-vis orig (/= arg 1) t nil))
+
+    (goto-char (if (/= first-vis-field-value first-vis)
+                  ;; If yes, obey them.
+                  first-vis-field-value
+                ;; Otherwise, move to START with attention to fields.
+                ;; (It is possible that fields never matter in this case.)
+                (constrain-to-field (point) orig
+                                    (/= arg 1) t nil)))))
 
 
 ;;; Many people have said they rarely use this feature, and often type
@@ -3980,6 +4146,7 @@ If optional arg REALLY-WORD is non-nil, it finds just a word."
                 string)
   :group 'fill)
 (make-variable-buffer-local 'fill-prefix)
+;;;###autoload(put 'fill-prefix 'safe-local-variable 'string-or-null-p)
 
 (defcustom auto-fill-inhibit-regexp nil
   "*Regexp to match lines which should not be auto-filled."
@@ -4161,7 +4328,7 @@ The variable `selective-display' has a separate value for each buffer."
 (defvaralias 'indicate-unused-lines 'indicate-empty-lines)
 (defvaralias 'default-indicate-unused-lines 'default-indicate-empty-lines)
 
-(defun toggle-truncate-lines (arg)
+(defun toggle-truncate-lines (&optional arg)
   "Toggle whether to fold or truncate long lines on the screen.
 With arg, truncate long lines iff arg is positive.
 Note that in side-by-side windows, truncation is always enabled."
@@ -4232,21 +4399,21 @@ in the mode line.
 Line numbers do not appear for very large buffers and buffers
 with very long lines; see variables `line-number-display-limit'
 and `line-number-display-limit-width'."
-  :init-value t :global t :group 'editing-basics)
+  :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 iff arg is positive.
 When Column Number mode is enabled, the column number appears
 in the mode line."
-  :global t :group 'editing-basics)
+  :global t :group 'mode-line)
 
 (define-minor-mode size-indication-mode
   "Toggle Size Indication mode.
 With arg, turn Size Indication mode on iff arg is positive.  When
 Size Indication mode is enabled, the size of the accessible part
 of the buffer appears in the mode line."
-  :global t :group 'editing-basics)
+  :global t :group 'mode-line)
 \f
 (defgroup paren-blinking nil
   "Blinking matching of parens and expressions."
@@ -4281,7 +4448,9 @@ If nil, search stops at the beginning of the accessible portion of the buffer."
   :group 'paren-blinking)
 
 (defcustom blink-matching-paren-dont-ignore-comments nil
-  "*Non-nil means `blink-matching-paren' will not ignore comments."
+  "*nil means `blink-matching-paren' ignores comments.
+More precisely, when looking for the matching parenthesis,
+it skips the contents of comments that end before point."
   :type 'boolean
   :group 'paren-blinking)
 
@@ -4525,10 +4694,6 @@ See also `read-mail-command' concerning reading mail."
        (insert body))
       t)))
 
-(define-mail-user-agent 'mh-e-user-agent
-  'mh-smail-batch 'mh-send-letter 'mh-fully-kill-draft
-  'mh-before-send-letter-hook)
-
 (defun compose-mail (&optional to subject other-headers continue
                               switch-function yank-action send-actions)
   "Start composing a mail message to send.
@@ -4744,7 +4909,7 @@ With prefix argument N, move N items (negative N means move backward)."
        (error "No completion here"))
     (setq beg (previous-single-property-change beg 'mouse-face))
     (setq end (or (next-single-property-change end 'mouse-face) (point-max)))
-    (setq completion (buffer-substring beg end))
+    (setq completion (buffer-substring-no-properties beg end))
     (let ((owindow (selected-window)))
       (if (and (one-window-p t 'selected-frame)
               (window-dedicated-p (selected-window)))
@@ -4878,6 +5043,12 @@ value of `completion-common-substring'. See also `display-completion-list'.")
 
 ;; Variables and faces used in `completion-setup-function'.
 
+(defcustom completion-show-help t
+  "Non-nil means show help message in *Completions* buffer."
+  :type 'boolean
+  :version "22.1"
+  :group 'completion)
+
 (defface completions-first-difference
   '((t (:inherit bold)))
   "Face put on the first uncommon character in completions in *Completions* buffer."
@@ -4901,68 +5072,52 @@ of the differing parts is, by contrast, slightly highlighted."
   "Common prefix substring to use in `completion-setup-function' to put faces.
 The value is set by `display-completion-list' during running `completion-setup-hook'.
 
-To put faces, `completions-first-difference' and `completions-common-part'
-into \"*Completions*\* buffer, the common prefix substring in completions is
-needed as a hint. (Minibuffer is a special case. The content of minibuffer itself
-is the substring.)")
+To put faces `completions-first-difference' and `completions-common-part'
+in the `*Completions*' buffer, the common prefix substring in completions
+is needed as a hint.  (The minibuffer is a special case.  The content
+of the minibuffer before point is always the common substring.)")
 
 ;; This function goes in completion-setup-hook, so that it is called
 ;; after the text of the completion list buffer is written.
 (defun completion-setup-function ()
   (let* ((mainbuf (current-buffer))
-         (mbuf-contents (minibuffer-contents))
-         (common-string-length (length mbuf-contents)))
+         (mbuf-contents (minibuffer-completion-contents))
+         common-string-length)
     ;; When reading a file name in the minibuffer,
     ;; set default-directory in the minibuffer
     ;; so it will get copied into the completion list buffer.
     (if minibuffer-completing-file-name
        (with-current-buffer mainbuf
          (setq default-directory (file-name-directory mbuf-contents))))
-    ;; If partial-completion-mode is on, point might not be after the
-    ;; last character in the minibuffer.
-    ;; FIXME: This hack should be moved to complete.el where we call
-    ;; display-completion-list.
-    (when partial-completion-mode
-      (setq common-string-length
-            (if (eq (char-after (field-beginning)) ?-)
-                ;; If the text to be completed starts with a `-', there is no
-                ;; common prefix.
-                ;; FIXME: this probably still doesn't do the right thing
-                ;; when completing file names.  It's not even clear what
-                ;; is TRT.
-                0
-              (- common-string-length (- (point-max) (point))))))
     (with-current-buffer standard-output
       (completion-list-mode)
       (set (make-local-variable 'completion-reference-buffer) mainbuf)
       (setq completion-base-size
-            (if minibuffer-completing-file-name
-                ;; For file name completion, use the number of chars before
-                ;; the start of the last file name component.
-               (with-current-buffer mainbuf
-                 (save-excursion
-                   (goto-char (point-max))
-                   (skip-chars-backward completion-root-regexp)
-                   (- (point) (minibuffer-prompt-end))))
-              ;; Otherwise, in minibuffer, the whole input is being completed.
-              (if (minibufferp mainbuf) 0)))
-      (if (and (symbolp minibuffer-completion-table)
-               (get minibuffer-completion-table 'completion-base-size-function))
-          (setq completion-base-size
-                ;; FIXME: without any extra arg, how is this function
-                ;; expected to return anything else than a constant unless
-                ;; it redoes part of the work of all-completions?
-                ;; In most cases this value would better be computed and
-                ;; returned at the same time as the list of all-completions
-                ;; is computed.  --Stef
-                (funcall (get minibuffer-completion-table
-                              'completion-base-size-function))))
+           (cond
+            ((and (symbolp minibuffer-completion-table)
+                  (get minibuffer-completion-table 'completion-base-size-function))
+             ;; To compute base size, a function can use the global value of
+             ;; completion-common-substring or minibuffer-completion-contents.
+             (with-current-buffer mainbuf
+               (funcall (get minibuffer-completion-table
+                             'completion-base-size-function))))
+            (minibuffer-completing-file-name
+             ;; For file name completion, use the number of chars before
+             ;; the start of the file name component at point.
+             (with-current-buffer mainbuf
+               (save-excursion
+                 (skip-chars-backward completion-root-regexp)
+                 (- (point) (minibuffer-prompt-end)))))
+            ;; Otherwise, in minibuffer, the base size is 0.
+            ((minibufferp mainbuf) 0)))
+      (setq common-string-length
+           (cond
+            (completion-common-substring
+             (length completion-common-substring))
+            (completion-base-size
+             (- (length mbuf-contents) completion-base-size))))
       ;; Put faces on first uncommon characters and common parts.
-      (when (or completion-common-substring completion-base-size)
-        (setq common-string-length
-              (if completion-common-substring
-                  (length completion-common-substring)
-                (- common-string-length completion-base-size)))
+      (when (and (integerp common-string-length) (>= common-string-length 0))
        (let ((element-start (point-min))
               (maxp (point-max))
               element-common-end)
@@ -4973,20 +5128,22 @@ is the substring.)")
                                (+ element-start common-string-length))
                          maxp))
            (when (get-char-property element-start 'mouse-face)
-             (if (get-char-property (1- element-common-end) 'mouse-face)
+             (if (and (> common-string-length 0)
+                      (get-char-property (1- element-common-end) 'mouse-face))
                  (put-text-property element-start element-common-end
                                     'font-lock-face 'completions-common-part))
              (if (get-char-property element-common-end 'mouse-face)
                  (put-text-property element-common-end (1+ element-common-end)
                                     'font-lock-face 'completions-first-difference))))))
-      ;; Insert help string.
-      (goto-char (point-min))
-      (if (display-mouse-p)
-         (insert (substitute-command-keys
-                  "Click \\[mouse-choose-completion] on a completion to select it.\n")))
-      (insert (substitute-command-keys
-              "In this buffer, type \\[choose-completion] to \
-select the completion near point.\n\n")))))
+      ;; Maybe insert help string.
+      (when completion-show-help
+       (goto-char (point-min))
+       (if (display-mouse-p)
+           (insert (substitute-command-keys
+                    "Click \\[mouse-choose-completion] on a completion to select it.\n")))
+       (insert (substitute-command-keys
+                "In this buffer, type \\[choose-completion] to \
+select the completion near point.\n\n"))))))
 
 (add-hook 'completion-setup-hook 'completion-setup-function)
 
@@ -5005,8 +5162,8 @@ select the completion near point.\n\n")))))
       (goto-char (point-min))
       (search-forward "\n\n")
       (forward-line 1))))
-
-;; Support keyboard commands to turn on various modifiers.
+\f
+;;; Support keyboard commands to turn on various modifiers.
 
 ;; These functions -- which are not commands -- each add one modifier
 ;; to the following event.
@@ -5071,7 +5228,7 @@ PREFIX is the string that represents this modifier in an event type symbol."
 (define-key function-key-map [?\C-x ?@ ?a] 'event-apply-alt-modifier)
 (define-key function-key-map [?\C-x ?@ ?S] 'event-apply-shift-modifier)
 (define-key function-key-map [?\C-x ?@ ?c] 'event-apply-control-modifier)
-
+\f
 ;;;; Keypad support.
 
 ;;; Make the keypad keys act like ordinary typing keys.  If people add
@@ -5166,7 +5323,8 @@ after it has been set up properly in other respects."
         (error "Cannot clone a file-visiting buffer"))
      (if (get major-mode 'no-clone)
         (error "Cannot clone a buffer in %s mode" mode-name))
-     (list (if current-prefix-arg (read-string "Name: "))
+     (list (if current-prefix-arg
+              (read-buffer "Name of new cloned buffer: " (current-buffer)))
           t)))
   (if buffer-file-name
       (error "Cannot clone a file-visiting buffer"))
@@ -5213,7 +5371,12 @@ after it has been set up properly in other respects."
       ;; Run any hooks (typically set up by the major mode
       ;; for cloning to work properly).
       (run-hooks 'clone-buffer-hook))
-    (if display-flag (pop-to-buffer new))
+    (if display-flag
+        ;; Presumably the current buffer is shown in the selected frame, so
+        ;; we want to display the clone elsewhere.
+        (let ((same-window-regexps nil)
+              (same-window-buffer-names))
+          (pop-to-buffer new)))
     new))
 
 
@@ -5236,7 +5399,7 @@ front of the list of recently selected ones."
      (if (get major-mode 'no-clone-indirect)
         (error "Cannot indirectly clone a buffer in %s mode" mode-name))
      (list (if current-prefix-arg
-              (read-string "BName of indirect buffer: "))
+              (read-buffer "Name of indirect buffer: " (current-buffer)))
           t)))
   (if (get major-mode 'no-clone-indirect)
       (error "Cannot indirectly clone a buffer in %s mode" mode-name))
@@ -5250,15 +5413,17 @@ front of the list of recently selected ones."
     buffer))
 
 
-(defun clone-indirect-buffer-other-window (buffer &optional norecord)
-  "Create an indirect buffer that is a twin copy of BUFFER.
-Select the new buffer in another window.
-Optional second arg NORECORD non-nil means do not put this buffer at
-the front of the list of recently selected ones."
-  (interactive "bClone buffer in other window: ")
+(defun clone-indirect-buffer-other-window (newname display-flag &optional norecord)
+  "Like `clone-indirect-buffer' but display in another window."
+  (interactive
+   (progn
+     (if (get major-mode 'no-clone-indirect)
+        (error "Cannot indirectly clone a buffer in %s mode" mode-name))
+     (list (if current-prefix-arg
+              (read-buffer "Name of indirect buffer: " (current-buffer)))
+          t)))
   (let ((pop-up-windows t))
-    (set-buffer buffer)
-    (clone-indirect-buffer nil t norecord)))
+    (clone-indirect-buffer newname display-flag norecord)))
 
 \f
 ;;; Handling of Backspace and Delete keys.