X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/9d78ff8be7ca60314fc76cca5c5be99ba6a136bc..0a8e8bc63e39c61309fd58f37c874db1ea65ccd7:/lisp/isearch.el diff --git a/lisp/isearch.el b/lisp/isearch.el index 27eb0b2eee..bbcc08bf00 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -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 - -;; |$Date: 1993/11/26 22:20:23 $|$Revision: 1.55 $ +;; 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: @@ -105,18 +103,8 @@ ;;; Code: -;;;========================================================================= -;;; 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,19 +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 [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. @@ -257,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) @@ -315,11 +294,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 +311,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) @@ -404,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." @@ -455,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 @@ -472,44 +457,37 @@ is treated as a regexp. See \\[isearch-forward] for more info." isearch-adjusted nil isearch-yank-flag nil isearch-invalid-regexp nil - ;; Use (baud-rate) for now, for sake of other versions. - isearch-slow-terminal-mode (and (<= (baud-rate) search-slow-speed) + isearch-within-brackets nil + isearch-slow-terminal-mode (and (<= baud-rate search-slow-speed) (> (window-height) (* 4 search-slow-window-lines))) isearch-other-end nil 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. -;; (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) - (use-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) ;;;==================================================== @@ -517,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)) @@ -547,18 +521,19 @@ is treated as a regexp. See \\[isearch-forward] for more info." (if isearch-other-end (if (< isearch-other-end (point)) ; isearch-forward? (isearch-highlight isearch-other-end (point)) - (isearch-highlight (point) isearch-other-end))) + (isearch-highlight (point) isearch-other-end)) + (isearch-dehighlight nil)) )) (setq ;; quit-flag nil not for isearch-mode isearch-adjusted nil 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. - (use-local-map isearch-old-local-map) + (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))) @@ -569,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. @@ -644,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. - +\\ 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. @@ -678,7 +656,13 @@ 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-other-end isearch-other-end) + (isearch-within-brackets isearch-within-brackets) +;;; 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) @@ -691,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 @@ -702,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 @@ -718,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 @@ -739,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. @@ -774,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. @@ -786,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)) @@ -817,14 +814,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)) @@ -846,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." @@ -928,6 +946,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)) @@ -987,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." @@ -1040,7 +1097,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 @@ -1208,7 +1265,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 () @@ -1221,7 +1280,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))) @@ -1236,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, @@ -1245,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 " "") @@ -1273,13 +1342,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 @@ -1300,6 +1370,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) @@ -1323,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)) @@ -1358,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