(insert-parentheses): Don't insert spaces at beginning and end of buffer.
[bpt/emacs.git] / lisp / isearch.el
index 7be09bd..3bcc23a 100644 (file)
@@ -1,27 +1,26 @@
 ;;; isearch.el --- incremental search minor mode.
 
-;; Copyright (C) 1992, 1993 Free Software Foundation, Inc.
+;; Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
 
 ;; Author: Daniel LaLiberte <liberte@cs.uiuc.edu>
 
-;; |$Date: 1993/12/23 03:28:10 $|$Revision: 1.56 $
+;; |$Date: 1994/08/30 07:03:33 $|$Revision: 1.72 $
 
 ;; 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:
 
@@ -233,19 +232,37 @@ 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.
+      ;; 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] 'isearch-printing-char)
-      (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-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.
@@ -282,6 +299,7 @@ Default value, nil, means edit the string instead.")
 
 ;; 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)
 
@@ -315,11 +333,15 @@ Default value, nil, means edit the string instead.")
 
 (defvar isearch-success t)             ; Searching is currently successful.
 (defvar isearch-invalid-regexp nil)    ; Regexp not well formed.
+(defvar isearch-within-brackets nil)   ; Regexp has unclosed [.
 (defvar isearch-other-end nil) ; Start (end) of match if forward (backward).
 (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)
@@ -328,7 +350,6 @@ Default value, nil, means edit the string instead.")
 (defvar isearch-opoint 0)
 ;;; The window configuration active at the beginning of the search.
 (defvar isearch-window-configuration nil)
-(defvar isearch-old-local-map nil)
 
 ;; Flag to indicate a yank occurred, so don't move the cursor.
 (defvar isearch-yank-flag nil)
@@ -472,6 +493,7 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
        isearch-adjusted nil
        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)
                                        (> (window-height)
@@ -480,11 +502,10 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
        isearch-small-window nil
 
        isearch-opoint (point)
-       isearch-old-local-map (current-local-map)
        search-ring-yank-pointer nil
        regexp-search-ring-yank-pointer nil)
-  (if isearch-slow-terminal-mode
-      (setq isearch-window-configuration (current-window-configuration)))
+  (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.
@@ -499,7 +520,8 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
 
   (isearch-push-state)
 
-  (use-local-map isearch-mode-map)
+  (make-local-variable 'overriding-local-map)
+  (setq overriding-local-map isearch-mode-map)
   (isearch-update)
   (run-hooks 'isearch-mode-hook)
 
@@ -509,7 +531,7 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
   (if recursive-edit
       (let ((isearch-recursive-edit t))
        (recursive-edit)))
-  )
+  isearch-success)
 
 
 ;;;====================================================
@@ -556,10 +578,10 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
   )
 
 
-(defun isearch-done (&optional nopush)
+(defun isearch-done (&optional nopush edit)
   ;; Called by all commands that terminate isearch-mode.
   ;; If NOPUSH is non-nil, we don't push the string on the search ring.
-  (use-local-map isearch-old-local-map)
+  (setq overriding-local-map nil)
   ;; (setq pre-command-hook isearch-old-pre-command-hook) ; for lemacs
   (isearch-dehighlight t)
   (let ((found-start (window-start (selected-window)))
@@ -577,7 +599,6 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
     (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?
@@ -605,7 +626,7 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
                  (setcdr (nthcdr (1- search-ring-max) search-ring) nil))))))
 
   (run-hooks 'isearch-mode-end-hook)
-  (if isearch-recursive-edit (exit-recursive-edit)))
+  (and (not edit) isearch-recursive-edit (exit-recursive-edit)))
 
 ;;;=======================================================
 ;;; Switching buffers should first terminate isearch-mode.
@@ -645,11 +666,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.
@@ -679,6 +700,7 @@ If first char entered is \\[isearch-yank-word], then do word search instead."
            (isearch-adjusted isearch-adjusted)
            (isearch-yank-flag isearch-yank-flag)
            (isearch-invalid-regexp isearch-invalid-regexp)
+           (isearch-within-brackets isearch-within-brackets)
            (isearch-other-end isearch-other-end)
            (isearch-opoint isearch-opoint)
            (isearch-slow-terminal-mode isearch-slow-terminal-mode)
@@ -692,7 +714,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
@@ -723,13 +745,14 @@ If first char entered is \\[isearch-yank-word], then do word search instead."
                                            isearch-string
                                            minibuffer-local-isearch-map nil
                                            'junk-ring))
-                   isearch-new-message (mapconcat 'text-char-description
-                                                  isearch-new-string "")))
+                   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
@@ -818,14 +841,21 @@ Use `isearch-exit' to quit without signalling."
     (setq isearch-forward (not isearch-forward)))
 
   (setq isearch-barrier (point)) ; For subsequent \| if regexp.
-  (setq isearch-success t)
-  (or (equal isearch-string "")
-      (progn
+
+  (if (equal isearch-string "")
+      (setq isearch-success t)
+    (if (and isearch-success (equal (match-end 0) (match-beginning 0)))
        ;; If repeating a search that found
        ;; an empty string, ensure we advance.
-       (if (equal (match-end 0) (match-beginning 0))
-           (forward-char (if isearch-forward 1 -1)))
-       (isearch-search)))
+       (if (if isearch-forward (eobp) (bobp))
+           ;; If there's nowhere to advance to, fail (and wrap next time).
+           (progn
+             (setq isearch-success nil)
+             (ding))
+         (forward-char (if isearch-forward 1 -1))
+         (isearch-search))
+      (isearch-search)))
+
   (isearch-push-state)
   (isearch-update))
 
@@ -847,6 +877,19 @@ 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))
+  (message "%s%s [case %ssensitive]"
+          (isearch-message-prefix)
+          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."
@@ -929,6 +972,7 @@ If no previous match was done, just beep."
                       (min isearch-opoint isearch-barrier))))
        (setq isearch-success t 
              isearch-invalid-regexp nil
+             isearch-within-brackets nil
              isearch-other-end (match-end 0))
       ;; Not regexp, not reverse, or no match at point.
       (if (and isearch-other-end (not isearch-adjusted))
@@ -1041,7 +1085,7 @@ Obsolete."
 If you want to search for just a space, type C-q SPC."
   (interactive)
   (if isearch-regexp 
-      (if search-whitespace-regexp
+      (if (and search-whitespace-regexp (not isearch-within-brackets))
          (isearch-process-search-string search-whitespace-regexp " ")
        (isearch-printing-char))
     (progn
@@ -1209,7 +1253,9 @@ If there is no completion possible, say so and continue searching."
          isearch-word (nth 6 cmd)
          isearch-invalid-regexp (nth 7 cmd)
          isearch-wrapped (nth 8 cmd)
-         isearch-barrier (nth 9 cmd))
+         isearch-barrier (nth 9 cmd)
+         isearch-within-brackets (nth 10 cmd)
+         isearch-case-fold-search (nth 11 cmd))
     (goto-char (car (cdr (cdr cmd))))))
 
 (defun isearch-pop-state ()
@@ -1222,7 +1268,8 @@ If there is no completion possible, say so and continue searching."
        (cons (list isearch-string isearch-message (point)
                    isearch-success isearch-forward isearch-other-end 
                    isearch-word
-                   isearch-invalid-regexp isearch-wrapped isearch-barrier)
+                   isearch-invalid-regexp isearch-wrapped isearch-barrier
+                   isearch-within-brackets isearch-case-fold-search)
              isearch-cmds)))
 
 \f
@@ -1246,7 +1293,8 @@ 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))
@@ -1274,13 +1322,14 @@ 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
       (let ((inhibit-quit nil)
            (case-fold-search isearch-case-fold-search))
        (if isearch-regexp (setq isearch-invalid-regexp nil))
+       (setq isearch-within-brackets nil)
        (setq isearch-success
              (funcall
               (cond (isearch-word
@@ -1301,6 +1350,8 @@ If there is no completion possible, say so and continue searching."
 
     (invalid-regexp 
      (setq isearch-invalid-regexp (car (cdr lossage)))
+     (setq isearch-within-brackets (string-match "\\`Unmatched \\["
+                                                isearch-invalid-regexp))
      (if (string-match
          "\\`Premature \\|\\`Unmatched \\|\\`Invalid "
          isearch-invalid-regexp)
@@ -1324,7 +1375,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))