Merge changes made in Gnus trunk.
[bpt/emacs.git] / lisp / isearch.el
index ebe2e8f..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
@@ -466,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)
@@ -474,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)
 
@@ -638,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
@@ -1059,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.
@@ -1078,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)
 
@@ -1123,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
 
@@ -1139,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
@@ -1244,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))
@@ -1497,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)
@@ -2152,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.
@@ -2185,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 "]")
@@ -2420,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))
@@ -2442,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
@@ -2581,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.
@@ -2622,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)
@@ -2762,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