]> code.delx.au - gnu-emacs/blobdiff - lisp/isearch.el
(command_loop_1): No direct display if Column Number mode.
[gnu-emacs] / lisp / isearch.el
index 677fdef363a9baa22a5f32af357918422ce5aa9f..cd035b08b3edc3df8baddcc164febb7f83127281 100644 (file)
@@ -1,10 +1,9 @@
 ;;; isearch.el --- incremental search minor mode.
 
-;; Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+;; Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
 
 ;; Author: Daniel LaLiberte <liberte@cs.uiuc.edu>
-
-;; |$Date: 1994/12/26 05:09:07 $|$Revision: 1.82 $
+;; Maintainer: FSF
 
 ;; This file is part of GNU Emacs.
 
@@ -137,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.")
 
@@ -235,37 +231,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)
 
-      ;; Bind the ASCII-equivalent "function keys" explicitly to nil
-      ;; so that the default binding does not apply.
-      ;; As a result, these keys translate thru function-key-map
-      ;; as normal, and they have the effect of the equivalent ASCII char.
-      ;; We bind [escape] below.
-      (define-key map [tab] 'nil)
-      (define-key map [kp-0] 'nil)
-      (define-key map [kp-1] 'nil)
-      (define-key map [kp-2] 'nil)
-      (define-key map [kp-3] 'nil)
-      (define-key map [kp-4] 'nil)
-      (define-key map [kp-5] 'nil)
-      (define-key map [kp-6] 'nil)
-      (define-key map [kp-7] 'nil)
-      (define-key map [kp-8] 'nil)
-      (define-key map [kp-9] 'nil)
-      (define-key map [kp-add] 'nil)
-      (define-key map [kp-subtract] 'nil)
-      (define-key map [kp-multiply] 'nil)
-      (define-key map [kp-divide] 'nil)
-      (define-key map [kp-decimal] 'nil)
-      (define-key map [kp-separator] 'nil)
-      (define-key map [kp-equal] 'nil)
-      (define-key map [kp-tab] 'nil)
-      (define-key map [kp-space] 'nil)
-      (define-key map [kp-enter] 'nil)
-      (define-key map [delete] 'nil)
-      (define-key map [backspace] 'nil)
-      (define-key map [return] 'nil)
-      (define-key map [newline] 'nil)
-
       ;; Define keys for regexp chars * ? |.
       ;; Nothing special for + because it matches at least once.
       (define-key map "*" 'isearch-*-char)
@@ -282,9 +247,14 @@ Default value, nil, means edit the string instead.")
 
       (define-key map "\M-\t" 'isearch-complete)
 
-      ;; Switching frames should terminate isearch-mode
-      (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)
       ))
 
@@ -416,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."
@@ -467,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
@@ -498,12 +471,11 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
        (if isearch-slow-terminal-mode (current-window-configuration) nil))
 
   (setq        isearch-mode " Isearch")  ;; forward? regexp?
-  (set-buffer-modified-p (buffer-modified-p)) ; update modeline
+  (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)
 
@@ -561,7 +533,7 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
   (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)))
@@ -584,29 +556,34 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
                  (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)
   (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.
 ;;; This is done quite differently for each variant of emacs.
@@ -680,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)
@@ -797,13 +779,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))
@@ -1020,42 +1004,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))
-               (main-event (aref key 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))
-               (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 (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."
@@ -1295,6 +1312,11 @@ If there is no completion possible, say so and continue searching."
   ;; 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 " "")