]> code.delx.au - gnu-emacs/blobdiff - lisp/isearch.el
New icons for debugger.
[gnu-emacs] / lisp / isearch.el
index 7b502220c2fc12be8a7f5452d2af986b719fc718..754b7cf6fa1745083c339e8d7b6a26f03f7760d4 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
 ;;   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.
@@ -171,7 +171,9 @@ nil means don't match invisible text.
 If the value is `open', if the text matched is made invisible by
 an overlay having an `invisible' property and that overlay has a property
 `isearch-open-invisible', then incremental search will show the contents.
-\(This applies when using `outline.el' and `hideshow.el'.)"
+\(This applies when using `outline.el' and `hideshow.el'.)
+See also `reveal-mode' if you want overlays to automatically be opened
+whenever point is in one of them."
   :type '(choice (const :tag "Match hidden text" t)
                 (const :tag "Open overlays" open)
                 (const :tag "Don't match hidden text" nil))
@@ -182,8 +184,8 @@ an overlay having an `invisible' property and that overlay has a property
 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
@@ -243,7 +245,7 @@ Default value, nil, means edit the string instead."
     ;; Make function keys, etc, 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 ?\ )
@@ -282,7 +284,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)
@@ -290,7 +292,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)
 
@@ -354,6 +356,7 @@ Default value, nil, means edit the string instead."
 (defvar isearch-forward nil)   ; Searching in the forward direction.
 (defvar isearch-regexp nil)    ; Searching for a regexp.
 (defvar isearch-word nil)      ; Searching for words.
+(defvar isearch-hidden nil) ; Non-nil if the string exists but is invisible.
 
 (defvar isearch-cmds nil
   "Stack of search status sets.
@@ -441,7 +444,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.
@@ -472,7 +475,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.
 
@@ -480,7 +483,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').
@@ -532,7 +535,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.
@@ -608,8 +611,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))
@@ -627,7 +630,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)
@@ -731,19 +734,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))))))
 
@@ -765,7 +767,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)))
@@ -837,7 +839,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)
@@ -845,7 +847,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)))
@@ -879,9 +881,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)
 
@@ -912,7 +914,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))))
@@ -975,7 +977,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 "")
@@ -1093,7 +1095,7 @@ Otherwise invoke whatever mouse-2 is bound to outside of Isearch."
     (if (and (window-minibuffer-p w)
             (not (minibuffer-window-active-p w))) ; in echo area
        (isearch-yank-x-selection)
-      (when binding
+      (when (functionp binding)
        (call-interactively binding)))))
 
 
@@ -1118,7 +1120,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)
@@ -1132,7 +1134,7 @@ might return the position of the end of the line."
 (defun isearch-yank-line ()
   "Pull rest of line from buffer into search string."
   (interactive)
-  (isearch-yank-internal (lambda () (line-end-position))))
+  (isearch-yank-internal 'line-end-position))
 
 
 (defun isearch-search-and-update ()
@@ -1141,7 +1143,10 @@ might return the position of the end of the line."
            ;; unsuccessful regexp search may become
            ;;  successful by addition of characters which
            ;;  make isearch-string valid
-           isearch-regexp)
+           isearch-regexp
+           ;; If the string was found but was completely invisible,
+           ;; it might now be partly visible, so try again.
+           (prog1 isearch-hidden (setq isearch-hidden nil)))
     ;; In reverse search, adding stuff at
     ;; the end may cause zero or many more chars to be
     ;; matched, in the string following point.
@@ -1208,7 +1213,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."
@@ -1309,7 +1314,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
@@ -1371,7 +1376,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 " ")
@@ -1487,9 +1492,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
@@ -1500,8 +1504,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))))
@@ -1515,7 +1519,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)))
@@ -1523,7 +1530,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)
@@ -1553,9 +1560,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)
@@ -1688,7 +1695,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.
@@ -1767,68 +1774,67 @@ Can be changed via `isearch-search-fun-function' for special needs."
 
 (defun isearch-range-invisible (beg end)
   "Return t if all the text from BEG to END is invisible."
-  (and (/= beg end)
-       ;; Check that invisibility runs up to END.
-       (save-excursion
-        (goto-char beg)
-        (let (
-              ;; can-be-opened keeps track if we can open some overlays.
-              (can-be-opened (eq search-invisible 'open))
-              ;; the list of overlays that could be opened
-              (crt-overlays nil))
-          (when (and can-be-opened isearch-hide-immediately) 
-            (isearch-close-unnecessary-overlays beg end))
-          ;; 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)
-                (progn 
-                  (goto-char (next-single-property-change (point) 'invisible
-                                                          nil end))
-                  ;; if text is hidden by an `invisible' text property
-                  ;; we cannot open it at all.
-                  (setq can-be-opened nil))
-              (unless (null can-be-opened)
-                (let ((overlays (overlays-at (point)))
-                      ov-list
-                      o
-                      invis-prop)
-                  (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 (overlay-get o 'isearch-open-invisible)
-                            (setq ov-list (cons o ov-list))
-                          ;; We found one overlay that cannot be
-                          ;; opened, that means the whole chunk
-                          ;; cannot be opened.
-                          (setq can-be-opened nil)))
-                    (setq overlays (cdr overlays)))
-                  (if can-be-opened 
-                      ;; It makes sense to append to the open
-                      ;; overlays list only if we know that this is
-                      ;; t.
-                      (setq crt-overlays (append ov-list crt-overlays)))))
-              (goto-char (next-overlay-change (point)))))
-        ;; See if invisibility reaches up thru END.
-        (if (>= (point) end)
-            (if (and (not (null can-be-opened)) (consp crt-overlays))
-                (progn
-                  (setq isearch-opened-overlays
-                        (append isearch-opened-overlays crt-overlays))
-                  (mapc 'isearch-open-overlay-temporary crt-overlays)
-                  nil)
-              t))))))
+  (when (/= beg end)
+    ;; Check that invisibility runs up to END.
+    (save-excursion
+      (goto-char beg)
+      (let (;; can-be-opened keeps track if we can open some overlays.
+           (can-be-opened (eq search-invisible 'open))
+           ;; the list of overlays that could be opened
+           (crt-overlays nil))
+       (when (and can-be-opened isearch-hide-immediately)
+         (isearch-close-unnecessary-overlays beg end))
+       ;; 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)
+             (progn
+               (goto-char (next-single-property-change (point) 'invisible
+                                                       nil end))
+               ;; if text is hidden by an `invisible' text property
+               ;; we cannot open it at all.
+               (setq can-be-opened nil))
+           (when can-be-opened
+             (let ((overlays (overlays-at (point)))
+                   ov-list
+                   o
+                   invis-prop)
+               (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 (overlay-get o 'isearch-open-invisible)
+                         (setq ov-list (cons o ov-list))
+                       ;; We found one overlay that cannot be
+                       ;; opened, that means the whole chunk
+                       ;; cannot be opened.
+                       (setq can-be-opened nil)))
+                 (setq overlays (cdr overlays)))
+               (if can-be-opened
+                   ;; It makes sense to append to the open
+                   ;; overlays list only if we know that this is
+                   ;; t.
+                   (setq crt-overlays (append ov-list crt-overlays)))))
+           (goto-char (next-overlay-change (point)))))
+       ;; See if invisibility reaches up thru END.
+       (if (>= (point) end)
+           (if (and can-be-opened (consp crt-overlays))
+               (progn
+                 (setq isearch-opened-overlays
+                       (append isearch-opened-overlays crt-overlays))
+                 (mapc 'isearch-open-overlay-temporary crt-overlays)
+                 nil)
+             (setq isearch-hidden t)))))))
 
 \f
 ;; Highlighting
@@ -1860,13 +1866,14 @@ 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 ?\\))
            (setq quote-flag (not quote-flag))
          (if (and (not quote-flag) (not (eq char (downcase char))))
-             (setq found t))))
+             (setq found t))
+         (setq quote-flag nil)))
       (setq i (1+ i)))
     (not found)))