;;; 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/18 15:46:30 $|$Revision: 1.35 $
+;; |$Date: 1993/07/08 22:33:57 $|$Revision: 1.45 $
;; 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.
;;;========================================================================
;;; 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.")
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 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?
;;;=======================================================
;;; 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