(imenu-update-menubar): New function.
[bpt/emacs.git] / lisp / isearch.el
index 11f829c..bbcc08b 100644 (file)
@@ -1,27 +1,25 @@
 ;;; isearch.el --- incremental search minor mode.
 
-;; Copyright (C) 1992, 1993 Free Software Foundation, Inc.
+;; Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
 
 ;; Author: Daniel LaLiberte <liberte@cs.uiuc.edu>
-
-;; |$Date: 1994/01/16 23:40:50 $|$Revision: 1.62 $
+;; Maintainer: FSF
 
 ;; This file is part of GNU Emacs.
 
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
 ;; GNU Emacs is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY.  No author or distributor
-;; accepts responsibility to anyone for the consequences of using it
-;; or for whether it serves any particular purpose or works at all,
-;; unless he says so in writing.  Refer to the GNU Emacs General Public
-;; License for full details.
-
-;; Everyone is granted permission to copy, modify and redistribute
-;; GNU Emacs, but only under the conditions described in the
-;; GNU Emacs General Public License.   A copy of this license is
-;; supposed to have been given to you along with GNU Emacs so you
-;; can know your rights and responsibilities.  It should be in a
-;; file named COPYING.  Among other things, the copyright notice
-;; and this notice must be preserved on all copies.
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
 ;;; Commentary:
 
 ;;; Code:
 
 \f
-;;;=========================================================================
-;;; Emacs features
-
-;; isearch-mode takes advantage of the features provided by several
-;; different versions of emacs.  Rather than testing the version of
-;; emacs, several constants are defined, one for each of the features.
-;; Each of the tests below must work on any version of emacs.
-;; (Perhaps provide and featurep could be used for this purpose.)
-
-(defconst isearch-gnu-emacs-events (fboundp 'set-frame-height)) ;; emacs 19
-(defconst isearch-pre-command-hook-exists (boundp 'pre-command-hook)) ;; lemacs
-(defconst isearch-event-data-type nil)  ;; lemacs
+;;;========================================================================
+;;; Some additional options and constants.
 
 (defconst search-exit-option t
   "*Non-nil means random control characters terminate incremental search.")
@@ -132,9 +120,6 @@ and the value is minus the number of lines.")
 This is the style where a one-line window is created to show the line
 that the search has reached.")
 
-;;;========================================================================
-;;; Some additional options and constants.
-
 (defvar search-upper-case 'not-yanks
   "*If non-nil, upper case chars disable case fold searching.
 That is, upper and lower case chars must match exactly.
@@ -151,9 +136,6 @@ string, and RET terminates editing and does a nonincremental search.")
   "*If non-nil, regular expression to match a sequence of whitespace chars.
 You might want to use something like \"[ \\t\\r\\n]+\" instead.")
 
-;; I removed the * from the doc string because highlighting is not 
-;; currently a clean thing to do.  Once highlighting is made clean, 
-;; this feature can be re-enabled and advertised.
 (defvar search-highlight nil
   "*Non-nil means incremental search highlights the current match.")
 
@@ -218,11 +200,26 @@ Default value, nil, means edit the string instead.")
        (define-key map (vector i) 'isearch-printing-char)
        (setq i (1+ i)))
 
+      ;; To handle local bindings with meta char prefix keys, define
+      ;; another full keymap.  This must be done for any other prefix
+      ;; keys as well, one full keymap per char of the prefix key.  It
+      ;; would be simpler to disable the global keymap, and/or have a
+      ;; default local key binding for any key not otherwise bound.
+      (let ((meta-map (make-sparse-keymap)))
+       (define-key map (char-to-string meta-prefix-char) meta-map)
+       (define-key map [escape] meta-map))
+      (define-key map (vector meta-prefix-char t) 'isearch-other-meta-char)
+
       ;; Several non-printing chars change the searching behavior.
       (define-key map "\C-s" 'isearch-repeat-forward)
       (define-key map "\C-r" 'isearch-repeat-backward)
       (define-key map "\177" 'isearch-delete-char)
       (define-key map "\C-g" 'isearch-abort)
+      ;; This assumes \e is the meta-prefix-char.
+      (or (= ?\e meta-prefix-char)
+         (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)
 
@@ -233,39 +230,6 @@ Default value, nil, means edit the string instead.")
     
       (define-key map "\C-w" 'isearch-yank-word)
       (define-key map "\C-y" 'isearch-yank-line)
-      (define-key map [mouse-2] 'isearch-yank-kill)
-      ;; This overrides the default binding for t.
-      (define-key map [down-mouse-2] 'nil)
-
-      ;; Bind the ASCII-equivalent "function keys" explicitly
-      ;; if we bind their equivalents, 
-      ;; since otherwise the default binding would override.
-      ;; We bind [escape] below.
-      (define-key map [tab] 'isearch-printing-char)
-      (define-key map [kp-0] 'isearch-printing-char)
-      (define-key map [kp-1] 'isearch-printing-char)
-      (define-key map [kp-2] 'isearch-printing-char)
-      (define-key map [kp-3] 'isearch-printing-char)
-      (define-key map [kp-4] 'isearch-printing-char)
-      (define-key map [kp-5] 'isearch-printing-char)
-      (define-key map [kp-6] 'isearch-printing-char)
-      (define-key map [kp-7] 'isearch-printing-char)
-      (define-key map [kp-8] 'isearch-printing-char)
-      (define-key map [kp-9] 'isearch-printing-char)
-      (define-key map [kp-add] 'isearch-printing-char)
-      (define-key map [kp-subtract] 'isearch-printing-char)
-      (define-key map [kp-multiply] 'isearch-printing-char)
-      (define-key map [kp-divide] 'isearch-printing-char)
-      (define-key map [kp-decimal] 'isearch-printing-char)
-      (define-key map [kp-separator] 'isearch-printing-char)
-      (define-key map [kp-equal] 'isearch-printing-char)
-      (define-key map [kp-tab] 'isearch-printing-char)
-      (define-key map [kp-space] 'isearch-printing-char)
-      (define-key map [kp-enter] 'isearch-exit)
-      (define-key map [delete] 'isearch-delete-char)
-      (define-key map [backspace] 'isearch-delete-char)
-      (define-key map [return] 'isearch-exit)
-      (define-key map [newline] 'isearch-printing-char)
 
       ;; Define keys for regexp chars * ? |.
       ;; Nothing special for + because it matches at least once.
@@ -277,31 +241,26 @@ Default value, nil, means edit the string instead.")
 ;;;      ;; Instead bind C-h to special help command for isearch-mode.
 ;;;      (define-key map "\C-h" 'isearch-mode-help)
 
-      ;; To handle local bindings with meta char prefix keys, define
-      ;; another full keymap.  This must be done for any other prefix
-      ;; keys as well, one full keymap per char of the prefix key.  It
-      ;; would be simpler to disable the global keymap, and/or have a
-      ;; default local key binding for any key not otherwise bound.
-      (let ((meta-map (make-sparse-keymap)))
-       (define-key map (char-to-string meta-prefix-char) meta-map)
-       (define-key map [escape] meta-map))
-      (define-key map (vector meta-prefix-char t) 'isearch-other-meta-char)
-
       (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-\t" 'isearch-complete)
 
-      ;; For emacs 19, switching frames should terminate isearch-mode
-      (if isearch-gnu-emacs-events
-         (define-key map [switch-frame] 'isearch-switch-frame-handler))
-      
+      ;; Pass frame events transparently so they won't exit the search.
+      ;; In particular, if we have more than one display open, then a
+      ;; switch-frame might be generated by someone typing at another keyboard.
+      (define-key map [switch-frame] nil)
+      (define-key map [delete-frame] nil)
+      (define-key map [iconify-frame] nil)
+      (define-key map [make-frame-visible] nil)
+
       (setq isearch-mode-map map)
       ))
 
 ;; Some bindings you may want to put in your isearch-mode-hook.
 ;; Suggest some alternates...
+;; (define-key isearch-mode-map "\C-t" 'isearch-toggle-case-fold)
 ;; (define-key isearch-mode-map "\C-t" 'isearch-toggle-regexp)
 ;; (define-key isearch-mode-map "\C-^" 'isearch-edit-string)
 
@@ -340,7 +299,10 @@ Default value, nil, means edit the string instead.")
 (defvar isearch-wrapped nil)   ; Searching restarted from the top (bottom).
 (defvar isearch-barrier 0)
 
-(defvar isearch-case-fold-search nil) ; case-fold-search while searching.
+; case-fold-search while searching.
+;   either nil, t, or 'yes.  'yes means the same as t except that mixed
+;   case in the search string is ignored.
+(defvar isearch-case-fold-search nil)
 
 (defvar isearch-adjusted nil)
 (defvar isearch-slow-terminal-mode nil)
@@ -424,6 +386,7 @@ 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').
+Likewise for function keys and mouse button events.
 
 If this function is called non-interactively, it does not return to
 the calling function until the search is done."
@@ -475,7 +438,9 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
                             
 
 (defun isearch-mode (forward &optional regexp op-fun recursive-edit word-p)
-  "Start isearch minor mode.  Called by isearch-forward, etc."
+  "Start isearch minor mode.  Called by `isearch-forward', etc.
+
+\\{isearch-mode-map}"
 
   ;; Initialize global vars.
   (setq isearch-forward forward
@@ -493,8 +458,7 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
        isearch-yank-flag nil
        isearch-invalid-regexp nil
        isearch-within-brackets nil
-       ;; Use (baud-rate) for now, for sake of other versions.
-       isearch-slow-terminal-mode (and (<= (baud-rate) search-slow-speed)
+       isearch-slow-terminal-mode (and (<= baud-rate search-slow-speed)
                                        (> (window-height)
                                           (* 4 search-slow-window-lines)))
        isearch-other-end nil
@@ -506,31 +470,24 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
   (setq isearch-window-configuration
        (if isearch-slow-terminal-mode (current-window-configuration) nil))
 
-;; This was for Lucid Emacs.  But now that we have pre-command-hook,
-;; it causes trouble.
-;;  (if isearch-pre-command-hook-exists
-;;      (add-hook 'pre-command-hook 'isearch-pre-command-hook))
   (setq        isearch-mode " Isearch")  ;; forward? regexp?
-  (set-buffer-modified-p (buffer-modified-p)) ; update modeline
-
-  ;; It is ugly to show region highlighting while the search
-  ;; is going on.  And we don't want the mark active at the end either.
-  (setq deactivate-mark t)      
+  (force-mode-line-update)
 
   (isearch-push-state)
 
-  (make-local-variable 'overriding-local-map)
-  (setq overriding-local-map isearch-mode-map)
+  (setq overriding-terminal-local-map isearch-mode-map)
   (isearch-update)
   (run-hooks 'isearch-mode-hook)
 
+  (setq mouse-leave-buffer-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 
   ;; a recursive-edit and exiting it when done isearching.
   (if recursive-edit
       (let ((isearch-recursive-edit t))
        (recursive-edit)))
-  )
+  isearch-success)
 
 
 ;;;====================================================
@@ -538,11 +495,7 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
 
 (defun isearch-update ()
   ;; Called after each command to update the display.  
-  (if (if isearch-event-data-type
-         (null unread-command-event)
-       (if isearch-gnu-emacs-events
-           (null unread-command-events)
-         (< unread-command-char 0)))
+  (if (null unread-command-events)
       (progn
        (if (not (input-pending-p))
            (isearch-message))
@@ -576,11 +529,11 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
    isearch-yank-flag nil)
   )
 
-
-(defun isearch-done (&optional nopush)
+(defun isearch-done (&optional nopush edit)
+  (setq mouse-leave-buffer-hook nil)
   ;; Called by all commands that terminate isearch-mode.
   ;; If NOPUSH is non-nil, we don't push the string on the search ring.
-  (setq overriding-local-map nil)
+  (setq overriding-terminal-local-map nil)
   ;; (setq pre-command-hook isearch-old-pre-command-hook) ; for lemacs
   (isearch-dehighlight t)
   (let ((found-start (window-start (selected-window)))
@@ -591,42 +544,45 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
     (if isearch-small-window
        (goto-char found-point)
       ;; Exiting the save-window-excursion clobbers window-start; restore it.
-      (set-window-start (selected-window) found-start t)))
+      (set-window-start (selected-window) found-start t))
 
     ;; If there was movement, mark the starting position.
     ;; Maybe should test difference between and set mark iff > threshold.
     (if (/= (point) isearch-opoint)
-       (progn
-         (push-mark isearch-opoint t)
-         (deactivate-mark)
-         (or executing-macro (> (minibuffer-depth) 0)
-             (message "Mark saved where search started")))
-      ;; (message "") why is this needed?
-      )
+       (or (and transient-mark-mode mark-active)
+           (progn
+             (push-mark isearch-opoint t)
+             (or executing-kbd-macro (> (minibuffer-depth) 0)
+                 (message "Mark saved where search started"))))))
 
   (setq isearch-mode nil)
-  (set-buffer-modified-p (buffer-modified-p))  ;; update modeline
+  (force-mode-line-update)
 
   (if (and (> (length isearch-string) 0) (not nopush))
       ;; Update the ring data.
-      (if isearch-regexp 
-         (if (or (null regexp-search-ring)
-                 (not (string= isearch-string (car regexp-search-ring))))
-             (progn
-               (setq regexp-search-ring
-                     (cons isearch-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= isearch-string (car search-ring))))
-           (progn
-             (setq search-ring (cons isearch-string search-ring))
-             (if (> (length search-ring) search-ring-max)
-                 (setcdr (nthcdr (1- search-ring-max) search-ring) nil))))))
+      (isearch-update-ring isearch-string isearch-regexp))
 
   (run-hooks 'isearch-mode-end-hook)
-  (if isearch-recursive-edit (exit-recursive-edit)))
+  (and (not edit) isearch-recursive-edit (exit-recursive-edit)))
+
+(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 (or (null regexp-search-ring)
+             (not (string= string (car regexp-search-ring))))
+         (progn
+           (setq regexp-search-ring
+                 (cons 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))
+         (if (> (length search-ring) search-ring-max)
+             (setcdr (nthcdr (1- search-ring-max) search-ring) nil))))))
 
 ;;;=======================================================
 ;;; Switching buffers should first terminate isearch-mode.
@@ -666,11 +622,11 @@ The following additional command keys are active while editing.
 \\[exit-minibuffer] to resume incremental searching with the edited string.
 \\[isearch-nonincremental-exit-minibuffer] to do one nonincremental search.
 \\[isearch-forward-exit-minibuffer] to resume isearching forward.
-\\[isearch-backward-exit-minibuffer] to resume isearching backward.
+\\[isearch-reverse-exit-minibuffer] to resume isearching backward.
 \\[isearch-ring-advance-edit] to replace the search string with the next item in the search ring.
 \\[isearch-ring-retreat-edit] to replace the search string with the previous item in the search ring.
 \\[isearch-complete-edit] to complete the search string using the search ring.
-
+\\<isearch-mode-map>
 If first char entered is \\[isearch-yank-word], then do word search instead."
 
   ;; This code is very hairy for several reasons, explained in the code.
@@ -701,7 +657,12 @@ If first char entered is \\[isearch-yank-word], then do word search instead."
            (isearch-yank-flag isearch-yank-flag)
            (isearch-invalid-regexp isearch-invalid-regexp)
            (isearch-within-brackets isearch-within-brackets)
-           (isearch-other-end isearch-other-end)
+;;; Don't bind this.  We want isearch-search, below, to set it.
+;;; And the old value won't matter after that.
+;;;        (isearch-other-end isearch-other-end)
+;;; Perhaps some of these other variables should be bound for a
+;;; shorter period, ending before the next isearch-search.
+;;; But there doesn't seem to be a real bug, so let's not risk it now.
            (isearch-opoint isearch-opoint)
            (isearch-slow-terminal-mode isearch-slow-terminal-mode)
            (isearch-small-window isearch-small-window)
@@ -714,7 +675,7 @@ If first char entered is \\[isearch-yank-word], then do word search instead."
        ;; 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)
+           (isearch-done t t)
          (exit nil))                   ; was recursive editing
 
        (isearch-message) ;; for read-char
@@ -725,7 +686,8 @@ If first char entered is \\[isearch-yank-word], then do word search instead."
                        (read-event)))
                   ;; Binding minibuffer-history-symbol to nil is a work-around
                   ;; for some incompatibility with gmhist.
-                  (minibuffer-history-symbol))
+                  (minibuffer-history-symbol)
+                  (message-log-max nil))
              ;; If the first character the user types when we prompt them
              ;; for a string is the yank-word character, then go into
              ;; word-search mode.  Otherwise unread that character and
@@ -741,17 +703,19 @@ If first char entered is \\[isearch-yank-word], then do word search instead."
              (setq cursor-in-echo-area nil)
              (setq isearch-new-string
                    (let (junk-ring)
-                     (read-from-minibuffer (isearch-message-prefix)
-                                           isearch-string
-                                           minibuffer-local-isearch-map nil
-                                           'junk-ring))
-                   isearch-new-message (mapconcat 'text-char-description
-                                                  isearch-new-string "")))
+                     (read-from-minibuffer
+                      (isearch-message-prefix nil nil isearch-nonincremental)
+                      isearch-string
+                      minibuffer-local-isearch-map nil
+                      'junk-ring))
+                   isearch-new-message
+                   (mapconcat 'isearch-text-char-description
+                              isearch-new-string "")))
          ;; Always resume isearching by restarting it.
          (isearch-mode isearch-forward 
                        isearch-regexp 
                        isearch-op-fun 
-                       isearch-recursive-edit
+                       nil
                        isearch-word)
 
          ;; Copy new local values to isearch globals
@@ -762,8 +726,10 @@ If first char entered is \\[isearch-yank-word], then do word search instead."
 
        ;; Empty isearch-string means use default.
        (if (= 0 (length isearch-string))
-           (setq isearch-string (car (if isearch-regexp regexp-search-ring
-                                       search-ring)))
+           (setq isearch-string (or (car (if isearch-regexp
+                                             regexp-search-ring
+                                           search-ring))
+                                    ""))
          ;; This used to set the last search string,
          ;; but I think it is not right to do that here.
          ;; Only the string actually used should be saved.
@@ -797,6 +763,12 @@ If first char entered is \\[isearch-yank-word], then do word search instead."
   (setq isearch-new-forward nil)
   (exit-minibuffer))
 
+(defun isearch-cancel ()
+  "Terminate the search and go back to the starting point."
+  (interactive)
+  (goto-char isearch-opoint)
+  (isearch-done t)
+  (signal 'quit nil))  ; and pass on quit signal
 
 (defun isearch-abort ()
   "Abort incremental search mode if searching is successful, signalling quit.
@@ -809,13 +781,15 @@ Use `isearch-exit' to quit without signalling."
       ;; If search is successful, move back to starting point
       ;; and really do quit.
       (progn (goto-char isearch-opoint)
+            (setq isearch-success nil)
             (isearch-done t)   ; exit isearch
             (signal 'quit nil))  ; and pass on quit signal
-    ;; If search is failing, rub out until it is once more successful.
-    (while (not isearch-success) (isearch-pop-state))
+    ;; If search is failing, or has an incomplete regexp,
+    ;; rub out until it is once more successful.
+    (while (or (not isearch-success) isearch-invalid-regexp)
+      (isearch-pop-state))
     (isearch-update)))
 
-
 (defun isearch-repeat (direction)
   ;; Utility for isearch-repeat-forward and -backward.
   (if (eq isearch-forward (eq direction 'forward))
@@ -876,6 +850,20 @@ Use `isearch-exit' to quit without signalling."
   (if isearch-regexp (setq isearch-word nil))
   (isearch-update))
 
+(defun isearch-toggle-case-fold ()
+  "Toggle case folding in searching on or off."
+  (interactive)
+  (setq isearch-case-fold-search
+       (if isearch-case-fold-search nil 'yes))
+  (let ((message-log-max nil))
+    (message "%s%s [case %ssensitive]"
+            (isearch-message-prefix nil nil isearch-nonincremental)
+            isearch-message
+            (if isearch-case-fold-search "in" "")))
+  (setq isearch-adjusted t)
+  (sit-for 1)
+  (isearch-update))
+
 (defun isearch-delete-char ()
   "Discard last input item and move point back.  
 If no previous match was done, just beep."
@@ -1018,37 +1006,75 @@ 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)
-  (cond ((eq search-exit-option 'edit)
-        (let ((key (this-command-keys)))
-          (apply 'isearch-unread (listify-key-sequence key)))
-        (isearch-edit-string))
-       (search-exit-option
-        (let ((key (this-command-keys))
-              (index 0)
-              window)
-          (apply 'isearch-unread (listify-key-sequence key))
-          ;; Properly handle scroll-bar and mode-line clicks
-          ;; for which a dummy prefix event was generated as (aref key 0).
-          (and (> (length key) 1)
-               (symbolp (aref key 0))
-               (listp (aref key 1))
-               ;; These events now have a symbol; they used to have a list.
-               ;; Accept either one.  Other events have a number here.
-               (not (numberp (posn-point (event-start (aref key 1)))))
-               (setq index 1))
-          ;; If we got a mouse click, maybe it was read with the buffer
-          ;; it was clicked on.  If so, that buffer, not the current one,
-          ;; is in isearch mode.  So end the search in that buffer.
-          (if (and (listp (aref key index))
-                   (setq window (posn-window (event-start (aref key index))))
-                   (windowp window))
-              (save-excursion
-                (set-buffer (window-buffer window))
-                (isearch-done))
-            (isearch-done))))
-       (t;; otherwise nil
-        (isearch-process-search-string (this-command-keys)
-                                       (this-command-keys)))))
+  (let* ((key (this-command-keys))
+        (main-event (aref key 0))
+        (keylist (listify-key-sequence key)))
+    (cond ((and (= (length key) 1)
+               (let ((lookup (lookup-key function-key-map key)))
+                 (not (or (null lookup) (integerp lookup)))))
+          ;; Handle a function key that translates into something else.
+          ;; If the key has a global definition too,
+          ;; exit and unread the key itself, so its global definition runs.
+          ;; Otherwise, unread the translation,
+          ;; so that the translated key takes effect within isearch.
+          (cancel-kbd-macro-events)
+          (if (lookup-key global-map key)
+              (progn 
+                (isearch-done)
+                (apply 'isearch-unread keylist))
+            (apply 'isearch-unread
+                   (listify-key-sequence (lookup-key function-key-map key)))))
+         (
+          ;; Handle an undefined shifted control character
+          ;; by downshifting it if that makes it defined.
+          ;; (As read-key-sequence would normally do,
+          ;; if we didn't have a default definition.)
+          (let ((mods (event-modifiers main-event)))
+            (and (integerp main-event)
+                 (memq 'shift mods)
+                 (memq 'control mods)
+                 (lookup-key isearch-mode-map
+                             (let ((copy (copy-sequence key)))
+                               (aset copy 0
+                                     (- main-event (- ?\C-\S-a ?\C-a)))
+                               copy)
+                             nil)))
+          (setcar keylist (- main-event (- ?\C-\S-a ?\C-a)))
+          (cancel-kbd-macro-events)
+          (apply 'isearch-unread keylist))
+         ((eq search-exit-option 'edit)
+          (apply 'isearch-unread keylist)
+          (isearch-edit-string))
+         (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).
+            (and (> (length key) 1)
+                 (symbolp (aref key 0))
+                 (listp (aref key 1))
+                 (not (numberp (posn-point (event-start (aref key 1)))))
+                 ;; Convert the event back into its raw form,
+                 ;; with the dummy prefix implicit in the mouse event,
+                 ;; so it will get split up once again.
+                 (progn (setq unread-command-events
+                              (cdr unread-command-events))
+                        (setq main-event (car unread-command-events))
+                        (setcar (cdr (event-start main-event))
+                                (car (nth 1 (event-start main-event))))))
+            ;; If we got a mouse click, maybe it was read with the buffer
+            ;; it was clicked on.  If so, that buffer, not the current one,
+            ;; is in isearch mode.  So end the search in that buffer.
+            (if (and (listp main-event)
+                     (setq window (posn-window (event-start main-event)))
+                     (windowp window))
+                (save-excursion
+                  (set-buffer (window-buffer window))
+                  (isearch-done))
+              (isearch-done))))
+         (t;; otherwise nil
+          (isearch-process-search-string key key)))))
 
 (defun isearch-quote-char ()
   "Quote special characters for incremental search."
@@ -1270,7 +1296,10 @@ If there is no completion possible, say so and continue searching."
            isearch-message
            (isearch-message-suffix c-q-hack ellipsis)
            )))
-    (if c-q-hack m (message "%s" m))))
+    (if c-q-hack
+       m
+      (let ((message-log-max nil))
+       (message "%s" m)))))
 
 (defun isearch-message-prefix (&optional c-q-hack ellipsis nonincremental)
   ;; If about to search, and previous search regexp was invalid,
@@ -1279,11 +1308,17 @@ If there is no completion possible, say so and continue searching."
   (and isearch-invalid-regexp ellipsis
        (condition-case ()
           (progn (re-search-forward isearch-string (point) t)
-                 (setq isearch-invalid-regexp nil))
+                 (setq isearch-invalid-regexp nil
+                       isearch-within-brackets nil))
         (error nil)))
   ;; If currently failing, display no ellipsis.
   (or isearch-success (setq ellipsis nil))
   (let ((m (concat (if isearch-success "" "failing ")
+                  (if (and isearch-wrapped
+                           (if isearch-forward
+                               (> (point) isearch-opoint)
+                             (< (point) isearch-opoint)))
+                      "over")
                   (if isearch-wrapped "wrapped ")
                   (if isearch-word "word " "")
                   (if isearch-regexp "regexp " "")
@@ -1307,7 +1342,7 @@ If there is no completion possible, say so and continue searching."
 (defun isearch-search ()
   ;; Do the search with the current search string.
   (isearch-message nil t)
-  (if (and isearch-case-fold-search search-upper-case)
+  (if (and (eq isearch-case-fold-search t) search-upper-case)
       (setq isearch-case-fold-search
            (isearch-no-upper-case-p isearch-string isearch-regexp)))
   (condition-case lossage
@@ -1360,7 +1395,7 @@ If there is no completion possible, say so and continue searching."
 (defvar isearch-overlay nil)
 
 (defun isearch-highlight (beg end)
-  (if (null search-highlight)
+  (if (or (null search-highlight) (null window-system))
       nil
     (or isearch-overlay (setq isearch-overlay (make-overlay beg end)))
     (move-overlay isearch-overlay beg end (current-buffer))
@@ -1395,36 +1430,20 @@ since they have special meaning in a regexp."
 (defvar last-command-event)
 
 (defun isearch-char-to-string (c)
-  (if (integerp c)
-      (make-string 1 c)
-    (if (and (symbolp c) (get c 'ascii-character))
-       (make-string 1 (get c 'ascii-character))
-      (make-string 1 (event-to-character c)))))
+  (make-string 1 c))
 
 (defun isearch-text-char-description (c)
   (if (and (integerp c) (or (< c ?\ ) (= c ?\^?)))
       (text-char-description c)
     (isearch-char-to-string c)))
 
+;; General function to unread characters or events.
 (defun isearch-unread (&rest char-or-events)
-  ;; General function to unread characters or events.
-  (if isearch-gnu-emacs-events
-      (setq unread-command-events
-           (append char-or-events unread-command-events))
-    (let ((char (if (cdr char-or-events)
-                   (progn
-                     (while (cdr char-or-events)
-                       (setq char-or-events (cdr char-or-events)))
-                     (+ 128 (car char-or-events)))
-                 (car char-or-events))))
-      (if isearch-event-data-type
-         (setq unread-command-event char)
-       (setq unread-command-char char)))))
+  (setq unread-command-events
+       (append char-or-events unread-command-events)))
 
 (defun isearch-last-command-char ()
   ;; General function to return the last command character.
-  (if isearch-event-data-type
-      last-command-event
-    last-command-char))
+  last-command-char)
 
 ;;; isearch.el ends here