;;; isearch.el --- incremental search minor mode.
-;; Copyright (C) 1992 Free Software Foundation, Inc.
+;; Copyright (C) 1992, 1993 Free Software Foundation, Inc.
;; Author: Daniel LaLiberte <liberte@cs.uiuc.edu>
-;; |$Date: 1993/05/15 20:05:36 $|$Revision: 1.33 $
+;; |$Date: 1993/07/15 03:46:02 $|$Revision: 1.46 $
;; This file is not yet part of GNU Emacs, but it is based almost
;; entirely on isearch.el which is part of GNU Emacs.
;; 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 Log:
-;;;====================================================================
-;;; Change History
-
-;;; $Header: /home/fsf/rms/e19/lisp/RCS/isearch.el,v 1.33 1993/05/15 20:05:36 rms Exp rms $
-;;; $Log: isearch.el,v $
-; Revision 1.33 1993/05/15 20:05:36 rms
-; (isearch-done): Don't activate mark.
-;
-; Revision 1.32 1993/05/14 18:02:55 rms
-; (isearch-mode-map): Handle any length vector in keymap.
-; (isearch-char-to-string): Handle non-character events properly.
-;
-; Revision 1.31 1993/04/23 07:31:14 eric
-; Replaced all fsets with defaliases.
-;
-; Revision 1.30 1993/04/14 19:40:53 rms
-; Doc fixes.
-;
-; Revision 1.29 1993/03/30 19:42:10 rms
-; (isearch-done): Customize the message about mark.
-;
-; Revision 1.28 1993/03/30 19:38:34 rms
-; (isearch-mode-map): Delete the binding for C-h.
-;
-; Revision 1.27 1993/03/21 05:50:17 jimb
-; * isearch.el (isearch-switch-frame-handler): Call
-; handle-switch-frame instead of select-frame; it has been renamed.
-;
-; Revision 1.26 1993/03/17 17:17:05 eric
-; Add standard library headers.
-;
-; Revision 1.25 1993/03/17 16:44:50 eric
-; Add standard library headers.
-;
-; Revision 1.24 1993/03/17 15:58:09 eric
-; Add standard library headers.
-;
-; Revision 1.23 1993/03/07 20:17:27 rms
-; (isearch-other-meta-char): Call listify-key-sequence.
-; (isearch-unread): Don't call it here.
-; (isearch-mode-map): Bind the ASCII-equivalent function keys.
-;
-; Revision 1.22 1993/03/07 08:43:57 rms
-; (isearch-mode): Don't make a pre-command-hook.
-;
-; Revision 1.21 1993/03/07 04:22:00 rms
-; (isearch-unread): Find last list element by hand.
-;
-; Revision 1.20 1993/03/06 06:15:05 rms
-; (isearch-unread): Handle multiple args.
-; For Emacs 19, use listify-key-sequence.
-; If not Emacs 19, assume they are a meta sequence.
-; (isearch-other-meta-char): Pass the whole key sequence.
-; (isearch-other-control-char): Make this alias for ...-meta-char.
-;
-; Revision 1.19 1993/02/17 21:30:25 rms
-; Fix minor bugs in previous change.
-;
-; Revision 1.18 1993/02/17 20:34:20 rms
-; (isearch-backward-regexp):
-; New arg no-recursive-edit, always non-nil for interactive call.
-; Rename first arg, and set it right in interactive call.
-; (isearch-forward-regexp): Likewise.
-; (isearch-forward, isearch-backward): Likewise no-recursive-edit.
-;
-; 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
-;
+;;; 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.
;;;========================================================================
;;; 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
;; 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.")
(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)
(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 ?\ )
- (or (vectorp (nth 1 map))
- (error "The initialization of isearch-mode-map must be updated"))
(while (< i (length (nth 1 map)))
- (define-key map (make-string 1 i) 'isearch-printing-char)
+ (define-key map (vector i) 'isearch-printing-char)
(setq i (1+ i)))
;; Several non-printing chars change the searching behavior.
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.
isearch-small-window nil
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-slow-terminal-mode
+ (setq isearch-window-configuration (current-window-configuration)))
+
;; This was for Lucid Emacs. But now that we have pre-command-hook,
;; it causes trouble.
;; (if isearch-pre-command-hook-exists
;; 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-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 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)))
;; 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)
- (if transient-mark-mode
- (setq mark-active nil))
+ (deactivate-mark)
(or executing-macro (> (minibuffer-depth) 0)
(message "Mark saved where search started")))
;; (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)))
(setq isearch-mode nil)
(set-buffer-modified-p (buffer-modified-p)) ;; update modeline
;;;=======================================================
;;; 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.
\\[isearch-forward-exit-minibuffer] to resume isearching forward.
\\[isearch-backward-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."
;; 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.
Otherwise, revert to previous successful search and continue searching.
Use `isearch-exit' to quit without signalling."
(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
(apply 'isearch-unread (listify-key-sequence key)))
(isearch-edit-string))
(search-exit-option
- (let ((key (this-command-keys)))
- (apply 'isearch-unread (listify-key-sequence key)))
- (isearch-done))
+ (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))
+ (consp (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)))))
-
(defun isearch-quote-char ()
"Quote special characters for incremental search."
(interactive)
(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)
(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 isearch-case-fold-search 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))
;;;========================================================
;;; Highlighting
-(defun isearch-highlight (begin end))
-(defun isearch-dehighlight (totally))
-
-;; lemacs uses faces
-'(progn
-(defvar isearch-extent nil)
+(defvar isearch-overlay 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 (null search-highlight)
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)))))
-
-(defalias 'isearch-highlight (symbol-function 'isearch-lemacs-highlight))
-(defalias 'isearch-dehighlight (symbol-function 'isearch-lemacs-dehighlight))
-)
+ (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))))
+
+(defun isearch-dehighlight (totally)
+ (if isearch-overlay
+ (delete-overlay isearch-overlay)))
;;;===========================================================
;;; General utilities
-;; (defalias 'isearch-member-equal (symbol-function 'member)) ; for emacs 19
-(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)
-
-
-(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 preceeded 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)
last-command-event
last-command-char))
-
-
-\f
-;;;========================================================
-;;; 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