;;; isearch.el --- incremental search minor mode
;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
-;; 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+;; 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
;; Author: Daniel LaLiberte <liberte@cs.uiuc.edu>
;; Maintainer: FSF
this, unless it is inside of a regexp construct such as [...] or *, + or ?.
You might want to use something like \"[ \\t\\r\\n]+\" instead.
In the Customization buffer, that is `[' followed by a space,
-a tab, a carriage return (control-M), a newline, and `]+'."
- :type 'regexp
+a tab, a carriage return (control-M), a newline, and `]+'.
+
+When this is nil, each space you type matches literally, against one space."
+ :type '(choice (const :tag "Find Spaces Literally" nil)
+ regexp)
:group 'isearch)
(defcustom search-invisible 'open
(define-key map [iconify-frame] nil)
(define-key map [make-frame-visible] nil)
(define-key map [mouse-movement] nil)
+ (define-key map [language-change] nil)
+
;; For searching multilingual text.
(define-key map "\C-\\" 'isearch-toggle-input-method)
(define-key map "\C-^" 'isearch-toggle-specified-input-method)
Type LFD (C-j) to match end of line.
Type \\[isearch-repeat-forward] to search again forward,\
\\[isearch-repeat-backward] to search again backward.
-Type \\[isearch-yank-word-or-char] to yank word from buffer onto end of search\
- string and search for it.
+Type \\[isearch-yank-word-or-char] to yank next word or character in buffer
+ onto the end of the search string, and search for it.
Type \\[isearch-del-char] to delete character from end of search string.
Type \\[isearch-yank-char] to yank char from buffer onto end of search\
string and search for it.
(lazy-highlight-cleanup lazy-highlight-cleanup)
(let ((found-start (window-start (selected-window)))
(found-point (point)))
- (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)))
+ (when isearch-window-configuration
+ (set-window-configuration isearch-window-configuration)
+ (if isearch-small-window
+ (goto-char found-point)
+ ;; set-window-configuration clobbers window-start; restore it.
+ ;; This has an annoying side effect of clearing the last_modiff
+ ;; field of the window, which can cause unwanted scrolling,
+ ;; so don't do it unless truly necessary.
+ (set-window-start (selected-window) found-start t))))
(setq isearch-mode nil)
(if isearch-input-method-local-p
(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
- (push 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
- (push string search-ring)
- (if (> (length search-ring) search-ring-max)
- (setcdr (nthcdr (1- search-ring-max) search-ring) nil))))))
+REGEXP if non-nil says use the regexp search ring."
+ (add-to-history
+ (if regexp 'regexp-search-ring 'search-ring)
+ string
+ (if regexp regexp-search-ring-max search-ring-max)))
;; Switching buffers should first terminate isearch-mode.
;; ;; For Emacs 19, the frame switch event is handled.
;; C-s in forward or C-r in reverse.
(if (equal isearch-string "")
;; If search string is empty, use last one.
- (setq isearch-string
- (or (if isearch-regexp
- (car regexp-search-ring)
- (car search-ring))
- (error "No previous search string"))
- isearch-message
- (mapconcat 'isearch-text-char-description
- isearch-string "")
- isearch-case-fold-search isearch-last-case-fold-search)
+ (if (null (if isearch-regexp regexp-search-ring search-ring))
+ (setq isearch-error "No previous search string")
+ (setq isearch-string
+ (if isearch-regexp
+ (car regexp-search-ring)
+ (car search-ring))
+ isearch-message
+ (mapconcat 'isearch-text-char-description
+ isearch-string "")
+ isearch-case-fold-search isearch-last-case-fold-search))
;; If already have what to search for, repeat it.
(or isearch-success
(progn
(let ((case-fold-search isearch-case-fold-search))
(isearch-done)
(isearch-clean-overlays)
- (if (and (< isearch-other-end (point))
+ (if (and isearch-other-end
+ (< isearch-other-end (point))
(not (and transient-mark-mode mark-active
- (< isearch-opoint (point)))))
+ (< (mark) (point)))))
(goto-char isearch-other-end))
(set query-replace-from-history-variable
(cons isearch-string
(defun isearch-mouse-2 (click)
"Handle mouse-2 in Isearch mode.
For a click in the echo area, invoke `isearch-yank-x-selection'.
-Otherwise invoke whatever mouse-2 is bound to outside of Isearch."
+Otherwise invoke whatever the calling mouse-2 command sequence
+is bound to outside of Isearch."
(interactive "e")
(let* ((w (posn-window (event-start click)))
(overriding-terminal-local-map nil)
- (key (vector (event-basic-type click)))
- ;; FIXME: `key-binding' should accept an event as argument
- ;; and do all the overlay/text-properties lookup etc...
- (binding (with-current-buffer
- (if (window-live-p w) (window-buffer w) (current-buffer))
- (key-binding key))))
+ (binding (key-binding (this-command-keys-vector) t)))
(if (and (window-minibuffer-p w)
(not (minibuffer-window-active-p w))) ; in echo area
(isearch-yank-x-selection)
(when (functionp binding)
(call-interactively binding)))))
-
(defun isearch-yank-internal (jumpform)
"Pull the text from point to the point reached by JUMPFORM.
JUMPFORM is a lambda expression that takes no arguments and returns a
"Pull rest of line from buffer into search string."
(interactive)
(isearch-yank-internal
- (lambda () (line-end-position (if (eolp) 2 1)))))
+ (lambda () (let ((inhibit-field-text-motion t))
+ (line-end-position (if (eolp) 2 1))))))
(defun isearch-search-and-update ()
;; Do the search and update the display.
(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)))
+ (not (memq (lookup-key isearch-mode-map
+ (let ((copy (copy-sequence key)))
+ (aset copy 0
+ (- main-event
+ (- ?\C-\S-a ?\C-a)))
+ copy)
+ nil)
+ '(nil
+ isearch-other-control-char)))))
(setcar keylist (- main-event (- ?\C-\S-a ?\C-a)))
(cancel-kbd-macro-events)
(apply 'isearch-unread keylist))
(t
(if isearch-forward 'search-forward 'search-backward)))))
+(defun isearch-search-string (string bound noerror)
+ ;; Search for the first occurance of STRING or its translation. If
+ ;; found, move point to the end of the occurance, update
+ ;; isearch-match-beg and isearch-match-end, and return point.
+ (let ((func (isearch-search-fun))
+ (len (length string))
+ pos1 pos2)
+ (setq pos1 (save-excursion (funcall func string bound noerror)))
+ (if (and (char-table-p translation-table-for-input)
+ (> (string-bytes string) len))
+ (let (translated match-data)
+ (dotimes (i len)
+ (let ((x (aref translation-table-for-input (aref string i))))
+ (when x
+ (or translated (setq translated (copy-sequence string)))
+ (aset translated i x))))
+ (when translated
+ (save-match-data
+ (save-excursion
+ (if (setq pos2 (funcall func translated bound noerror))
+ (setq match-data (match-data t)))))
+ (when (and pos2
+ (or (not pos1)
+ (if isearch-forward (< pos2 pos1) (> pos2 pos1))))
+ (setq pos1 pos2)
+ (set-match-data match-data)))))
+ (if pos1
+ (goto-char pos1))
+ pos1))
+
(defun isearch-search ()
;; Do the search with the current search string.
(isearch-message nil t)
(setq isearch-error nil)
(while retry
(setq isearch-success
- (funcall
- (isearch-search-fun)
- isearch-string nil t))
+ (isearch-search-string isearch-string nil t))
;; Clear RETRY unless we matched some invisible text
;; and we aren't supposed to do that.
(if (or (eq search-invisible t)
(setq found t))
(setq quote-flag nil)))
(setq i (1+ i)))
- (not found)))
+ (not (or found
+ ;; Even if there's no uppercase char, we want to detect the use
+ ;; of [:upper:] or [:lower:] char-class, which indicates
+ ;; clearly that the user cares about case distinction.
+ (and regexp-flag (string-match "\\[:\\(upp\\|low\\)er:]" string)
+ (condition-case err
+ (progn
+ (string-match (substring string 0 (match-beginning 0))
+ "")
+ nil)
+ (invalid-regexp
+ (equal "Unmatched [ or [^" (cadr err)))))))))
;; Portability functions to support various Emacs versions.
(defvar isearch-overlay nil)
(defun isearch-highlight (beg end)
- (unless (null search-highlight)
- (cond (isearch-overlay
- ;; Overlay already exists, just move it.
- (move-overlay isearch-overlay beg end (current-buffer)))
-
- (t
- ;; Overlay doesn't exist, create it.
- (setq isearch-overlay (make-overlay beg end))
- (overlay-put isearch-overlay 'face isearch)
- (overlay-put isearch-overlay 'priority 1) ;higher than lazy overlays
- ))))
+ (if search-highlight
+ (if isearch-overlay
+ ;; Overlay already exists, just move it.
+ (move-overlay isearch-overlay beg end (current-buffer))
+ ;; Overlay doesn't exist, create it.
+ (setq isearch-overlay (make-overlay beg end))
+ ;; 1001 is higher than lazy's 1000 and ediff's 100+
+ (overlay-put isearch-overlay 'priority 1001)
+ (overlay-put isearch-overlay 'face isearch))))
(defun isearch-dehighlight ()
(when isearch-overlay
(isearch-regexp isearch-lazy-highlight-regexp)
(search-spaces-regexp search-whitespace-regexp))
(condition-case nil
- (funcall (isearch-search-fun)
+ (isearch-search-string
isearch-lazy-highlight-last-string
(if isearch-forward
(min (or isearch-lazy-highlight-end-limit (point-max))
;; non-zero-length match
(let ((ov (make-overlay mb me)))
(push ov isearch-lazy-highlight-overlays)
+ ;; 1000 is higher than ediff's 100+,
+ ;; but lower than isearch main overlay's 1001
+ (overlay-put ov 'priority 1000)
(overlay-put ov 'face lazy-highlight-face)
- (overlay-put ov 'priority 0) ;lower than main overlay
(overlay-put ov 'window (selected-window))))
(if isearch-forward
(setq isearch-lazy-highlight-end (point))