X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/eceee2c04a26e60fc91636fc527c86d1a9722289..b578f267af27af50e3c091f8c9c9eee939b69978:/lisp/isearch.el diff --git a/lisp/isearch.el b/lisp/isearch.el index f4e15dcad9..6fb53604b4 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -1,58 +1,36 @@ -;; Incremental search minor mode. -;; Copyright (C) 1992 Free Software Foundation, Inc. +;;; isearch.el --- incremental search minor mode. -;; LCD Archive Entry: -;; isearch-mode|Daniel LaLiberte|liberte@cs.uiuc.edu -;; |A minor mode replacement for isearch.el. -;; |$Date: 1993/01/26 01:48:27 $|$Revision: 1.17 $|~/modes/isearch-mode.el +;; Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. -;; This file is not yet part of GNU Emacs, but it is based almost -;; entirely on isearch.el which is part of GNU Emacs. +;; Author: Daniel LaLiberte +;; 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. - -;;;==================================================================== -;; Instructions +;; 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. -;; Searching with isearch-mode.el should work just like isearch.el, -;; except it is done in a temporary minor mode that terminates when -;; you finish searching. +;; 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, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. -;; To use isearch-mode instead of the standard isearch.el, add the -;; following to your .emacs file. The standard key bindings to -;; isearch-forward, etc, will then use isearch-mode instead of -;; isearch. +;;; Commentary: -;; (fset 'isearch 'isearch-mode) -;; (autoload 'isearch-mode "isearch-mode") +;; Instructions ;; For programmed use of isearch-mode, e.g. calling (isearch-forward), ;; isearch-mode behaves modally and does not return until the search ;; is completed. It uses a recursive-edit to behave this way. Note: ;; gnus does it wrong: (call-interactively 'isearch-forward). -;; If any package you use invokes isearching non-interactively to get -;; the modal behavior described above, you must use the redefinitions -;; of isearch-forward, etc. found in this file instead of those in -;; loaddefs.el. The simplest way to ensure this is to just load -;; isearch-mode explicitly in your .emacs instead of using the above -;; fset and autoload. - -;; (load "isearch-mode") - ;; The key bindings active within isearch-mode are defined below in ;; `isearch-mode-map' which is given bindings close to the default ;; characters of the original isearch.el. With `isearch-mode', @@ -81,102 +59,51 @@ ;; the last possible moment. ;; TODO -;; - Integrate the emacs 19 generalized commmand history. +;; - Integrate the emacs 19 generalized command history. ;; - Think about incorporating query-replace. ;; - Hooks and options for failed search. -;;;==================================================================== -;;; Change History - -;;; $Header: /gd/gnu/emacs/19.0/lisp/RCS/isearch-mode.el,v 1.17 1993/01/26 01:48:27 jimb Exp rms $ -;;; $Log: isearch-mode.el,v $ -; Revision 1.17 1993/01/26 01:48:27 jimb -; JimB's changes since January 18th -; -; Revision 1.16 1992/11/16 01:37:06 jimb -; * bytecomp.el: Declare unread-command-char an obsolete variable. -; * vip.el (vip-escape-to-emacs, vip-prefix-arg-value, -; vip-prefix-arg-com): Use unread-command-event instead of -; unread-command-char; respect its new semantics. -; * isearch-mode.el (isearch-update, isearch-unread): Same. -; -; Revision 1.15 1992/11/07 06:17:04 jimb -; * isearch.el (isearch-frames-exist): This isn't what we want - -; replaced by... -; (isearch-gnu-emacs-events): non-nil if should expect events in the -; style generated by GNU Emacs 19. Set if set-frame-height is -; fboundp; this is true on any GNU Emacs 19, whether or not it was -; compiled with multiple frame support. -; (isearch-mode-map): Test isearch-gnu-emacs-events instead of -; isearch-frames-exist to see if we should bind switch-frame events. -; (isearch-update): Test isearch-gnu-emacs-events instead of -; isearch-frames-exist to see if unread-command-char's quiescent -; value is nil or -1. -; -; Revision 1.14 1992/11/01 22:10:59 rms -; (isearch-search): Handle all sorts of errors from regexp search. -; -; Revision 1.13 1992/10/27 04:11:46 rms -; (isearch-edit-string): -; Bind cursor-in-echo-area only around read-char/allocate-event. -; -; Revision 1.12 1992/10/20 21:21:47 rms -; (isearch-mode-map): Make the top-level keymap dense. -; Explicitly bind control characters at that level. -; -; Revision 1.11 1992/10/11 05:25:11 rms -; (isearch-ring-advance-edit): Delete spurious `)'. -; -; Revision 1.10 1992/09/21 08:28:43 rms -; entered into RCS -; -;;; Revision 1.4 92/09/14 16:26:02 liberte -;;; Added prefix args to isearch-forward, etc. to switch between -;;; string and regular expression searching. -;;; Added some support for lemacs. -;;; Added general isearch-highlight option - but only for lemacs so far. -;;; Added support for frame switching in emacs 19. -;;; 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. -;;; isearch-edit-string used by ring adjustments, completion, and -;;; nonincremental searching. C-s and C-r are additional exit commands. -;;; Renamed all regex to regexp. -;;; Got rid of found-start and found-point globals. -;;; Generalized handling of upper-case chars. - -;;; Revision 1.2 92/05/27 11:33:57 liberte -;;; Emacs version 19 has a search ring, which is supported here. -;;; Other fixes found in the version 19 isearch are included here. -;;; -;;; Also see variables search-caps-disable-folding, -;;; search-nonincremental-instead, search-whitespace-regexp, and -;;; commands isearch-toggle-regexp, isearch-edit-string. -;;; -;;; semi-modal isearching is supported. - -;;; Changes for 1.1 -;;; 3/18/92 Fixed invalid-regexp. -;;; 3/18/92 Fixed yanking in regexps. - +;;; Change Log: + +;; Changes before those recorded in ChangeLog: + +;; Revision 1.4 92/09/14 16:26:02 liberte +;; Added prefix args to isearch-forward, etc. to switch between +;; string and regular expression searching. +;; Added some support for lemacs. +;; Added general isearch-highlight option - but only for lemacs so far. +;; Added support for frame switching in emacs 19. +;; 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. +;; isearch-edit-string used by ring adjustments, completion, and +;; nonincremental searching. C-s and C-r are additional exit commands. +;; Renamed all regex to regexp. +;; Got rid of found-start and found-point globals. +;; Generalized handling of upper-case chars. + +;; Revision 1.2 92/05/27 11:33:57 liberte +;; Emacs version 19 has a search ring, which is supported here. +;; Other fixes found in the version 19 isearch are included here. +;; +;; Also see variables search-caps-disable-folding, +;; search-nonincremental-instead, search-whitespace-regexp, and +;; commands isearch-toggle-regexp, isearch-edit-string. +;; +;; semi-modal isearching is supported. + +;; Changes for 1.1 +;; 3/18/92 Fixed invalid-regexp. +;; 3/18/92 Fixed yanking in regexps. + +;;; 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.") @@ -192,10 +119,7 @@ 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 t +(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. This applies no matter where the chars come from, but does not @@ -211,13 +135,8 @@ 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 - "Whether isearch and query-replace should highlight the text which -currently matches the search-string.") - + "*Non-nil means incremental search highlights the current match.") (defvar isearch-mode-hook nil "Function(s) to call after starting up an incremental search.") @@ -225,7 +144,6 @@ currently matches the search-string.") (defvar isearch-mode-end-hook nil "Function(s) to call after terminating an incremental search.") -;;;================================================================== ;;; Search ring. (defvar search-ring nil @@ -249,7 +167,6 @@ nil if none yet.") "*Non-nil if advancing or retreating in the search ring should cause search. Default value, nil, means edit the string instead.") -;;;==================================================== ;;; Define isearch-mode keymap. (defvar isearch-mode-map nil @@ -258,6 +175,11 @@ Default value, nil, means edit the string instead.") (or isearch-mode-map (let* ((i 0) (map (make-keymap))) + (or (vectorp (nth 1 map)) + (error "The initialization of isearch-mode-map must be updated")) + ;; Give this map a vector 256 long, for dense binding + ;; of a larger range of ordinary characters. + (setcar (cdr map) (make-vector 256 nil)) ;; Make function keys, etc, exit the search. (define-key map [t] 'isearch-other-control-char) @@ -269,23 +191,35 @@ Default value, nil, means edit the string instead.") (define-key map (make-string 1 i) 'isearch-other-control-char) (setq i (1+ i))) - ;; Printing chars extend the selection by default. + ;; Printing chars extend the search string by default. (setq i ?\ ) - (while (< i 128) - (define-key map (make-string 1 i) 'isearch-printing-char) + (while (< i (length (nth 1 map))) + (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) - ;; (define-key map "\r" 'isearch-return-char) - ;; For version 19, RET (C-m) terminates search and LFD (C-j) matches eol. - ;; We could make this conditional. (define-key map "\r" 'isearch-exit) (define-key map "\C-j" 'isearch-printing-char) (define-key map "\t" 'isearch-printing-char) @@ -300,44 +234,30 @@ Default value, nil, means edit the string instead.") (define-key map "?" 'isearch-*-char) (define-key map "|" 'isearch-|-char) - ;; You can reenable global keys by binding them locally to nil. - ;; For the help char this doesnt work quite as expected because - ;; isearch-mode is not a major mode. Also the echo area is not - ;; restored after the help command while isearch-mode is - ;; still active. Furthermore, we should not assume that the - ;; help-command is on C-h. But here is how it would be done: - ;; (define-key map "\C-h" nil) - - ;; 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. - (define-key map (char-to-string meta-prefix-char) (make-sparse-keymap)) - (define-key map (vector meta-prefix-char t) 'isearch-other-meta-char) -;;; (setq i 0) -;;; (while (< i 128) -;;; (define-key map (char-to-string (+ 128 i));; Needs to be generalized. -;;; 'isearch-other-meta-char) -;;; (setq i (1+ i))) +;;; Turned off because I find I expect to get the global definition--rms. +;;; ;; Instead bind C-h to special help command for isearch-mode. +;;; (define-key map "\C-h" 'isearch-mode-help) (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) @@ -356,7 +276,6 @@ Default value, nil, means edit the string instead.") (setq minibuffer-local-isearch-map map) )) -;;;======================================================== ;; Internal variables declared globally for byte-compiler. ;; These are all set with setq while isearching ;; and bound locally while editing the search string. @@ -371,11 +290,16 @@ 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-just-started nil) -(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) @@ -384,7 +308,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,7 +327,6 @@ Default value, nil, means edit the string instead.") (defvar isearch-new-forward nil) -;;;============================================================== ;; Minor-mode-alist changes - kind of redundant with the ;; echo area, but if isearching in multiple windows, it can be useful. @@ -420,10 +342,9 @@ Default value, nil, means edit the string instead.") (define-key global-map "\C-r" 'isearch-backward) (define-key esc-map "\C-r" 'isearch-backward-regexp) -;;;=============================================================== ;;; Entry points to isearch-mode. ;;; These four functions should replace those in loaddefs.el -;;; An alternative is to fset isearch-forward etc to isearch-mode, +;;; An alternative is to defalias isearch-forward etc to isearch-mode, ;;; and look at this-command to set the options accordingly. (defun isearch-forward (&optional regexp-p no-recursive-edit) @@ -444,7 +365,6 @@ Type \\[isearch-yank-word] to yank word from buffer onto end of search\ Type \\[isearch-yank-line] to yank rest of line onto end of search string\ and search for it. Type \\[isearch-quote-char] to quote control character to search for it. -Type \\[isearch-whitespace-chars] to match all whitespace chars in regexp. \\[isearch-abort] while searching or when search has failed cancels input\ back to what has been found successfully. @@ -461,12 +381,13 @@ 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." (interactive "P\np") - (isearch-mode t (not (null regexp-p)) nil no-recursive-edit)) + (isearch-mode t (not (null regexp-p)) nil (not no-recursive-edit))) (defun isearch-forward-regexp (&optional not-regexp no-recursive-edit) "\ @@ -475,7 +396,7 @@ With a prefix argument, do a regular string search instead. Like ordinary incremental search except that your input is treated as a regexp. See \\[isearch-forward] for more info." (interactive "P\np") - (isearch-mode t (null not-regexp) nil no-recursive-edit)) + (isearch-mode t (null not-regexp) nil (not no-recursive-edit))) (defun isearch-backward (&optional regexp-p no-recursive-edit) "\ @@ -483,7 +404,7 @@ Do incremental search backward. With a prefix argument, do a regular expression search instead. See \\[isearch-forward] for more information." (interactive "P\np") - (isearch-mode nil (not (null regexp-p)) nil no-recursive-edit)) + (isearch-mode nil (not (null regexp-p)) nil (not no-recursive-edit))) (defun isearch-backward-regexp (&optional not-regexp no-recursive-edit) "\ @@ -492,7 +413,7 @@ With a prefix argument, do a regular string search instead. Like ordinary incremental search except that your input is treated as a regexp. See \\[isearch-forward] for more info." (interactive "P\np") - (isearch-mode nil (null not-regexp) nil no-recursive-edit)) + (isearch-mode nil (null not-regexp) nil (not no-recursive-edit))) (defun isearch-mode-help () @@ -501,7 +422,6 @@ is treated as a regexp. See \\[isearch-forward] for more info." (isearch-update)) -;;;================================================================== ;; isearch-mode only sets up incremental search for the minor mode. ;; All the work is done by the isearch-mode commands. @@ -512,7 +432,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 @@ -529,46 +451,46 @@ 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-just-started t isearch-opoint (point) - isearch-window-configuration (current-window-configuration) - isearch-old-local-map (current-local-map) search-ring-yank-pointer nil regexp-search-ring-yank-pointer nil) - (if isearch-pre-command-hook-exists - (add-hook 'pre-command-hook 'isearch-pre-command-hook)) + (looking-at "") + (setq isearch-window-configuration + (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) - (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 (recursive-edit)) - ) + (if recursive-edit + (let ((isearch-recursive-edit t)) + (recursive-edit))) + isearch-success) -;;;==================================================== ;; Some high level utilities. Others below. (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)) @@ -594,62 +516,71 @@ 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))) (found-point (point))) - (set-window-configuration isearch-window-configuration) + (if isearch-window-configuration + (set-window-configuration isearch-window-configuration)) - ;; If there was movement, mark the starting position. - ;; Maybe should test difference between and set mark iff > threshold. - (if (/= (point) isearch-opoint) - (push-mark isearch-opoint) - ;; (message "") why is this needed? - ) (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) + (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. -;;; This is done quite differently for each varient of emacs. +;;; This is done quite differently for each variant of emacs. ;;; For lemacs, see Exiting in lemacs below ;; For Emacs 19, the frame switch event is handled. @@ -657,12 +588,9 @@ is treated as a regexp. See \\[isearch-forward] for more info." (interactive) ;; Is this necessary? ;; First terminate isearch-mode. (isearch-done) - (select-frame (car (cdr (isearch-last-command-char))))) - -;;;======================================================== + (handle-switch-frame (car (cdr (isearch-last-command-char))))) -;;;==================================================== ;; Commands active while inside of the isearch minor mode. (defun isearch-exit () @@ -685,21 +613,21 @@ 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 previou 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. ;; Mainly, isearch-mode must be terminated while editing and then restarted. ;; If there were a way to catch any change of buffer from the minibuffer, ;; this could be simplified greatly. - ;; Editing doesnt back up the search point. Should it? + ;; Editing doesn't back up the search point. Should it? (interactive) (condition-case err - (let (isearch-nonincremental ; should search nonincrementally? + (let ((isearch-nonincremental isearch-nonincremental) ;; Locally bind all isearch global variables to protect them ;; from recursive isearching. @@ -719,7 +647,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) @@ -732,7 +666,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 @@ -740,11 +674,11 @@ If first char entered is \\[isearch-yank-word], then do word search instead." (let* (;; Why does following read-char echo? ;;(echo-keystrokes 0) ;; not needed with above message (e (let ((cursor-in-echo-area t)) - (if isearch-event-data-type - (allocate-event) (read-char)))) + (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 @@ -753,29 +687,26 @@ If first char entered is \\[isearch-yank-word], then do word search instead." ;; no check is made here. (message (isearch-message-prefix nil nil t)) (if (eq 'isearch-yank-word - (lookup-key - isearch-mode-map - (char-to-string - (if isearch-event-data-type - (or (event-to-character (next-command-event e)) 0) - e)))) + (lookup-key isearch-mode-map (vector e))) (setq isearch-word t ;; so message-prefix is right isearch-new-word t) (isearch-unread e)) (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 @@ -786,8 +717,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. @@ -821,25 +754,33 @@ 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. + "Abort incremental search mode if searching is successful, signaling quit. Otherwise, revert to previous successful search and continue searching. -Use `isearch-exit' to quit without signalling." +Use `isearch-exit' to quit without signaling." (interactive) -;; (ding) signal instead below, if quiting +;; (ding) signal instead below, if quitting (discard-input) (if isearch-success ;; 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)) @@ -864,14 +805,22 @@ 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)) + (not isearch-just-started)) ;; 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)) @@ -893,6 +842,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." @@ -905,18 +868,23 @@ If no previous match was done, just beep." (defun isearch-yank (chunk) ;; Helper for isearch-yank-word and isearch-yank-line - (let ((string (save-excursion - (and (not isearch-forward) isearch-other-end - (goto-char isearch-other-end)) - (buffer-substring - (point) - (save-excursion - (cond - ((eq chunk 'word) - (forward-word 1)) - ((eq chunk 'line) - (end-of-line))) - (point)))))) + ;; CHUNK should be word, line or kill. + (let ((string (cond + ((eq chunk 'kill) + (current-kill 0)) + (t + (save-excursion + (and (not isearch-forward) isearch-other-end + (goto-char isearch-other-end)) + (buffer-substring + (point) + (save-excursion + (cond + ((eq chunk 'word) + (forward-word 1)) + ((eq chunk 'line) + (end-of-line))) + (point)))))))) ;; Downcase the string if not supposed to case-fold yanked strings. (if (and isearch-case-fold-search (eq 'not-yanks search-upper-case)) @@ -931,6 +899,10 @@ If no previous match was done, just beep." isearch-yank-flag t)) (isearch-search-and-update)) +(defun isearch-yank-kill () + "Pull string from kill ring into search string." + (interactive) + (isearch-yank 'kill)) (defun isearch-yank-word () "Pull next word from buffer into search string." @@ -958,14 +930,16 @@ If no previous match was done, just beep." ;; long as the match does not extend past search origin. (if (and (not isearch-forward) (not isearch-adjusted) (condition-case () - (looking-at (if isearch-regexp isearch-string - (regexp-quote isearch-string))) + (let ((case-fold-search isearch-case-fold-search)) + (looking-at (if isearch-regexp isearch-string + (regexp-quote isearch-string)))) (error nil)) (or isearch-yank-flag (<= (match-end 0) (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)) @@ -1017,40 +991,83 @@ If no previous match was done, just beep." (isearch-process-search-char (isearch-last-command-char))) -(defun isearch-other-control-char () - "Any other control char => unread it and exit the search normally. -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 control char is unread so that it applies to editing the string." - (interactive) - (cond ((eq search-exit-option 'edit) - (isearch-unread (isearch-last-command-char)) - (isearch-edit-string)) - (search-exit-option;; any other non-nil value - (isearch-unread (isearch-last-command-char)) - (isearch-done)) - (t;; search-exit-option is nil - (isearch-process-search-char (isearch-last-command-char))))) - +(defalias 'isearch-other-control-char 'isearch-other-meta-char) (defun isearch-other-meta-char () - "Any other meta char => exit the search normally and reread the character. + "Exit the search normally and reread this key sequence. 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))) - (isearch-unread (+ 128 (aref key (1- (length key)))))) - (isearch-edit-string)) - (search-exit-option - (let ((key (this-command-keys))) - (isearch-unread (+ 128 (aref key (1- (length key)))))) - (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." @@ -1064,20 +1081,20 @@ Obsolete." (isearch-process-search-char ?\n)) (defun isearch-printing-char () - "Any other printing character => add it to the search string and search." + "Add this ordinary printing character to the search string and search." (interactive) (isearch-process-search-char (isearch-last-command-char))) (defun isearch-whitespace-chars () "Match all whitespace chars, if in regexp mode. -If not in regexp mode, activate word search." +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 - ;; This way of doing word search doesnt correctly extend current search. + ;; This way of doing word search doesn't correctly extend current search. ;; (setq isearch-word t) ;; (setq isearch-adjusted t) ;; (goto-char isearch-barrier) @@ -1095,7 +1112,6 @@ If not in regexp mode, activate word search." (isearch-search-and-update)) -;;=========================================================== ;; Search Ring (defun isearch-ring-adjust1 (advance) @@ -1110,9 +1126,9 @@ If not in regexp mode, activate word search." () (set yank-pointer-name (setq yank-pointer - (% (+ (or yank-pointer 0) - (if advance (1- length) 1)) - length))) + (mod (+ (or yank-pointer 0) + (if advance -1 1)) + length))) (setq isearch-string (nth yank-pointer ring) isearch-message (mapconcat 'isearch-text-char-description isearch-string ""))))) @@ -1154,11 +1170,8 @@ If not in regexp mode, activate word search." () (set yank-pointer-name (setq yank-pointer - (% (+ (or yank-pointer 0) - ;; Add LENGTH here to ensure a positive result. - length - (% (- n) length)) - length))) + (mod (- (or yank-pointer 0) n) + length))) (erase-buffer) (insert (nth yank-pointer ring)) @@ -1197,7 +1210,7 @@ If not in regexp mode, activate word search." ;; isearch-string stays the same t) ((or completion ; not nil, must be a string - (= 0 (length isearch-string))) ; shouldnt have to say this + (= 0 (length isearch-string))) ; shouldn't have to say this (if (equal completion isearch-string) ;; no extension? (if completion-auto-help (with-output-to-temp-buffer "*Isearch completions*" @@ -1230,7 +1243,6 @@ If there is no completion possible, say so and continue searching." (insert isearch-string)))) -;;;============================================================== ;; The search status stack (and isearch window-local variables, not used). ;; Need a structure for this. @@ -1244,7 +1256,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 () @@ -1257,11 +1271,11 @@ 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))) -;;;================================================================== ;; Message string (defun isearch-message (&optional c-q-hack ellipsis) @@ -1272,7 +1286,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, @@ -1281,11 +1298,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 " "") @@ -1303,18 +1326,19 @@ If there is no completion possible, say so and continue searching." ""))) -;;;======================================================== ;;; Searching (defun isearch-search () ;; Do the search with the current search string. (isearch-message nil t) - (if search-upper-case - (setq isearch-case-fold-search (isearch-no-upper-case-p isearch-string))) + (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 @@ -1326,6 +1350,7 @@ If there is no completion possible, say so and continue searching." (t (if isearch-forward 'search-forward 'search-backward))) isearch-string nil t)) + (setq isearch-just-started nil) (if isearch-success (setq isearch-other-end (if isearch-forward (match-beginning 0) (match-end 0))))) @@ -1335,6 +1360,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) @@ -1352,74 +1379,37 @@ If there is no completion possible, say so and continue searching." -;;;======================================================== ;;; Highlighting -(defun isearch-highlight (begin end)) -(defun isearch-dehighlight (totally)) +(defvar isearch-overlay nil) -;; lemacs uses faces -'(progn -(defvar isearch-extent nil) - -(or (find-face 'isearch) ;; this face is initialized by x-faces.el - (make-face 'isearch)) ;; since isearch is preloaded - -(defun isearch-lemacs-highlight (begin end) - (if (null isearch-highlight) +(defun isearch-highlight (beg end) + (if (or (null search-highlight) (null window-system)) nil - (if (and (extentp isearch-extent) - (eq (extent-buffer isearch-extent) (current-buffer))) - (set-extent-endpoints isearch-extent begin end) - (if (and (extentp isearch-extent) - (bufferp (extent-buffer isearch-extent)) - (buffer-name (extent-buffer isearch-extent))) - (delete-extent isearch-extent)) - (setq isearch-extent (make-extent begin end (current-buffer)))) - (set-extent-face isearch-extent 'isearch))) - -(defun isearch-lemacs-dehighlight (totally) - (if (and isearch-highlight isearch-extent) - (if totally - (let ((inhibit-quit t)) - (if (and (extentp isearch-extent) - (bufferp (extent-buffer isearch-extent)) - (buffer-name (extent-buffer isearch-extent))) - (delete-extent isearch-extent)) - (setq isearch-extent nil)) - (if (and (extentp isearch-extent) - (bufferp (extent-buffer isearch-extent)) - (buffer-name (extent-buffer isearch-extent))) - (set-extent-face isearch-extent 'default) - (isearch-dehighlight t))))) - -(fset 'isearch-highlight (symbol-function 'isearch-lemacs-highlight)) -(fset 'isearch-dehighlight (symbol-function 'isearch-lemacs-dehighlight)) -) - -;;;=========================================================== -;;; General utilities + (or isearch-overlay (setq isearch-overlay (make-overlay beg end))) + (move-overlay isearch-overlay beg end (current-buffer)) + (overlay-put isearch-overlay 'face + (if (internal-find-face 'isearch nil) + 'isearch 'region)))) -;; (fset 'isearch-member-equal (symbol-function 'member)) ; for emacs 19 +(defun isearch-dehighlight (totally) + (if isearch-overlay + (delete-overlay isearch-overlay))) -(defun isearch-member-equal (item list) - "Return non-nil if ITEM is `equal' to some item in LIST. -Actually return the list whose car is that item." - (while (and list (not (equal item (car list)))) - (setq list (cdr list))) - list) +;;; General utilities -(defun isearch-no-upper-case-p (string) - "Return t if there are no upper case chars in string. -But upper case chars preceeded by \\ (but not \\\\) do not count since they -have special meaning in a regexp." +(defun isearch-no-upper-case-p (string regexp-flag) + "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 ((case-fold-search nil)) - (not (string-match "\\(^\\|\\\\\\\\\\|[^\\]\\)[A-Z]" string)))) + (not (string-match (if regexp-flag "\\(^\\|\\\\\\\\\\|[^\\]\\)[A-Z]" + "[A-Z]") + string)))) -;;;================================================= -;;; Special functions for lemacs events. +;; Portability functions to support various Emacs versions. ;; To quiet the byte-compiler. (defvar unread-command-event) @@ -1427,129 +1417,22 @@ have special meaning in a regexp." (defvar last-command-event) (defun isearch-char-to-string (c) - (if (integerp c) - (make-string 1 c) - (make-string 1 (event-to-character c)))) + (make-string 1 c)) (defun isearch-text-char-description (c) - (isearch-char-to-string c)) - -(defun isearch-unread (char-or-event) - ;; General function to unread a character or event. - (cond - (isearch-event-data-type - (setq unread-command-event char-or-event)) - (isearch-gnu-emacs-events - (setq unread-command-events (list char-or-event))) - (t - (setq unread-command-char char-or-event)))) + (if (and (integerp c) (or (< c ?\ ) (= c ?\^?))) + (text-char-description c) + (isearch-char-to-string c))) + +;; General function to unread characters or events. +;; Also insert them in a keyboard macro being defined. +(defun isearch-unread (&rest char-or-events) + (mapcar 'store-kbd-macro-event char-or-events) + (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) - - -;;;======================================================== -;;; Exiting in lemacs - -;; This is a large amount of code to support automatic termination of -;; isearch-mode when a command (however it is invoked) is not an -;; isearch command, or the buffer is switched out from under -;; isearch-mode. Only later versions of lemacs have the pre-command-hook. - -;;(if isearch-pre-command-hook-exists -;;(progn - -;;;; This list must be modified whenever the available commands are modified. -;;(mapcar (function (lambda (command) -;; (put command 'isearch-command t))) -;; '(isearch-printing-char -;; isearch-return-char -;; isearch-repeat-forward -;; isearch-repeat-backward -;; isearch-delete-char -;; isearch-abort -;; isearch-quote-char -;; isearch-exit -;; isearch-printing-char -;; isearch-printing-char -;; isearch-yank-word -;; isearch-yank-line -;; isearch-*-char -;; isearch-*-char -;; isearch-|-char -;; isearch-toggle-regexp -;; isearch-edit-string -;; isearch-mode-help -;; isearch-ring-advance -;; isearch-ring-retreat -;; isearch-ring-advance-edit -;; isearch-ring-retreat-edit -;; isearch-whitespace-chars -;; isearch-complete -;; isearch-complete-edit -;; isearch-edit-string -;; isearch-toggle-regexp -;; ;; The following may not be needed since isearch-mode is off already. -;; isearch-forward-exit-minibuffer -;; isearch-reverse-exit-minibuffer -;; isearch-nonincremental-exit-minibuffer)) - -;;(defun isearch-pre-command-hook () -;; ;; -;; ;; For use as the value of `pre-command-hook' when isearch-mode is active. -;; ;; If the command about to be executed is not one of the isearch commands, -;; ;; then isearch-mode is turned off before that command is executed. -;; ;; -;; ;; If the command about to be executed is self-insert-command, or is a -;; ;; keyboard macro of a single key sequence which is bound to self-insert- -;; ;; command, then we add those chars to the search ring instead of inserting -;; ;; them in the buffer. In this way, the set of self-searching characters -;; ;; need not be exhaustively enumerated, but is derived from other maps. -;; ;; -;; (isearch-maybe-frob-keyboard-macros) -;; (if (and (symbolp this-command) -;; (get this-command 'isearch-command)) -;; nil -;; (isearch-done))) - -;;(defun isearch-maybe-frob-keyboard-macros () -;; ;; -;; ;; If the command about to be executed is `self-insert-command' then change -;; ;; the command to `isearch-printing-char' instead, meaning add the last- -;; ;; typed character to the search string. -;; ;; -;; ;; If `this-command' is a string or a vector (that is, a keyboard macro) -;; ;; and it contains only one command, which is bound to self-insert-command, -;; ;; then do the same thing as for self-inserting commands: arrange for that -;; ;; character to be added to the search string. If we didn't do this, then -;; ;; typing a compose sequence (a la x-compose.el) would terminate the search -;; ;; and insert the character, instead of searching for that character. -;; ;; -;; (cond ((eq this-command 'self-insert-command) -;; (setq this-command 'isearch-printing-char)) -;; ((and (stringp this-command) -;; (eq (key-binding this-command) 'self-insert-command)) -;; (setq last-command-char (aref this-command 0) -;; last-command-event (character-to-event last-command-char) -;; this-command 'isearch-printing-char)) -;; ((and (vectorp this-command) -;; (eq (key-binding this-command) 'self-insert-command)) -;; (let* ((desc (aref this-command 0)) -;; (code (cond ((integerp desc) desc) -;; ((symbolp desc) (get desc character-set-property)) -;; ((consp desc) -;; (and (null (cdr desc)) -;; (get (car desc) character-set-property))) -;; (t nil)))) -;; (if code -;; (setq last-command-char code -;; last-command-event (character-to-event last-command-char) -;; this-command 'isearch-printing-char)))) -;; )) - -;;)) +;;; isearch.el ends here