(list-colors-display): Use with-help-window instead of with-output-to-temp-buffer.
[bpt/emacs.git] / lisp / simple.el
index 7c5bd13..572d7d6 100644 (file)
@@ -1,7 +1,8 @@
 ;;; 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, 2006, 2007 Free Software Foundation, Inc.
+;;   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+;;   Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: internal
@@ -457,7 +458,7 @@ than the value of `fill-column' and ARG is nil."
     ;; Mark the newline(s) `hard'.
     (if use-hard-newlines
        (set-hard-newline-properties
-        (- (point) (if arg (prefix-numeric-value arg) 1)) (point)))
+        (- (point) (prefix-numeric-value arg)) (point)))
     ;; If the newline leaves the previous line blank,
     ;; and we have a left margin, delete that from the blank line.
     (or flag
@@ -632,7 +633,16 @@ column specified by the function `current-left-margin'."
     (newline)
     (save-excursion
       (goto-char pos)
+      ;; We are at EOL before the call to indent-according-to-mode, and
+      ;; after it we usually are as well, but not always.  We tried to
+      ;; address it with `save-excursion' but that uses a normal marker
+      ;; whereas we need `move after insertion', so we do the save/restore
+      ;; by hand.
+      (setq pos (copy-marker pos t))
       (indent-according-to-mode)
+      (goto-char pos)
+      ;; Remove the trailing white-space after indentation because
+      ;; indentation may introduce the whitespace.
       (delete-horizontal-space t))
     (indent-according-to-mode)))
 
@@ -1043,7 +1053,7 @@ display the result of expression evaluation."
                (if (boundp 'edebug-active) edebug-active)))
       (let ((char-string
              (if (or (if (boundp 'edebug-active) edebug-active)
-                     (memq this-command '(eval-last-sexp eval-print-last-sexp)))
+                    (memq this-command '(eval-last-sexp eval-print-last-sexp)))
                  (prin1-char value))))
         (if char-string
             (format " (#o%o, #x%x, %s)" value value char-string)
@@ -1292,7 +1302,11 @@ makes the search case-sensitive."
   "Puts element of the minibuffer history in the minibuffer.
 The argument NABS specifies the absolute history position."
   (interactive "p")
-  (let ((minimum (if minibuffer-default -1 0))
+  (let ((minimum (if minibuffer-default
+                    (- (if (listp minibuffer-default)
+                           (length minibuffer-default)
+                         1))
+                  0))
        elt minibuffer-returned-to-present)
     (if (and (zerop minibuffer-history-position)
             (null minibuffer-text-before-history))
@@ -1314,8 +1328,10 @@ The argument NABS specifies the absolute history position."
     (goto-char (point-max))
     (delete-minibuffer-contents)
     (setq minibuffer-history-position nabs)
-    (cond ((= nabs -1)
-          (setq elt minibuffer-default))
+    (cond ((< nabs 0)
+          (setq elt (if (listp minibuffer-default)
+                        (nth (1- (abs nabs)) minibuffer-default)
+                      minibuffer-default)))
          ((= nabs 0)
           (setq elt (or minibuffer-text-before-history ""))
           (setq minibuffer-returned-to-present t)
@@ -2545,8 +2561,6 @@ the text which should be made available.
 The second, optional, argument PUSH, has the same meaning as the
 similar argument to `x-set-cut-buffer', which see.")
 
-(make-variable-frame-local 'interprogram-cut-function)
-
 (defvar interprogram-paste-function nil
   "Function to call to get text cut from other programs.
 
@@ -2561,14 +2575,17 @@ 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
+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.")
-
-(make-variable-frame-local 'interprogram-paste-function)
 \f
 
 
@@ -2644,11 +2661,11 @@ If `interprogram-cut-function' is set, pass the resulting kill to it."
 
 (defun current-kill (n &optional do-not-move)
   "Rotate the yanking point by N places, and then return that kill.
-If N is zero, `interprogram-paste-function' is set, and calling it
-returns a string, then that string is added to the front of the
-kill ring and returned as the latest kill.
-If optional arg DO-NOT-MOVE is non-nil, then don't actually move the
-yanking point; just return the Nth kill forward."
+If N is zero, `interprogram-paste-function' is set, and calling it returns a
+string or list of strings, then that string (or list) is added to the front
+of the kill ring and the string (or first string in the list) is returned as
+the latest kill.  If optional arg DO-NOT-MOVE is non-nil, then don't
+actually move the yanking point; just return the Nth kill forward."
   (let ((interprogram-paste (and (= n 0)
                                 interprogram-paste-function
                                 (funcall interprogram-paste-function))))
@@ -2658,8 +2675,10 @@ yanking point; just return the Nth kill forward."
          ;; text to the kill ring, so Emacs doesn't try to own the
          ;; selection, with identical text.
          (let ((interprogram-cut-function nil))
-           (kill-new interprogram-paste))
-         interprogram-paste)
+           (if (listp interprogram-paste)
+             (mapc 'kill-new (nreverse interprogram-paste))
+             (kill-new interprogram-paste)))
+         (car kill-ring))
       (or kill-ring (error "Kill ring is empty"))
       (let ((ARGth-kill-element
             (nthcdr (mod (- n (length kill-ring-yank-pointer))
@@ -2745,7 +2764,9 @@ text.  See `insert-for-yank'."
   "Save the region as if killed, but don't kill it.
 In Transient Mark mode, deactivate the mark.
 If `interprogram-cut-function' is non-nil, also save the text for a window
-system cut and paste."
+system cut and paste.
+
+This command's old key binding has been given to `kill-ring-save'."
   (interactive "r")
   (if (eq last-command 'kill-region)
       (kill-append (filter-buffer-substring beg end) (< end beg))
@@ -2815,7 +2836,7 @@ The argument is used for internal purposes; do not supply one."
 (defcustom yank-excluded-properties
   '(read-only invisible intangible field mouse-face help-echo local-map keymap
     yank-handler follow-link fontified)
-  "*Text properties to discard when yanking.
+  "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."
   :type '(choice (const :tag "All" t) (repeat symbol))
@@ -3623,7 +3644,7 @@ The beginning of a blank line does not count as the end of a line."
   "Current goal column for vertical motion.
 It is the column where point was
 at the start of current run of vertical motion commands.
-When the `track-eol' feature is doing its job, the value is 9999.")
+When the `track-eol' feature is doing its job, the value is `most-positive-fixnum'.")
 
 (defcustom line-move-ignore-invisible t
   "*Non-nil means \\[next-line] and \\[previous-line] ignore invisible lines.
@@ -3631,16 +3652,6 @@ Outline mode sets this."
   :type 'boolean
   :group 'editing-basics)
 
-(defun invisible-p (pos)
-  "Return non-nil if the character after POS is currently invisible."
-  (let ((prop
-        (get-char-property pos 'invisible)))
-    (if (eq buffer-invisibility-spec t)
-       prop
-      (or (memq prop buffer-invisibility-spec)
-         (assq prop buffer-invisibility-spec)))))
-(define-obsolete-function-alias 'line-move-invisible-p 'invisible-p)
-
 ;; Returns non-nil if partial move was done.
 (defun line-move-partial (arg noerror to-end)
   (if (< arg 0)
@@ -3655,7 +3666,7 @@ Outline mode sets this."
           (vpos (nth 1 lh))
           (ypos (nth 2 lh))
           (rbot (nth 3 lh))
-          ppos py vs)
+          py vs)
       (when (or (null lh)
                (>= rbot (frame-char-height))
                (<= ypos (- (frame-char-height))))
@@ -3732,11 +3743,11 @@ Outline mode sets this."
                             ;; 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 'move-end-of-line)))
-                       9999
+                       most-positive-fixnum
                      (current-column))))
 
-         (if (and (not (integerp selective-display))
-                  (not line-move-ignore-invisible))
+         (if (not (or (integerp selective-display)
+                       line-move-ignore-invisible))
              ;; Use just newline characters.
              ;; Set ARG to 0 if we move as many lines as requested.
              (or (if (> arg 0)
@@ -3975,7 +3986,8 @@ To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
                      (not (bobp))
                      (progn
                        (while (and (not (bobp)) (invisible-p (1- (point))))
-                         (goto-char (previous-char-property-change (point))))
+                         (goto-char (previous-single-char-property-change
+                                      (point) 'invisible)))
                        (backward-char 1)))
                 (point)))))
        (goto-char newpos)
@@ -4002,7 +4014,7 @@ To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
   (or arg (setq arg 1))
 
   (let ((orig (point))
-       start first-vis first-vis-field-value)
+       first-vis first-vis-field-value)
 
     ;; Move by lines, if ARG is not 1 (the default).
     (if (/= arg 1)
@@ -4013,7 +4025,6 @@ To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
     (while (and (not (bobp)) (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)) (invisible-p (point)))
@@ -4664,86 +4675,92 @@ it skips the contents of comments that end before point."
                                 (skip-syntax-backward "/\\")
                                 (point))))))
     (let* ((oldpos (point))
-          blinkpos
-          message-log-max  ; Don't log messages about paren matching.
-          matching-paren
-          open-paren-line-string)
-      (save-excursion
-       (save-restriction
-         (if blink-matching-paren-distance
-             (narrow-to-region (max (minibuffer-prompt-end)
-                                    (- (point) blink-matching-paren-distance))
-                               oldpos))
-         (condition-case ()
-             (let ((parse-sexp-ignore-comments
-                    (and parse-sexp-ignore-comments
-                         (not blink-matching-paren-dont-ignore-comments))))
-               (setq blinkpos (scan-sexps oldpos -1)))
-           (error nil)))
-       (and blinkpos
-            ;; Not syntax '$'.
-            (not (eq (syntax-class (syntax-after blinkpos)) 8))
-            (setq matching-paren
-                  (let ((syntax (syntax-after blinkpos)))
-                    (and (consp syntax)
-                         (eq (syntax-class syntax) 4)
-                         (cdr syntax)))))
-       (cond
-        ((not (or (eq matching-paren (char-before oldpos))
-                   ;; The cdr might hold a new paren-class info rather than
-                   ;; a matching-char info, in which case the two CDRs
-                   ;; should match.
-                   (eq matching-paren (cdr (syntax-after (1- oldpos))))))
-         (message "Mismatched parentheses"))
-        ((not blinkpos)
-         (if (not blink-matching-paren-distance)
-             (message "Unmatched parenthesis")))
-        ((pos-visible-in-window-p blinkpos)
-         ;; Matching open within window, temporarily move to blinkpos but only
-         ;; if `blink-matching-paren-on-screen' is non-nil.
-         (and blink-matching-paren-on-screen
-              (not show-paren-mode)
-              (save-excursion
-                (goto-char blinkpos)
-                (sit-for blink-matching-delay))))
-        (t
-         (save-excursion
-           (goto-char blinkpos)
-           (setq open-paren-line-string
-                 ;; Show what precedes the open in its line, if anything.
-                 (if (save-excursion
-                       (skip-chars-backward " \t")
-                       (not (bolp)))
-                     (buffer-substring (line-beginning-position)
-                                       (1+ blinkpos))
-                   ;; Show what follows the open in its line, if anything.
-                   (if (save-excursion
-                         (forward-char 1)
-                         (skip-chars-forward " \t")
-                         (not (eolp)))
-                       (buffer-substring blinkpos
-                                         (line-end-position))
-                     ;; Otherwise show the previous nonblank line,
-                     ;; if there is one.
-                     (if (save-excursion
-                           (skip-chars-backward "\n \t")
-                           (not (bobp)))
-                         (concat
-                          (buffer-substring (progn
-                                              (skip-chars-backward "\n \t")
-                                              (line-beginning-position))
-                                            (progn (end-of-line)
-                                                   (skip-chars-backward " \t")
-                                                   (point)))
-                          ;; Replace the newline and other whitespace with `...'.
-                          "..."
-                          (buffer-substring blinkpos (1+ blinkpos)))
-                       ;; There is nothing to show except the char itself.
-                       (buffer-substring blinkpos (1+ blinkpos)))))))
-         (message "Matches %s"
-                  (substring-no-properties open-paren-line-string))))))))
-
-;Turned off because it makes dbx bomb out.
+          (message-log-max nil)  ; Don't log messages about paren matching.
+          (atdollar (eq (syntax-class (syntax-after (1- oldpos))) 8))
+          (isdollar)
+          (blinkpos
+            (save-excursion
+              (save-restriction
+                (if blink-matching-paren-distance
+                    (narrow-to-region
+                     (max (minibuffer-prompt-end) ;(point-min) unless minibuf.
+                          (- (point) blink-matching-paren-distance))
+                     oldpos))
+                (let ((parse-sexp-ignore-comments
+                       (and parse-sexp-ignore-comments
+                            (not blink-matching-paren-dont-ignore-comments))))
+                  (condition-case ()
+                      (scan-sexps oldpos -1)
+                    (error nil))))))
+          (matching-paren
+            (and blinkpos
+                 ;; Not syntax '$'.
+                 (not (setq isdollar
+                            (eq (syntax-class (syntax-after blinkpos)) 8)))
+                 (let ((syntax (syntax-after blinkpos)))
+                   (and (consp syntax)
+                        (eq (syntax-class syntax) 4)
+                        (cdr syntax))))))
+      (cond
+       ;; isdollar is for:
+       ;; http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00871.html
+       ((not (or (and isdollar blinkpos)
+                 (and atdollar (not blinkpos)) ; see below
+                 (eq matching-paren (char-before oldpos))
+                 ;; The cdr might hold a new paren-class info rather than
+                 ;; a matching-char info, in which case the two CDRs
+                 ;; should match.
+                 (eq matching-paren (cdr (syntax-after (1- oldpos))))))
+        (message "Mismatched parentheses"))
+       ((not blinkpos)
+        (or blink-matching-paren-distance
+            ;; Don't complain when `$' with no blinkpos, because it
+            ;; could just be the first one typed in the buffer.
+            atdollar
+            (message "Unmatched parenthesis")))
+       ((pos-visible-in-window-p blinkpos)
+        ;; Matching open within window, temporarily move to blinkpos but only
+        ;; if `blink-matching-paren-on-screen' is non-nil.
+        (and blink-matching-paren-on-screen
+             (not show-paren-mode)
+             (save-excursion
+               (goto-char blinkpos)
+               (sit-for blink-matching-delay))))
+       (t
+        (save-excursion
+          (goto-char blinkpos)
+          (let ((open-paren-line-string
+                 ;; Show what precedes the open in its line, if anything.
+                 (cond
+                  ((save-excursion (skip-chars-backward " \t") (not (bolp)))
+                   (buffer-substring (line-beginning-position)
+                                     (1+ blinkpos)))
+                  ;; Show what follows the open in its line, if anything.
+                  ((save-excursion
+                     (forward-char 1)
+                     (skip-chars-forward " \t")
+                     (not (eolp)))
+                   (buffer-substring blinkpos
+                                     (line-end-position)))
+                  ;; Otherwise show the previous nonblank line,
+                  ;; if there is one.
+                  ((save-excursion (skip-chars-backward "\n \t") (not (bobp)))
+                   (concat
+                    (buffer-substring (progn
+                                        (skip-chars-backward "\n \t")
+                                        (line-beginning-position))
+                                      (progn (end-of-line)
+                                             (skip-chars-backward " \t")
+                                             (point)))
+                    ;; Replace the newline and other whitespace with `...'.
+                    "..."
+                    (buffer-substring blinkpos (1+ blinkpos))))
+                  ;; There is nothing to show except the char itself.
+                  (t (buffer-substring blinkpos (1+ blinkpos))))))
+            (message "Matches %s"
+                     (substring-no-properties open-paren-line-string)))))))))
+
+;; Turned off because it makes dbx bomb out.
 (setq blink-paren-function 'blink-matching-open)
 \f
 ;; This executes C-g typed while Emacs is waiting for a command.
@@ -5560,13 +5577,13 @@ after it has been set up properly in other respects."
       (funcall mode)
 
       ;; Set up other local variables.
-      (mapcar (lambda (v)
-               (condition-case ()      ;in case var is read-only
-                   (if (symbolp v)
-                       (makunbound v)
-                     (set (make-local-variable (car v)) (cdr v)))
-                 (error nil)))
-             lvars)
+      (mapc (lambda (v)
+             (condition-case ()        ;in case var is read-only
+                 (if (symbolp v)
+                     (makunbound v)
+                   (set (make-local-variable (car v)) (cdr v)))
+               (error nil)))
+           lvars)
 
       ;; Run any hooks (typically set up by the major mode
       ;; for cloning to work properly).
@@ -5669,22 +5686,21 @@ call `normal-erase-is-backspace-mode' (which see) instead."
   (unless frame (setq frame (selected-frame)))
   (with-selected-frame frame
     (unless (terminal-parameter nil 'normal-erase-is-backspace)
-      (if (cond ((eq normal-erase-is-backspace 'maybe)
-                (and (not noninteractive)
-                     (or (memq system-type '(ms-dos windows-nt))
-                         (eq window-system 'mac)
-                         (and (memq window-system '(x))
-                              (fboundp 'x-backspace-delete-keys-p)
-                              (x-backspace-delete-keys-p))
-                         ;; If the terminal Emacs is running on has erase char
-                         ;; set to ^H, use the Backspace key for deleting
-                         ;; backward and, and the Delete key for deleting forward.
-                         (and (null window-system)
-                              (eq tty-erase-char ?\^H)))))
-               (t
-                normal-erase-is-backspace))
-         (normal-erase-is-backspace-mode 1)
-       (normal-erase-is-backspace-mode 0)))))
+      (normal-erase-is-backspace-mode
+       (if (if (eq normal-erase-is-backspace 'maybe)
+               (and (not noninteractive)
+                    (or (memq system-type '(ms-dos windows-nt))
+                        (eq window-system 'mac)
+                        (and (memq window-system '(x))
+                             (fboundp 'x-backspace-delete-keys-p)
+                             (x-backspace-delete-keys-p))
+                        ;; If the terminal Emacs is running on has erase char
+                        ;; set to ^H, use the Backspace key for deleting
+                        ;; backward, and the Delete key for deleting forward.
+                        (and (null window-system)
+                             (eq tty-erase-char ?\^H))))
+             normal-erase-is-backspace)
+           1 0)))))
 
 (defun normal-erase-is-backspace-mode (&optional arg)
   "Toggle the Erase and Delete mode of the Backspace and Delete keys.
@@ -5821,9 +5837,10 @@ works by saving the value of `buffer-invisibility-spec' and setting it to nil."
 (defconst bad-packages-alist
   ;; Not sure exactly which semantic versions have problems.
   ;; Definitely 2.0pre3, probably all 2.0pre's before this.
-  '((semantic semantic-version "2\\.0pre[1-3]"
+  '((semantic semantic-version "\\`2\\.0pre[1-3]\\'"
               "The version of `semantic' loaded does not work in Emacs 22.
-It can cause constant high CPU load.  Upgrade to at least 2.0pre4.")
+It can cause constant high CPU load.
+Upgrade to at least Semantic 2.0pre4 (distributed with CEDET 1.0pre4).")
     ;; CUA-mode does not work with GNU Emacs version 22.1 and newer.
     ;; Except for version 1.2, all of the 1.x and 2.x version of cua-mode
     ;; provided the `CUA-mode' feature.  Since this is no longer true,