;;; isearch.el --- incremental search minor mode
-;; Copyright (C) 1992, 93, 94, 95, 96, 97, 1999, 2000, 01, 2003
-;; Free Software Foundation, Inc.
+;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1999,
+;; 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
;; Author: Daniel LaLiberte <liberte@cs.uiuc.edu>
;; Maintainer: FSF
;; TODO
;; - Integrate the emacs 19 generalized command history.
-;; - Think about incorporating query-replace.
;; - Hooks and options for failed search.
;;; Change Log:
(define-key map " " 'isearch-whitespace-chars)
(define-key map [?\S-\ ] 'isearch-whitespace-chars)
- (define-key map "\C-w" 'isearch-yank-word-or-char)
- (define-key map "\C-y" 'isearch-yank-line)
+ (define-key map "\C-w" 'isearch-yank-word-or-char)
+ (define-key map "\M-\C-w" 'isearch-del-char)
+ (define-key map "\M-\C-y" 'isearch-yank-char)
+ (define-key map "\C-y" 'isearch-yank-line)
;; Define keys for regexp chars * ? |.
;; Nothing special for + because it matches at least once.
(define-key map "*" 'isearch-*-char)
(define-key map "?" 'isearch-*-char)
+ (define-key map "{" 'isearch-{-char)
(define-key map "|" 'isearch-|-char)
;; Turned off because I find I expect to get the global definition--rms.
(define-key map "\M-r" 'isearch-toggle-regexp)
(define-key map "\M-e" 'isearch-edit-string)
+ (define-key map [?\M-%] 'isearch-query-replace)
+ (define-key map [?\C-\M-%] 'isearch-query-replace-regexp)
+
map)
"Keymap for `isearch-mode'.")
(defvar minibuffer-local-isearch-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map minibuffer-local-map)
- (define-key map "\r" 'isearch-nonincremental-exit-minibuffer)
- (define-key map "\M-n" 'isearch-ring-advance-edit)
- (define-key map "\M-p" 'isearch-ring-retreat-edit)
+ (define-key map "\r" 'isearch-nonincremental-exit-minibuffer)
+ (define-key map "\M-n" 'isearch-ring-advance-edit)
+ (define-key map [next] 'isearch-ring-advance-edit)
+ (define-key map [down] 'isearch-ring-advance-edit)
+ (define-key map "\M-p" 'isearch-ring-retreat-edit)
+ (define-key map [prior] 'isearch-ring-retreat-edit)
+ (define-key map [up] 'isearch-ring-retreat-edit)
(define-key map "\M-\t" 'isearch-complete-edit)
- (define-key map "\C-s" 'isearch-forward-exit-minibuffer)
- (define-key map "\C-r" 'isearch-reverse-exit-minibuffer)
+ (define-key map "\C-s" 'isearch-forward-exit-minibuffer)
+ (define-key map "\C-r" 'isearch-reverse-exit-minibuffer)
+ (define-key map "\C-f" 'isearch-yank-char-in-minibuffer)
+ (define-key map [right] 'isearch-yank-char-in-minibuffer)
map)
"Keymap for editing isearch strings in the minibuffer.")
As you type characters, they add to the search string and are found.
The following non-printing keys are bound in `isearch-mode-map'.
-Type \\[isearch-delete-char] to cancel characters from end of search string.
+Type \\[isearch-delete-char] to cancel last input item from end of search string.
Type \\[isearch-exit] to exit, leaving point at location found.
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-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.
Type \\[isearch-yank-line] to yank rest of line onto end of search string\
and search for it.
Type \\[isearch-yank-kill] to yank last killed text onto end of search string\
you want to use.
The above keys, bound in `isearch-mode-map', are often controlled by
- options; do M-x apropos on search-.* to find them.
+ options; do \\[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 (equal isearch-string "")
(setq isearch-success t)
- (if (and isearch-success (equal (match-end 0) (match-beginning 0))
+ (if (and isearch-success
+ (equal (point) isearch-other-end)
(not isearch-just-started))
;; If repeating a search that found
;; an empty string, ensure we advance.
(sit-for 1)
(isearch-update))
+(defun isearch-query-replace ()
+ "Start query-replace with string to replace from last search string."
+ (interactive)
+ (barf-if-buffer-read-only)
+ (let ((case-fold-search isearch-case-fold-search))
+ (isearch-done)
+ (isearch-clean-overlays)
+ (and isearch-forward isearch-other-end (goto-char isearch-other-end))
+ (perform-replace
+ isearch-string
+ (query-replace-read-to isearch-string "Query replace" isearch-regexp)
+ t isearch-regexp isearch-word)))
+
+(defun isearch-query-replace-regexp ()
+ "Start query-replace-regexp with string to replace from last search string."
+ (interactive)
+ (let ((query-replace-interactive t)
+ (case-fold-search isearch-case-fold-search))
+ ;; Put search string into the right ring
+ (setq isearch-regexp t)
+ (isearch-done)
+ (isearch-clean-overlays)
+ (and isearch-forward isearch-other-end (goto-char isearch-other-end))
+ (call-interactively 'query-replace-regexp)))
+
+\f
(defun isearch-delete-char ()
"Discard last input item and move point back.
If no previous match was done, just beep."
(isearch-pop-state))
(isearch-update))
+(defun isearch-del-char (&optional arg)
+ "Delete character from end of search string and search again.
+If search string is empty, just beep."
+ (interactive "p")
+ (if (= 0 (length isearch-string))
+ (ding)
+ (setq isearch-string (substring isearch-string 0 (- (or arg 1)))
+ isearch-message (mapconcat 'isearch-text-char-description
+ isearch-string "")
+ ;; Don't move cursor in reverse search.
+ isearch-yank-flag t))
+ (isearch-search-and-update))
(defun isearch-yank-string (string)
"Pull STRING into search string."
(goto-char isearch-other-end))
(buffer-substring-no-properties (point) (funcall jumpform)))))
-(defun isearch-yank-char ()
- "Pull next letter from buffer into search string."
- (interactive)
- (isearch-yank-internal (lambda () (forward-char 1) (point))))
+(defun isearch-yank-char-in-minibuffer (&optional arg)
+ "Pull next character from buffer into end of search string in minibuffer."
+ (interactive "p")
+ (if (eobp)
+ (insert
+ (save-excursion
+ (set-buffer (cadr (buffer-list)))
+ (buffer-substring-no-properties
+ (point) (progn (forward-char arg) (point)))))
+ (forward-char arg)))
+
+(defun isearch-yank-char (&optional arg)
+ "Pull next character from buffer into search string."
+ (interactive "p")
+ (isearch-yank-internal (lambda () (forward-char arg) (point))))
(defun isearch-yank-word-or-char ()
"Pull next character or word from buffer into search string."
(defun isearch-search-and-update ()
;; Do the search and update the display.
(when (or isearch-success
- ;; unsuccessful regexp search may become
- ;; successful by addition of characters which
- ;; make isearch-string valid
+ ;; Unsuccessful regexp search may become successful by
+ ;; addition of characters which make isearch-string valid
isearch-regexp
;; If the string was found but was completely invisible,
;; it might now be partly visible, so try again.
(isearch-update))
+(defun isearch-{-char ()
+ "Handle \{ specially in regexps."
+ (interactive)
+ (isearch-*-char t))
+
;; *, ?, and | chars can make a regexp more liberal.
;; They can make a regexp match sooner or make it succeed instead of failing.
;; So go back to place last successful search started
;; or to the last ^S/^R (barrier), whichever is nearer.
;; + needs no special handling because the string must match at least once.
-(defun isearch-*-char ()
- "Handle * and ? specially in regexps."
+(defun isearch-*-char (&optional want-backslash)
+ "Handle * and ? specially in regexps.
+When WANT-BACKSLASH is non-nil, do special handling for \{."
(interactive)
(if isearch-regexp
(let ((idx (length isearch-string)))
(while (and (> idx 0)
(eq (aref isearch-string (1- idx)) ?\\))
(setq idx (1- idx)))
- (when (= (mod (- (length isearch-string) idx) 2) 0)
+ ;; * and ? are special when not preceded by \.
+ ;; { is special when it is preceded by \.
+ (when (= (mod (- (length isearch-string) idx) 2)
+ (if want-backslash 1 0))
(setq isearch-adjusted t)
;; Get the isearch-other-end from before the last search.
;; We want to start from there,
(command-execute scroll-command)
(let ((ab-bel (isearch-string-out-of-window isearch-point)))
(if ab-bel
- (isearch-back-into-window (eq ab-bel 'above) isearch-point)))
+ (isearch-back-into-window (eq ab-bel 'above) isearch-point)
+ (or (eq (point) isearch-point)
+ (goto-char isearch-point))))
(isearch-update))
(search-exit-option
(let (window)
(let ((cursor-in-echo-area ellipsis)
(m (concat
(isearch-message-prefix c-q-hack ellipsis isearch-nonincremental)
- isearch-message
+ (if (and (not isearch-success)
+ (string-match " +$" isearch-message))
+ (concat
+ (substring isearch-message 0 (match-beginning 0))
+ (propertize (substring isearch-message (match-beginning 0))
+ 'face 'trailing-whitespace))
+ isearch-message)
(isearch-message-suffix c-q-hack ellipsis)
)))
(if c-q-hack
\f
;; Searching
-(defvar isearch-search-fun-function nil "Override `isearch-function-fun'.")
+(defvar isearch-search-fun-function nil
+ "Override `isearch-search-fun'.
+This function should return the search function for isearch to use.
+It will call this function with three arguments
+as if it were `search-forward'.")
(defun isearch-search-fun ()
"Return the function to use for the search.
:group 'isearch)
(defface isearch
- '((((type tty pc) (class color))
- (:background "magenta4" :foreground "cyan1"))
- (((class color) (background light))
+ '((((class color) (min-colors 88) (background light))
;; The background must not be too dark, for that means
;; the character is hard to see when the cursor is there.
(:background "magenta2" :foreground "lightskyblue1"))
- (((class color) (background dark))
+ (((class color) (min-colors 88) (background dark))
(:background "palevioletred2" :foreground "brown4"))
+ (((class color) (min-colors 16))
+ (:background "magenta4" :foreground "cyan1"))
+ (((class color) (min-colors 8))
+ (:background "magenta4" :foreground "cyan1"))
(t (:inverse-video t)))
"Face for highlighting Isearch matches."
:group 'isearch-faces)
(defvar isearch 'isearch)
(defface isearch-lazy-highlight-face
- '((((type tty pc) (class color))
- (:background "turquoise3"))
- (((class color) (background light))
+ '((((class color) (min-colors 88) (background light))
(:background "paleturquoise"))
- (((class color) (background dark))
+ (((class color) (min-colors 88) (background dark))
(:background "paleturquoise4"))
+ (((class color) (min-colors 16))
+ (:background "turquoise3"))
+ (((class color) (min-colors 8))
+ (:background "turquoise3"))
(t (:underline t)))
"Face for lazy highlighting of Isearch matches other than the current one."
:group 'isearch-faces)
isearch-case-fold-search case-fold)
(isearch-search))
-;;; arch-tag: 74850515-f7d8-43a6-8a2c-ca90a4c1e675
+;; arch-tag: 74850515-f7d8-43a6-8a2c-ca90a4c1e675
;;; isearch.el ends here