Merge changes made in Gnus trunk.
[bpt/emacs.git] / lisp / isearch.el
index f18a74c..7f018ab 100644 (file)
@@ -1,8 +1,6 @@
 ;;; isearch.el --- incremental search minor mode
 
-;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000, 2001,
-;;   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 1992-1997, 1999-2011  Free Software Foundation, Inc.
 
 ;; Author: Daniel LaLiberte <liberte@cs.uiuc.edu>
 ;; Maintainer: FSF
@@ -239,7 +237,7 @@ Default value, nil, means edit the string instead."
   "Face for highlighting Isearch matches."
   :group 'isearch
   :group 'basic-faces)
-(defvar isearch 'isearch)
+(defvar isearch-face 'isearch)
 
 (defface isearch-fail
   '((((class color) (min-colors 88) (background light))
@@ -275,30 +273,37 @@ and `lazy-highlight-interval')."
   :group 'isearch
   :group 'matching)
 
+(define-obsolete-variable-alias 'isearch-lazy-highlight-cleanup
+                                'lazy-highlight-cleanup
+                                "22.1")
+
 (defcustom lazy-highlight-cleanup t
   "Controls whether to remove extra highlighting after a search.
 If this is nil, extra highlighting can be \"manually\" removed with
 \\[lazy-highlight-cleanup]."
   :type 'boolean
   :group 'lazy-highlight)
-(define-obsolete-variable-alias 'isearch-lazy-highlight-cleanup
-                                'lazy-highlight-cleanup
+
+(define-obsolete-variable-alias 'isearch-lazy-highlight-initial-delay
+                                'lazy-highlight-initial-delay
                                 "22.1")
 
 (defcustom lazy-highlight-initial-delay 0.25
   "Seconds to wait before beginning to lazily highlight all matches."
   :type 'number
   :group 'lazy-highlight)
-(define-obsolete-variable-alias 'isearch-lazy-highlight-initial-delay
-                                'lazy-highlight-initial-delay
+
+(define-obsolete-variable-alias 'isearch-lazy-highlight-interval
+                                'lazy-highlight-interval
                                 "22.1")
 
 (defcustom lazy-highlight-interval 0 ; 0.0625
   "Seconds between lazily highlighting successive matches."
   :type 'number
   :group 'lazy-highlight)
-(define-obsolete-variable-alias 'isearch-lazy-highlight-interval
-                                'lazy-highlight-interval
+
+(define-obsolete-variable-alias 'isearch-lazy-highlight-max-at-a-time
+                                'lazy-highlight-max-at-a-time
                                 "22.1")
 
 (defcustom lazy-highlight-max-at-a-time 20
@@ -309,9 +314,6 @@ A value of nil means highlight all matches."
   :type '(choice (const :tag "All" nil)
                 (integer :tag "Some"))
   :group 'lazy-highlight)
-(define-obsolete-variable-alias 'isearch-lazy-highlight-max-at-a-time
-                                'lazy-highlight-max-at-a-time
-                                "22.1")
 
 (defface lazy-highlight
   '((((class color) (min-colors 88) (background light))
@@ -327,10 +329,10 @@ A value of nil means highlight all matches."
   :group 'lazy-highlight
   :group 'basic-faces)
 (define-obsolete-face-alias 'isearch-lazy-highlight-face 'lazy-highlight "22.1")
-(defvar lazy-highlight-face 'lazy-highlight)
 (define-obsolete-variable-alias 'isearch-lazy-highlight-face
                                 'lazy-highlight-face
                                 "22.1")
+(defvar lazy-highlight-face 'lazy-highlight)
 \f
 ;; Define isearch help map.
 
@@ -462,7 +464,8 @@ This is like `describe-bindings', but displays only Isearch keys."
     (define-key map    "\C-w" 'isearch-yank-word-or-char)
     (define-key map "\M-\C-w" 'isearch-del-char)
     (define-key map "\M-\C-y" 'isearch-yank-char)
-    (define-key map    "\C-y" 'isearch-yank-line)
+    (define-key map    "\C-y" 'isearch-yank-kill)
+    (define-key map "\M-s\C-e" 'isearch-yank-line)
 
     (define-key map (char-to-string help-char) isearch-help-map)
     (define-key map [help] isearch-help-map)
@@ -470,7 +473,7 @@ This is like `describe-bindings', but displays only Isearch keys."
 
     (define-key map "\M-n" 'isearch-ring-advance)
     (define-key map "\M-p" 'isearch-ring-retreat)
-    (define-key map "\M-y" 'isearch-yank-kill)
+    (define-key map "\M-y" 'isearch-yank-pop)
 
     (define-key map "\M-\t" 'isearch-complete)
 
@@ -634,6 +637,8 @@ Type \\[isearch-yank-char] to yank char from buffer onto end of search\
 Type \\[isearch-yank-line] to yank rest of line onto end of search string\
  and search for it.
 Type \\[isearch-yank-kill] to yank the last string of killed text.
+Type \\[isearch-yank-pop] to replace string just yanked into search prompt
+ with string killed before it.
 Type \\[isearch-quote-char] to quote control character to search for it.
 \\[isearch-abort] while searching or when search has failed cancels input\
  back to what has
@@ -1055,6 +1060,23 @@ nonincremental search instead via `isearch-edit-string'."
   (isearch-done)
   (isearch-clean-overlays))
 
+(defvar minibuffer-history-symbol) ;; from external package gmhist.el
+
+(defun isearch-fail-pos ()
+  "Position of first mismatch in search string, or its length if none."
+  (let ((cmds isearch-cmds))
+    (if (and isearch-success (not isearch-error))
+        (length isearch-message)
+      (while (or (not (isearch-success-state (car cmds)))
+                 (isearch-error-state (car cmds)))
+        (pop cmds))
+      (let ((succ-msg (and cmds (isearch-message-state (car cmds)))))
+        (if (and (stringp succ-msg)
+                 (< (length succ-msg) (length isearch-message))
+                 (equal succ-msg
+                        (substring isearch-message 0 (length succ-msg))))
+            (length succ-msg)
+          0)))))
 
 (defun isearch-edit-string ()
   "Edit the search string in the minibuffer.
@@ -1074,7 +1096,7 @@ If first char entered is \\[isearch-yank-word-or-char], then do word search inst
   ;; this could be simplified greatly.
   ;; Editing doesn't back up the search point.  Should it?
   (interactive)
-  (condition-case err
+  (condition-case nil
       (progn
        (let ((isearch-nonincremental isearch-nonincremental)
 
@@ -1119,7 +1141,7 @@ If first char entered is \\[isearch-yank-word-or-char], then do word search inst
          ;; Actually terminate isearching until editing is done.
          ;; This is so that the user can do anything without failure,
          ;; like switch buffers and start another isearch, and return.
-         (condition-case err
+         (condition-case nil
              (isearch-done t t)
            (exit nil))                 ; was recursive editing
 
@@ -1135,7 +1157,7 @@ If first char entered is \\[isearch-yank-word-or-char], then do word search inst
                (setq isearch-new-string
                       (read-from-minibuffer
                        (isearch-message-prefix nil nil isearch-nonincremental)
-                       isearch-string
+                        (cons isearch-string (1+ (isearch-fail-pos)))
                        minibuffer-local-isearch-map nil
                        (if isearch-regexp
                           (cons 'regexp-search-ring
@@ -1240,9 +1262,9 @@ Use `isearch-exit' to quit without signaling."
   (interactive)
 ;;  (ding)  signal instead below, if quitting
   (discard-input)
-  (if isearch-success
-      ;; If search is successful, move back to starting point
-      ;; and really do quit.
+  (if (and isearch-success (not isearch-error))
+      ;; If search is successful and has no incomplete regexp,
+      ;; move back to starting point and really do quit.
       (progn
         (setq isearch-success nil)
         (isearch-cancel))
@@ -1493,6 +1515,18 @@ If search string is empty, just beep."
   (interactive)
   (isearch-yank-string (current-kill 0)))
 
+(defun isearch-yank-pop ()
+  "Replace just-yanked search string with previously killed string."
+  (interactive)
+  (if (not (memq last-command '(isearch-yank-kill isearch-yank-pop)))
+      ;; Fall back on `isearch-yank-kill' for the benefits of people
+      ;; who are used to the old behavior of `M-y' in isearch mode. In
+      ;; future, this fallback may be changed if we ever change
+      ;; `yank-pop' to do something like the kill-ring-browser.
+      (isearch-yank-kill)
+    (isearch-pop-state)
+    (isearch-yank-string (current-kill 1))))
+
 (defun isearch-yank-x-selection ()
   "Pull current X selection into search string."
   (interactive)
@@ -1990,12 +2024,6 @@ Isearch mode."
           (setq char (unibyte-char-to-multibyte char)))
       (isearch-process-search-char char))))
 
-(defun isearch-return-char ()
-  "Convert return into newline for incremental search."
-  (interactive)
-  (isearch-process-search-char ?\n))
-(make-obsolete 'isearch-return-char 'isearch-printing-char "19.7")
-
 (defun isearch-printing-char ()
   "Add this ordinary printing character to the search string and search."
   (interactive)
@@ -2154,7 +2182,7 @@ If there is no completion possible, say so and continue searching."
             (isearch-message-suffix c-q-hack ellipsis)))
     (if c-q-hack m (let ((message-log-max nil)) (message "%s" m)))))
 
-(defun isearch-message-prefix (&optional c-q-hack ellipsis nonincremental)
+(defun isearch-message-prefix (&optional _c-q-hack ellipsis nonincremental)
   ;; If about to search, and previous search regexp was invalid,
   ;; check that it still is.  If it is valid now,
   ;; let the message we display while searching say that it is valid.
@@ -2187,7 +2215,7 @@ If there is no completion possible, say so and continue searching."
     (propertize (concat (upcase (substring m 0 1)) (substring m 1))
                'face 'minibuffer-prompt)))
 
-(defun isearch-message-suffix (&optional c-q-hack ellipsis)
+(defun isearch-message-suffix (&optional c-q-hack _ellipsis)
   (concat (if c-q-hack "^Q" "")
          (if isearch-error
              (concat " [" isearch-error "]")
@@ -2422,14 +2450,8 @@ update the match data, and return point."
        ;; If the following character is currently invisible,
        ;; skip all characters with that same `invisible' property value.
        ;; Do that over and over.
-       (while (and (< (point) end)
-                   (let ((prop
-                          (get-char-property (point) 'invisible)))
-                     (if (eq buffer-invisibility-spec t)
-                         prop
-                       (or (memq prop buffer-invisibility-spec)
-                           (assq prop buffer-invisibility-spec)))))
-         (if (get-text-property (point) 'invisible)
+       (while (and (< (point) end) (invisible-p (point)))
+         (if (invisible-p (get-text-property (point) 'invisible))
              (progn
                (goto-char (next-single-property-change (point) 'invisible
                                                        nil end))
@@ -2444,10 +2466,7 @@ update the match data, and return point."
                (while overlays
                  (setq o (car overlays)
                        invis-prop (overlay-get o 'invisible))
-                 (if (if (eq buffer-invisibility-spec t)
-                         invis-prop
-                       (or (memq invis-prop buffer-invisibility-spec)
-                           (assq invis-prop buffer-invisibility-spec)))
+                 (if (invisible-p invis-prop)
                      (if (overlay-get o 'isearch-open-invisible)
                          (setq ov-list (cons o ov-list))
                        ;; We found one overlay that cannot be
@@ -2537,7 +2556,7 @@ since they have special meaning in a regexp."
        (setq isearch-overlay (make-overlay beg end))
        ;; 1001 is higher than lazy's 1000 and ediff's 100+
        (overlay-put isearch-overlay 'priority 1001)
-       (overlay-put isearch-overlay 'face isearch))))
+       (overlay-put isearch-overlay 'face isearch-face))))
 
 (defun isearch-dehighlight ()
   (when isearch-overlay
@@ -2583,6 +2602,7 @@ since they have special meaning in a regexp."
 (defvar isearch-lazy-highlight-regexp nil)
 (defvar isearch-lazy-highlight-space-regexp nil)
 (defvar isearch-lazy-highlight-forward nil)
+(defvar isearch-lazy-highlight-error nil)
 
 (defun lazy-highlight-cleanup (&optional force)
   "Stop lazy highlighting and remove extra highlighting from current buffer.
@@ -2624,9 +2644,13 @@ by other Emacs features."
                  (not (= (window-end)   ; Window may have been split/joined.
                         isearch-lazy-highlight-window-end))
                 (not (eq isearch-forward
-                         isearch-lazy-highlight-forward))))
+                         isearch-lazy-highlight-forward))
+                ;; In case we are recovering from an error.
+                (not (equal isearch-error
+                            isearch-lazy-highlight-error))))
     ;; something important did indeed change
     (lazy-highlight-cleanup t) ;kill old loop & remove overlays
+    (setq isearch-lazy-highlight-error isearch-error)
     (when (not isearch-error)
       (setq isearch-lazy-highlight-start-limit beg
            isearch-lazy-highlight-end-limit end)
@@ -2764,5 +2788,4 @@ CASE-FOLD non-nil means the search was case-insensitive."
   (isearch-search)
   (isearch-update))
 
-;; arch-tag: 74850515-f7d8-43a6-8a2c-ca90a4c1e675
 ;;; isearch.el ends here