]> code.delx.au - gnu-emacs/blobdiff - lisp/isearch.el
*** empty log message ***
[gnu-emacs] / lisp / isearch.el
index b8103285aecbed9f8d3398b81bf8d0186b348c29..91a2c34870dab107206437d1f1f0bf2a9c0feedd 100644 (file)
@@ -1,6 +1,6 @@
 ;;; isearch.el --- incremental search minor mode
 
-;; Copyright (C) 1992, 93, 94, 95, 96, 97, 1999, 2000, 2001
+;; Copyright (C) 1992, 93, 94, 95, 96, 97, 1999, 2000, 01, 2003, 2004
 ;;   Free Software Foundation, Inc.
 
 ;; Author: Daniel LaLiberte <liberte@cs.uiuc.edu>
@@ -75,7 +75,7 @@
 ;; Added word search option to isearch-edit-string.
 ;; Renamed isearch-quit to isearch-abort.
 ;; Numerous changes to comments and doc strings.
-;; 
+;;
 ;; Revision 1.3  92/06/29  13:10:08  liberte
 ;; Moved modal isearch-mode handling into isearch-mode.
 ;; Got rid of buffer-local isearch variables.
@@ -151,7 +151,7 @@ string, and RET terminates editing and does a nonincremental search."
   :type 'boolean
   :group 'isearch)
 
-(defcustom search-whitespace-regexp "\\s-+"
+(defcustom search-whitespace-regexp "\\(?:\\s-+\\)"
   "*If non-nil, regular expression to match a sequence of whitespace chars.
 This applies to regular expression incremental search.
 You might want to use something like \"[ \\t\\r\\n]+\" instead.
@@ -184,8 +184,8 @@ whenever point is in one of them."
 This variable makes a difference when `search-invisible' is set to `open'.
 It means that after search makes some invisible text visible
 to show the match, it makes the text invisible again when the match moves.
-Ordinarily the text becomes invisible again at the end of the search."  
-  :type 'boolean 
+Ordinarily the text becomes invisible again at the end of the search."
+  :type 'boolean
   :group 'isearch)
 
 (defcustom isearch-resume-enabled t
@@ -242,10 +242,11 @@ Default value, nil, means edit the string instead."
       (while l
        (set-char-table-default table (car l) 'isearch-printing-char)
        (setq l (cdr l))))
-    ;; Make function keys, etc, exit the search.
+    ;; Make function keys, etc, which aren't bound to a scrolling-function
+    ;; exit the search.
     (define-key map [t] 'isearch-other-control-char)
     ;; Control chars, by default, end isearch mode transparently.
-    ;; We need these explicit definitions because, in a dense keymap, 
+    ;; We need these explicit definitions because, in a dense keymap,
     ;; the binding for t does not affect characters.
     ;; We use a dense keymap to save space.
     (while (< i ?\ )
@@ -284,7 +285,7 @@ Default value, nil, means edit the string instead."
        (error "Inconsistency in isearch.el"))
     (define-key map "\e\e\e" 'isearch-cancel)
     (define-key map  [escape escape escape] 'isearch-cancel)
-    
+
     (define-key map "\C-q" 'isearch-quote-char)
 
     (define-key map "\r" 'isearch-exit)
@@ -292,7 +293,7 @@ Default value, nil, means edit the string instead."
     (define-key map "\t" 'isearch-printing-char)
     (define-key map " " 'isearch-whitespace-chars)
     (define-key map [?\S-\ ] 'isearch-whitespace-chars)
-    
+
     (define-key map "\C-w" 'isearch-yank-word-or-char)
     (define-key map "\C-y" 'isearch-yank-line)
 
@@ -300,6 +301,7 @@ Default value, nil, means edit the string instead."
     ;; Nothing special for + because it matches at least once.
     (define-key map "*" 'isearch-*-char)
     (define-key map "?" 'isearch-*-char)
+    (define-key map "{" 'isearch-{-char)
     (define-key map "|" 'isearch-|-char)
 
     ;; Turned off because I find I expect to get the global definition--rms.
@@ -444,7 +446,7 @@ Do incremental search forward.
 With a prefix argument, do an incremental regular expression search instead.
 \\<isearch-mode-map>
 As you type characters, they add to the search string and are found.
-The following non-printing keys are bound in `isearch-mode-map'.  
+The following non-printing keys are bound in `isearch-mode-map'.
 
 Type \\[isearch-delete-char] to cancel characters from end of search string.
 Type \\[isearch-exit] to exit, leaving point at location found.
@@ -475,7 +477,7 @@ Type \\[isearch-ring-retreat] to search for the previous item in the search\
 Type \\[isearch-complete] to complete the search string using the search ring.
 
 If an input method is turned on in the current buffer, that input
-method is also active while you are typing characters to search.  To
+method is also active while you are typing characters to search.  To
 toggle the input method, type \\[isearch-toggle-input-method].  It
 also toggles the input method in the current buffer.
 
@@ -483,7 +485,7 @@ To use a different input method for searching, type
 \\[isearch-toggle-specified-input-method], and specify an input method
 you want to use.
 
-The above keys, bound in `isearch-mode-map', are often controlled by 
+The above keys, bound in `isearch-mode-map', are often controlled by
  options; do M-x apropos on search-.* to find them.
 Other control and meta characters terminate the search
  and are then executed normally (depending on `search-exit-option').
@@ -535,7 +537,7 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
 ;;(defvar isearch-commands '(isearch-forward isearch-backward
 ;;                          isearch-forward-regexp isearch-backward-regexp)
 ;;  "List of commands for which isearch-mode does not recursive-edit.")
-                            
+
 
 (defun isearch-mode (forward &optional regexp op-fun recursive-edit word-p)
   "Start isearch minor mode.  Called by `isearch-forward', etc.
@@ -611,8 +613,8 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
   (add-hook 'mouse-leave-buffer-hook 'isearch-done)
   (add-hook 'kbd-macro-termination-hook 'isearch-done)
 
-  ;; isearch-mode can be made modal (in the sense of not returning to 
-  ;; the calling function until searching is completed) by entering 
+  ;; isearch-mode can be made modal (in the sense of not returning to
+  ;; the calling function until searching is completed) by entering
   ;; a recursive-edit and exiting it when done isearching.
   (if recursive-edit
       (let ((isearch-recursive-edit t))
@@ -630,7 +632,7 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
         (if (not (input-pending-p))
             (isearch-message))
         (if (and isearch-slow-terminal-mode
-                 (not (or isearch-small-window 
+                 (not (or isearch-small-window
                           (pos-visible-in-window-p))))
             (let ((found-point (point)))
               (setq isearch-small-window t)
@@ -734,19 +736,18 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
 (defun isearch-update-ring (string &optional regexp)
   "Add STRING to the beginning of the search ring.
 REGEXP says which ring to use."
-  (if regexp 
+  (if regexp
       (if (or (null regexp-search-ring)
              (not (string= string (car regexp-search-ring))))
          (progn
-           (setq regexp-search-ring
-                 (cons string regexp-search-ring))
+           (push string regexp-search-ring)
            (if (> (length regexp-search-ring) regexp-search-ring-max)
                (setcdr (nthcdr (1- search-ring-max) regexp-search-ring)
                        nil))))
     (if (or (null search-ring)
            (not (string= string (car search-ring))))
        (progn
-         (setq search-ring (cons string search-ring))
+         (push string search-ring)
          (if (> (length search-ring) search-ring-max)
              (setcdr (nthcdr (1- search-ring-max) search-ring) nil))))))
 
@@ -768,7 +769,7 @@ However, if this is the first command after starting incremental
 search and `search-nonincremental-instead' is non-nil, do a
 nonincremental search instead via `isearch-edit-string'."
   (interactive)
-  (if (and search-nonincremental-instead 
+  (if (and search-nonincremental-instead
           (= 0 (length isearch-string)))
       (let ((isearch-nonincremental t))
        (isearch-edit-string)))
@@ -840,7 +841,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, 
+         ;; This is so that the user can do anything without failure,
          ;; like switch buffers and start another isearch, and return.
          (condition-case err
              (isearch-done t t)
@@ -848,7 +849,7 @@ If first char entered is \\[isearch-yank-word-or-char], then do word search inst
 
          (isearch-message) ;; for read-char
          (unwind-protect
-             (let* (;; Why does following read-char echo?  
+             (let* (;; Why does following read-char echo?
                     ;;(echo-keystrokes 0) ;; not needed with above message
                     (e (let ((cursor-in-echo-area t))
                          (read-event)))
@@ -882,9 +883,9 @@ If first char entered is \\[isearch-yank-word-or-char], then do word search inst
                      (mapconcat 'isearch-text-char-description
                                 isearch-new-string "")))
            ;; Always resume isearching by restarting it.
-           (isearch-mode isearch-forward 
-                         isearch-regexp 
-                         isearch-op-fun 
+           (isearch-mode isearch-forward
+                         isearch-regexp
+                         isearch-op-fun
                          nil
                          isearch-word)
 
@@ -915,7 +916,7 @@ If first char entered is \\[isearch-yank-word-or-char], then do word search inst
        ;; Reinvoke the pending search.
        (isearch-search)
        (isearch-update)
-       (if isearch-nonincremental 
+       (if isearch-nonincremental
            (progn
              ;; (sit-for 1) ;; needed if isearch-done does: (message "")
              (isearch-done))))
@@ -978,7 +979,7 @@ Use `isearch-exit' to quit without signaling."
                (or (if isearch-regexp
                        (car regexp-search-ring)
                      (car search-ring))
-                   "")
+                   (error "No previous search string"))
                isearch-message
                (mapconcat 'isearch-text-char-description
                           isearch-string "")
@@ -1121,7 +1122,7 @@ might return the position of the end of the line."
   "Pull next character or word from buffer into search string."
   (interactive)
   (isearch-yank-internal
-   (lambda () 
+   (lambda ()
      (if (or (= (char-syntax (or (char-after) 0)) ?w)
              (= (char-syntax (or (char-after (1+ (point))) 0)) ?w))
          (forward-word 1)
@@ -1186,21 +1187,30 @@ might return the position of the end of the line."
   (isearch-update))
 
 
+(defun isearch-{-char ()
+  "Handle \{ specially in regexps."
+  (interactive)
+  (isearch-*-char t))
+
 ;; *, ?, and | chars can make a regexp more liberal.
 ;; They can make a regexp match sooner or make it succeed instead of failing.
 ;; So go back to place last successful search started
 ;; or to the last ^S/^R (barrier), whichever is nearer.
 ;; + needs no special handling because the string must match at least once.
 
-(defun isearch-*-char ()
-  "Handle * and ? specially in regexps."
+(defun isearch-*-char (&optional want-backslash)
+  "Handle * and ? specially in regexps.
+When WANT-BACKSLASH is non-nil, do special handling for \{."
   (interactive)
   (if isearch-regexp
       (let ((idx (length isearch-string)))
        (while (and (> idx 0)
                    (eq (aref isearch-string (1- idx)) ?\\))
          (setq idx (1- idx)))
-       (when (= (mod (- (length isearch-string) idx) 2) 0)
+       ;; * and ? are special when not preceded by \.
+       ;; { is special when it is preceded by \.
+       (when (= (mod (- (length isearch-string) idx) 2)
+                (if want-backslash 1 0))
          (setq isearch-adjusted t)
          ;; Get the isearch-other-end from before the last search.
          ;; We want to start from there,
@@ -1214,7 +1224,7 @@ might return the position of the end of the line."
                 (max cs isearch-barrier)
               (min cs isearch-barrier)))))))
   (isearch-process-search-char last-command-char))
-  
+
 
 (defun isearch-|-char ()
   "If in regexp search, jump to the barrier."
@@ -1225,18 +1235,176 @@ might return the position of the end of the line."
        (goto-char isearch-barrier)))
   (isearch-process-search-char last-command-char))
 
+(defun isearch-unread-key-sequence (keylist)
+  "Unread the given key-sequence KEYLIST.
+Scroll-bar or mode-line events are processed appropriately."
+  (cancel-kbd-macro-events)
+  (apply 'isearch-unread keylist)
+  ;; If the event was a scroll-bar or mode-line click, the event will have
+  ;; been prefixed by a symbol such as vertical-scroll-bar.  We must remove
+  ;; it here, because this symbol will be attached to the event again next
+  ;; time it gets read by read-key-sequence.
+  ;;
+  ;; (Old comment from isearch-other-meta-char: "Note that we don't have to
+  ;; modify the event anymore in 21 because read_key_sequence no longer
+  ;; modifies events to produce fake prefix keys.")
+  (if (and (> (length keylist) 1)
+           (symbolp (car keylist))
+           (listp (cadr keylist))
+           (not (numberp (posn-point
+                          (event-start (cadr keylist)  )))))
+      (pop unread-command-events)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; scrolling within Isearch mode.  Alan Mackenzie (acm@muc.de), 2003/2/24
+;;
+;; The idea here is that certain vertical scrolling commands (like C-l
+;; `recenter') should be usable WITHIN Isearch mode.  For a command to be
+;; suitable, it must NOT alter the buffer, swap to another buffer or frame,
+;; tamper with isearch's state, or move point.  It is unacceptable for the
+;; search string to be scrolled out of the current window.  If a command
+;; attempts this, we scroll the text back again.
+;;
+;; We implement this feature with a property called `isearch-scroll'.
+;; If a command's symbol has the value t for this property it is a
+;; scrolling command.  The feature needs to be enabled by setting the
+;; customizable variable `isearch-allow-scroll' to a non-nil value.
+;;
+;; The universal argument commands (e.g. C-u) in simple.el are marked
+;; as scrolling commands, and isearch.el has been amended to allow
+;; prefix arguments to be passed through to scrolling commands.  Thus
+;; M-0 C-l will scroll point to the top of the window.
+;;
+;; Horizontal scrolling commands are currently not catered for.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Set the isearch-scroll property on some standard functions:
+;; Scroll-bar functions:
+(if (fboundp 'scroll-bar-toolkit-scroll)
+    (put 'scroll-bar-toolkit-scroll 'isearch-scroll t))
+(if (fboundp 'mac-handle-scroll-bar-event)
+    (put 'mac-handle-scroll-bar-event 'isearch-scroll t))
+(if (fboundp 'w32-handle-scroll-bar-event)
+    (put 'w32-handle-scroll-bar-event 'isearch-scroll t))
+
+;; Commands which scroll the window:
+(put 'recenter 'isearch-scroll t)
+(put 'reposition-window 'isearch-scroll t)
+(put 'scroll-up 'isearch-scroll t)
+(put 'scroll-down 'isearch-scroll t)
+
+;; Commands which act on the other window
+(put 'list-buffers 'isearch-scroll t)
+(put 'scroll-other-window 'isearch-scroll t)
+(put 'scroll-other-window-down 'isearch-scroll t)
+(put 'beginning-of-buffer-other-window 'isearch-scroll t)
+(put 'end-of-buffer-other-window 'isearch-scroll t)
+
+;; Commands which change the window layout
+(put 'delete-other-windows 'isearch-scroll t)
+(put 'balance-windows 'isearch-scroll t)
+(put 'split-window-vertically 'isearch-scroll t)
+(put 'enlarge-window 'isearch-scroll t)
+
+;; Universal argument commands
+(put 'universal-argument 'isearch-scroll t)
+(put 'negative-argument 'isearch-scroll t)
+(put 'digit-argument 'isearch-scroll t)
+
+(defcustom isearch-allow-scroll nil
+  "If non-nil, scrolling commands are allowed during incremental search."
+  :type 'boolean
+  :group 'isearch)
+
+(defun isearch-string-out-of-window (isearch-point)
+  "Test whether the search string is currently outside of the window.
+Return nil if it's completely visible, or if point is visible,
+together with as much of the search string as will fit; the symbol
+`above' if we need to scroll the text downwards; the symbol `below',
+if upwards."
+  (let ((w-start (window-start))
+        (w-end (window-end nil t))
+        (w-L1 (save-excursion (move-to-window-line 1) (point)))
+        (w-L-1 (save-excursion (move-to-window-line -1) (point)))
+        start end)                  ; start and end of search string in buffer
+    (if isearch-forward
+        (setq end isearch-point  start (or isearch-other-end isearch-point))
+      (setq start isearch-point  end (or isearch-other-end isearch-point)))
+    (cond ((or (and (>= start w-start) (<= end w-end))
+               (if isearch-forward
+                   (and (>= isearch-point w-L-1) (< isearch-point w-end)) ; point on Line -1
+                 (and (>= isearch-point w-start) (< isearch-point w-L1)))) ; point on Line 0
+           nil)
+          ((and (< start w-start)
+                (< isearch-point w-L-1))
+           'above)
+          (t 'below))))
+
+(defun isearch-back-into-window (above isearch-point)
+  "Scroll the window to bring the search string back into view.
+Restore point to ISEARCH-POINT in the process.  ABOVE is t when the
+search string is above the top of the window, nil when it is beneath
+the bottom."
+  (let (start end)
+    (if isearch-forward
+        (setq end isearch-point  start (or isearch-other-end isearch-point))
+      (setq start isearch-point  end (or isearch-other-end isearch-point)))
+    (if above
+        (progn
+          (goto-char start)
+          (recenter 0)
+          (when (>= isearch-point (window-end nil t))
+            (goto-char isearch-point)
+            (recenter -1)))
+      (goto-char end)
+      (recenter -1)
+      (when (< isearch-point (window-start))
+        (goto-char isearch-point)
+        (recenter 0))))
+  (goto-char isearch-point))
+
+(defun isearch-reread-key-sequence-naturally (keylist)
+  "Reread key sequence KEYLIST with Isearch mode's keymap deactivated.
+Return the key sequence as a string/vector."
+  (isearch-unread-key-sequence keylist)
+  (let (overriding-terminal-local-map)
+    (read-key-sequence nil)))  ; This will go through function-key-map, if nec.
+
+(defun isearch-lookup-scroll-key (key-seq)
+  "If KEY-SEQ is bound to a scrolling command, return it as a symbol.
+Otherwise return nil."
+  (let* ((overriding-terminal-local-map nil)
+         (binding (key-binding key-seq)))
+    (and binding (symbolp binding) (commandp binding)
+         (eq (get binding 'isearch-scroll) t)
+         binding)))
 
 (defalias 'isearch-other-control-char 'isearch-other-meta-char)
 
-(defun isearch-other-meta-char ()
-  "Exit the search normally and reread this key sequence.
-But only if `search-exit-option' is non-nil, the default.
-If it is the symbol `edit', the search string is edited in the minibuffer
-and the meta character is unread so that it applies to editing the string."
-  (interactive)
-  (let* ((key (this-command-keys))
+(defun isearch-other-meta-char (&optional arg)
+  "Process a miscellaneous key sequence in Isearch mode.
+
+Try to convert the current key-sequence to something usable in Isearch
+mode, either by converting it with `function-key-map', downcasing a
+key with C-<upper case>, or finding a \"scrolling command\" bound to
+it.  \(In the last case, we may have to read more events.)  If so,
+either unread the converted sequence or execute the command.
+
+Otherwise, if `search-exit-option' is non-nil (the default) unread the
+key-sequence and exit the search normally.  If it is the symbol
+`edit', the search string is edited in the minibuffer and the meta
+character is unread so that it applies to editing the string.
+
+ARG is the prefix argument.  It will be transmitted through to the
+scrolling command or to the command whose key-sequence exits
+Isearch mode."
+  (interactive "P")
+  (let* ((key (if current-prefix-arg    ; not nec the same as ARG
+                  (substring (this-command-keys) universal-argument-num-events)
+                (this-command-keys)))
         (main-event (aref key 0))
-        (keylist (listify-key-sequence key)))
+        (keylist (listify-key-sequence key))
+         scroll-command isearch-point)
     (cond ((and (= (length key) 1)
                (let ((lookup (lookup-key function-key-map key)))
                  (not (or (null lookup) (integerp lookup)
@@ -1288,23 +1456,27 @@ and the meta character is unread so that it applies to editing the string."
          ((eq search-exit-option 'edit)
           (apply 'isearch-unread keylist)
           (isearch-edit-string))
+          ;; Handle a scrolling function.
+          ((and isearch-allow-scroll
+                (progn (setq key (isearch-reread-key-sequence-naturally keylist))
+                       (setq keylist (listify-key-sequence key))
+                       (setq main-event (aref key 0))
+                       (setq scroll-command (isearch-lookup-scroll-key key))))
+           ;; From this point onwards, KEY, KEYLIST and MAIN-EVENT hold a
+           ;; complete key sequence, possibly as modified by function-key-map,
+           ;; not merely the one or two event fragment which invoked
+           ;; isearch-other-meta-char in the first place.
+           (setq isearch-point (point))
+           (setq prefix-arg arg)
+           (command-execute scroll-command)
+           (let ((ab-bel (isearch-string-out-of-window isearch-point)))
+             (if ab-bel
+                 (isearch-back-into-window (eq ab-bel 'above) isearch-point)))
+           (isearch-update))
          (search-exit-option
           (let (window)
-            (cancel-kbd-macro-events)
-            (apply 'isearch-unread keylist)
-
-            ;; Properly handle scroll-bar and mode-line clicks for
-            ;; which a dummy prefix event was generated as (aref key
-            ;; 0).  Note that we don't have to modify the event
-            ;; anymore in 21 because read_key_sequence no longer modifies
-            ;; events to produce fake prefix keys.
-            (when (and (> (length key) 1)
-                       (symbolp (aref key 0))
-                       (listp (aref key 1))
-                       (not (numberp (posn-point
-                                      (event-start (aref key 1))))))
-              (pop unread-command-events)
-              (setq main-event (car unread-command-events)))
+             (isearch-unread-key-sequence keylist)
+             (setq main-event (car unread-command-events))
 
             ;; If we got a mouse click event, that event contains the
             ;; window clicked on. maybe it was read with the buffer
@@ -1315,7 +1487,7 @@ and the meta character is unread so that it applies to editing the string."
             ;; obviously wrong for the case that a down-mouse event
             ;; on another window invokes this function.  The event
             ;; will contain the window clicked on and that window's
-            ;; buffer is certainaly not always in Isearch mode.
+            ;; buffer is certainly not always in Isearch mode.
             ;;
             ;; Leave the code in, but check for current buffer not
             ;; being in Isearch mode for now, until someone tells
@@ -1334,8 +1506,9 @@ and the meta character is unread so that it applies to editing the string."
                   (isearch-done)
                   (isearch-clean-overlays))
               (isearch-done)
-              (isearch-clean-overlays))))
-         (t;; otherwise nil
+              (isearch-clean-overlays)
+               (setq prefix-arg arg))))
+          (t;; otherwise nil
           (isearch-process-search-string key key)))))
 
 (defun isearch-quote-char ()
@@ -1377,7 +1550,7 @@ Obsolete."
   "Match all whitespace chars, if in regexp mode.
 If you want to search for just a space, type \\<isearch-mode-map>\\[isearch-quote-char] SPC."
   (interactive)
-  (if isearch-regexp 
+  (if isearch-regexp
       (if (and search-whitespace-regexp (not isearch-within-brackets)
               (not isearch-invalid-regexp))
          (isearch-process-search-string search-whitespace-regexp " ")
@@ -1493,9 +1666,8 @@ With prefix arg N, insert the Nth element."
   ;; Helper for isearch-complete and isearch-complete-edit
   ;; Return t if completion OK, nil if no completion exists.
   (let* ((ring (if isearch-regexp regexp-search-ring search-ring))
-         (alist (mapcar (function (lambda (string) (list string))) ring))
          (completion-ignore-case case-fold-search)
-         (completion (try-completion isearch-string alist)))
+         (completion (try-completion isearch-string ring)))
     (cond
      ((eq completion t)
       ;; isearch-string stays the same
@@ -1506,8 +1678,8 @@ With prefix arg N, insert the Nth element."
          (progn
            (if completion-auto-help
                (with-output-to-temp-buffer "*Isearch completions*"
-                 (display-completion-list 
-                  (all-completions isearch-string alist))))
+                 (display-completion-list
+                  (all-completions isearch-string ring))))
            t)
        (and completion
             (setq isearch-string completion))))
@@ -1521,7 +1693,10 @@ The completed string is then editable in the minibuffer.
 If there is no completion possible, say so and continue searching."
   (interactive)
   (if (isearch-complete1)
-      (isearch-edit-string)
+      (progn (setq isearch-message
+                  (mapconcat 'isearch-text-char-description
+                             isearch-string ""))
+            (isearch-edit-string))
     ;; else
     (sit-for 1)
     (isearch-update)))
@@ -1529,7 +1704,7 @@ If there is no completion possible, say so and continue searching."
 (defun isearch-complete-edit ()
   "Same as `isearch-complete' except in the minibuffer."
   (interactive)
-  (setq isearch-string (buffer-string))
+  (setq isearch-string (field-string))
   (if (isearch-complete1)
       (progn
        (delete-field)
@@ -1559,9 +1734,9 @@ If there is no completion possible, say so and continue searching."
   (isearch-top-state))
 
 (defun isearch-push-state ()
-  (setq isearch-cmds 
+  (setq isearch-cmds
        (cons (list isearch-string isearch-message (point)
-                   isearch-success isearch-forward isearch-other-end 
+                   isearch-success isearch-forward isearch-other-end
                    isearch-word
                    isearch-invalid-regexp isearch-wrapped isearch-barrier
                    isearch-within-brackets isearch-case-fold-search)
@@ -1694,7 +1869,7 @@ Can be changed via `isearch-search-fun-function' for special needs."
 
 ;; Called when opening an overlay, and we are still in isearch.
 (defun isearch-open-overlay-temporary (ov)
-  (if (not (null (overlay-get ov 'isearch-open-invisible-temporary))) 
+  (if (not (null (overlay-get ov 'isearch-open-invisible-temporary)))
       ;; Some modes would want to open the overlays temporary during
       ;; isearch in their own way, they should set the
       ;; `isearch-open-invisible-temporary' to a function doing this.
@@ -1865,7 +2040,7 @@ Can be changed via `isearch-search-fun-function' for special needs."
   "Return t if there are no upper case chars in STRING.
 If REGEXP-FLAG is non-nil, disregard letters preceded by `\\' (but not `\\\\')
 since they have special meaning in a regexp."
-  (let (quote-flag (i 0) (len (length string)) found) 
+  (let (quote-flag (i 0) (len (length string)) found)
     (while (and (not found) (< i len))
       (let ((char (aref string i)))
        (if (and regexp-flag (eq char ?\\))
@@ -1963,26 +2138,30 @@ A value of nil means highlight all matches."
   :group 'isearch)
 
 (defface isearch
-  '((((type tty pc) (class color))
-     (:background "magenta4" :foreground "cyan1"))
-    (((class color) (background light))
+  '((((class color) (min-colors 88) (background light))
      ;; The background must not be too dark, for that means
      ;; the character is hard to see when the cursor is there.
      (:background "magenta2" :foreground "lightskyblue1"))
-    (((class color) (background dark))
+    (((class color) (min-colors 88) (background dark))
      (:background "palevioletred2" :foreground "brown4"))
+    (((class color) (min-colors 16))
+     (:background "magenta4" :foreground "cyan1"))
+    (((class color) (min-colors 8))
+     (:background "magenta4" :foreground "cyan1"))
     (t (:inverse-video t)))
   "Face for highlighting Isearch matches."
   :group 'isearch-faces)
 (defvar isearch 'isearch)
 
 (defface isearch-lazy-highlight-face
-  '((((type tty pc) (class color))
-     (:background "turquoise3"))
-    (((class color) (background light))
+  '((((class color) (min-colors 88) (background light))
      (:background "paleturquoise"))
-    (((class color) (background dark))
+    (((class color) (min-colors 88) (background dark))
      (:background "paleturquoise4"))
+    (((class color) (min-colors 16))
+     (:background "turquoise3"))
+    (((class color) (min-colors 8))
+     (:background "turquoise3"))
     (t (:underline t)))
   "Face for lazy highlighting of Isearch matches other than the current one."
   :group 'isearch-faces)
@@ -1996,6 +2175,7 @@ A value of nil means highlight all matches."
 (defvar isearch-lazy-highlight-last-string nil)
 (defvar isearch-lazy-highlight-window nil)
 (defvar isearch-lazy-highlight-window-start nil)
+(defvar isearch-lazy-highlight-window-end nil)
 (defvar isearch-lazy-highlight-case-fold-search nil)
 (defvar isearch-lazy-highlight-regexp nil)
 
@@ -2030,12 +2210,15 @@ search string to change or the window to scroll)."
                 (not (eq isearch-lazy-highlight-regexp
                          isearch-regexp))
                  (not (= (window-start)
-                         isearch-lazy-highlight-window-start))))
+                         isearch-lazy-highlight-window-start))
+                 (not (= (window-end)   ; Window may have been split/joined.
+                         isearch-lazy-highlight-window-end))))
     ;; something important did indeed change
     (isearch-lazy-highlight-cleanup t) ;kill old loop & remove overlays
     (when (not isearch-invalid-regexp)
       (setq isearch-lazy-highlight-window       (selected-window)
             isearch-lazy-highlight-window-start (window-start)
+            isearch-lazy-highlight-window-end   (window-end)
             isearch-lazy-highlight-start        (point)
             isearch-lazy-highlight-end          (point)
             isearch-lazy-highlight-last-string  isearch-string
@@ -2123,4 +2306,5 @@ CASE-FOLD non-nil means the search was case-insensitive."
        isearch-case-fold-search case-fold)
   (isearch-search))
 
+;;; arch-tag: 74850515-f7d8-43a6-8a2c-ca90a4c1e675
 ;;; isearch.el ends here