(define-key map "\M-r" 'isearch-toggle-regexp)
(define-key map "\M-e" 'isearch-edit-string)
+ (define-key map "\M-sr" 'isearch-toggle-regexp)
+ (define-key map "\M-sw" 'isearch-toggle-word)
+
(define-key map [?\M-%] 'isearch-query-replace)
(define-key map [?\C-\M-%] 'isearch-query-replace-regexp)
(define-key map "\M-so" 'isearch-occur)
(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-w" 'isearch-edit-string-set-word)
(define-key map "\C-f" 'isearch-yank-char-in-minibuffer)
(define-key map [right] 'isearch-yank-char-in-minibuffer)
map)
(defvar isearch-string "") ; The current search string.
(defvar isearch-message "") ; text-char-description version of isearch-string
+(defvar isearch-message-prefix-add nil) ; Additonal text for the message prefix
+(defvar isearch-message-suffix-add nil) ; Additonal text for the message suffix
+
(defvar isearch-success t) ; Searching is currently successful.
(defvar isearch-error nil) ; Error message for failed search.
(defvar isearch-other-end nil) ; Start (end) of match if forward (backward).
(define-key esc-map "\C-s" 'isearch-forward-regexp)
(define-key global-map "\C-r" 'isearch-backward)
(define-key esc-map "\C-r" 'isearch-backward-regexp)
+(define-key search-map "w" 'isearch-forward-word)
;; Entry points to isearch-mode.
If you try to exit with the search string still empty, it invokes
nonincremental search.
-Type \\[isearch-query-replace] to start `query-replace' with string to\
- replace from last search string.
-Type \\[isearch-query-replace-regexp] to start `query-replace-regexp'\
- with string to replace from last search string.
-
Type \\[isearch-toggle-case-fold] to toggle search case-sensitivity.
Type \\[isearch-toggle-regexp] to toggle regular-expression mode.
+Type \\[isearch-toggle-word] to toggle word mode.
Type \\[isearch-edit-string] to edit the search string in the minibuffer.
Also supported is a search ring of the previous 16 search strings.
ring.
Type \\[isearch-complete] to complete the search string using the search ring.
+Type \\[isearch-query-replace] to run `query-replace' with string to\
+ replace from last search string.
+Type \\[isearch-query-replace-regexp] to run `query-replace-regexp'\
+ with the last search string.
+Type \\[isearch-occur] to run `occur' that shows\
+ the last search string.
+Type \\[isearch-highlight-regexp] to run `highlight-regexp'\
+ that highlights the last search string.
+
Type \\[isearch-describe-bindings] to display all isearch key bindings.
Type \\[isearch-describe-key] to display documentation of isearch key.
Type \\[isearch-describe-mode] to display documentation of isearch mode.
"\
Do incremental search forward for regular expression.
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.
+Like ordinary incremental search except that your input is treated
+as a regexp. See the command `isearch-forward' for more information.
In regexp incremental searches, a space or spaces normally matches
any whitespace (the variable `search-whitespace-regexp' controls
(interactive "P\np")
(isearch-mode t (null not-regexp) nil (not no-recursive-edit)))
+(defun isearch-forward-word (&optional not-word no-recursive-edit)
+ "\
+Do incremental search forward for a sequence of words.
+With a prefix argument, do a regular string search instead.
+Like ordinary incremental search except that your input is treated
+as a sequence of words without regard to how the words are separated.
+See the command `isearch-forward' for more information."
+ (interactive "P\np")
+ (isearch-mode t nil nil (not no-recursive-edit) (null not-word)))
+
(defun isearch-backward (&optional regexp-p no-recursive-edit)
"\
Do incremental search backward.
With a prefix argument, do a regular expression search instead.
-See \\[isearch-forward] for more information."
+See the command `isearch-forward' for more information."
(interactive "P\np")
(isearch-mode nil (not (null regexp-p)) nil (not no-recursive-edit)))
"\
Do incremental search backward for regular expression.
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."
+Like ordinary incremental search except that your input is treated
+as a regexp. See the command `isearch-forward' for more information."
(interactive "P\np")
(isearch-mode nil (null not-regexp) nil (not no-recursive-edit)))
;; that can change their values.
(setq old-point (point) old-other-end isearch-other-end)
- (isearch-message) ;; for read-char
(unwind-protect
- (let* (;; Why does following read-char echo?
- ;;(echo-keystrokes 0) ;; not needed with above message
- (e (let ((cursor-in-echo-area t))
- (read-event)))
+ (let* ((message-log-max nil)
;; Binding minibuffer-history-symbol to nil is a work-around
;; for some incompatibility with gmhist.
- (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
- ;; read a key the normal way.
- ;; Word search does not apply (yet) to regexp searches,
- ;; no check is made here.
- (message "%s" (isearch-message-prefix nil nil t))
- (if (memq (lookup-key isearch-mode-map (vector e))
- '(isearch-yank-word
- isearch-yank-word-or-char))
- (setq isearch-word t;; so message-prefix is right
- isearch-new-word t)
- (cancel-kbd-macro-events)
- (isearch-unread e))
- (setq cursor-in-echo-area nil)
+ (minibuffer-history-symbol))
(setq isearch-new-string
(read-from-minibuffer
(isearch-message-prefix nil nil isearch-nonincremental)
(isearch-abort) ;; outside of let to restore outside global values
)))
+;; Obsolete usage of `C-s M-e C-w'. Remove after 23.1.
+(defvar isearch-new-word)
+(defun isearch-edit-string-set-word ()
+ "Do word search after exiting `isearch-edit-string'."
+ (interactive)
+ (message "This feature is obsolete since 23.1; use `M-s w' instead.")
+ (setq isearch-word t isearch-new-word t))
+
+
(defun isearch-nonincremental-exit-minibuffer ()
(interactive)
(setq isearch-nonincremental t)
(setq isearch-success t isearch-adjusted t)
(isearch-update))
+(defun isearch-toggle-word ()
+ "Toggle word searching on or off."
+ (interactive)
+ (setq isearch-word (not isearch-word))
+ (setq isearch-success t isearch-adjusted t)
+ (isearch-update))
+
(defun isearch-toggle-case-fold ()
"Toggle case folding in searching on or off."
(interactive)
(sit-for 1)
(isearch-update))
-(defun isearch-query-replace (&optional regexp-flag)
- "Start `query-replace' with string to replace from last search string."
- (interactive)
+(defun isearch-query-replace (&optional delimited regexp-flag)
+ "Start `query-replace' with string to replace from last search string.
+The arg DELIMITED (prefix arg if interactive), if non-nil, means replace
+only matches surrounded by word boundaries. Note that using the prefix arg
+is possible only when `isearch-allow-scroll' is non-nil, and it don't
+always provides the correct matches for `query-replace', so the preferred
+way to run word replacements from Isearch is `M-s w ... M-%'."
+ (interactive
+ (list current-prefix-arg))
(barf-if-buffer-read-only)
(if regexp-flag (setq isearch-regexp t))
(let ((case-fold-search isearch-case-fold-search)
;; set `search-upper-case' to nil to not call
;; `isearch-no-upper-case-p' in `perform-replace'
- (search-upper-case nil))
- (isearch-done)
+ (search-upper-case nil)
+ ;; Set `isearch-recursive-edit' to nil to prevent calling
+ ;; `exit-recursive-edit' in `isearch-done' that terminates
+ ;; the execution of this command when it is non-nil.
+ ;; We call `exit-recursive-edit' explicitly at the end below.
+ (isearch-recursive-edit nil))
+ (isearch-done nil t)
(isearch-clean-overlays)
(if (and isearch-other-end
(< isearch-other-end (point))
isearch-string
(query-replace-read-to
isearch-string
- (if isearch-regexp "Query replace regexp" "Query replace")
+ (concat "Query replace"
+ (if (or delimited isearch-word) " word" "")
+ (if isearch-regexp " regexp" "")
+ (if (and transient-mark-mode mark-active) " in region" ""))
isearch-regexp)
- t isearch-regexp isearch-word nil nil
+ t isearch-regexp (or delimited isearch-word) nil nil
(if (and transient-mark-mode mark-active) (region-beginning))
- (if (and transient-mark-mode mark-active) (region-end)))))
+ (if (and transient-mark-mode mark-active) (region-end))))
+ (and isearch-recursive-edit (exit-recursive-edit)))
-(defun isearch-query-replace-regexp ()
- "Start `query-replace-regexp' with string to replace from last search string."
- (interactive)
- (isearch-query-replace t))
+(defun isearch-query-replace-regexp (&optional delimited)
+ "Start `query-replace-regexp' with string to replace from last search string.
+See `isearch-query-replace' for more information."
+ (interactive
+ (list current-prefix-arg))
+ (isearch-query-replace delimited t))
(defun isearch-occur (regexp &optional nlines)
"Run `occur' with regexp to search from the current search string.
string. NLINES has the same meaning as in `occur'."
(interactive
(list
- (if isearch-regexp isearch-string (regexp-quote isearch-string))
+ (cond
+ (isearch-word (concat "\\b" (regexp-quote isearch-string) "\\b"))
+ (isearch-regexp isearch-string)
+ (t (regexp-quote isearch-string)))
(if current-prefix-arg (prefix-numeric-value current-prefix-arg))))
(let ((case-fold-search isearch-case-fold-search)
;; set `search-upper-case' to nil to not call
(declare-function hi-lock-regexp-okay "hi-lock" (regexp))
(declare-function hi-lock-read-face-name "hi-lock" ())
-(defun isearch-highlight-regexp (regexp &optional face)
+(defun isearch-highlight-regexp ()
"Run `highlight-regexp' with regexp from the current search string.
-Interactively, REGEXP is the current search regexp or a quoted search
-string. FACE has the same meaning as in `highlight-regexp'."
- (interactive
- (list
- (progn
- (require 'hi-lock nil t)
- (hi-lock-regexp-okay
- (if isearch-regexp isearch-string (regexp-quote isearch-string))))
- (hi-lock-read-face-name)))
- (isearch-done)
- (isearch-clean-overlays)
- ;; (add-to-history 'hi-lock-regexp-history regexp)
- (let ((case-fold-search isearch-case-fold-search))
- (hi-lock-face-buffer regexp face)))
+It exits Isearch mode and calls `hi-lock-face-buffer' with its regexp
+argument from the last search regexp or a quoted search string,
+and reads its face argument using `hi-lock-read-face-name'."
+ (interactive)
+ (let (
+ ;; Set `isearch-recursive-edit' to nil to prevent calling
+ ;; `exit-recursive-edit' in `isearch-done' that terminates
+ ;; the execution of this command when it is non-nil.
+ ;; We call `exit-recursive-edit' explicitly at the end below.
+ (isearch-recursive-edit nil))
+ (isearch-done nil t)
+ (isearch-clean-overlays))
+ (require 'hi-lock nil t)
+ (let ((string (cond (isearch-regexp isearch-string)
+ ((if (and (eq isearch-case-fold-search t)
+ search-upper-case)
+ (isearch-no-upper-case-p
+ isearch-string isearch-regexp)
+ isearch-case-fold-search)
+ ;; Turn isearch-string into a case-insensitive
+ ;; regexp.
+ (mapconcat
+ (lambda (c)
+ (let ((s (string c)))
+ (if (string-match "[[:alpha:]]" s)
+ (format "[%s%s]" (upcase s) (downcase s))
+ (regexp-quote s))))
+ isearch-string ""))
+ (t (regexp-quote isearch-string)))))
+ (hi-lock-face-buffer string (hi-lock-read-face-name)))
+ (and isearch-recursive-edit (exit-recursive-edit)))
\f
(defun isearch-delete-char ()
;; Scroll-bar functions:
(if (fboundp 'scroll-bar-toolkit-scroll)
(put 'scroll-bar-toolkit-scroll 'isearch-scroll t))
-(if (fboundp 'mac-handle-scroll-bar-event)
- (put 'mac-handle-scroll-bar-event 'isearch-scroll t))
(if (fboundp 'w32-handle-scroll-bar-event)
(put 'w32-handle-scroll-bar-event 'isearch-scroll t))
(if isearch-wrapped "wrapped ")
(if isearch-word "word " "")
(if isearch-regexp "regexp " "")
+ (if multi-isearch-next-buffer-current-function "multi " "")
+ (or isearch-message-prefix-add "")
(if nonincremental "search" "I-search")
(if isearch-forward "" " backward")
(if current-input-method
(concat (if c-q-hack "^Q" "")
(if isearch-error
(concat " [" isearch-error "]")
- "")))
+ "")
+ (or isearch-message-suffix-add "")))
\f
;; Searching
(funcall isearch-search-fun-function)
(cond
(isearch-word
- (if isearch-forward 'word-search-forward 'word-search-backward))
+ ;; Use lax versions to not fail at the end of the word while the user
+ ;; adds and removes characters in the search string
+ (if (not (eq (length isearch-string)
+ (length (isearch-string-state (car isearch-cmds)))))
+ (if isearch-forward 'word-search-forward-lax 'word-search-backward-lax)
+ (if isearch-forward 'word-search-forward 'word-search-backward)))
(isearch-regexp
(if isearch-forward 're-search-forward 're-search-backward))
(t
(when pos1
;; When using multiple buffers isearch, switch to the new buffer here,
;; because `save-excursion' above doesn't allow doing it inside funcall.
- (if (and isearch-buffers-next-buffer-function
- (buffer-live-p isearch-buffers-current-buffer))
- (switch-to-buffer isearch-buffers-current-buffer))
+ (if (and multi-isearch-next-buffer-current-function
+ (buffer-live-p multi-isearch-current-buffer))
+ (switch-to-buffer multi-isearch-current-buffer))
(goto-char pos1))
pos1))
(defun isearch-lazy-highlight-search ()
"Search ahead for the next or previous match, for lazy highlighting.
Attempt to do the search exactly the way the pending isearch would."
- (let ((case-fold-search isearch-lazy-highlight-case-fold-search)
- (isearch-regexp isearch-lazy-highlight-regexp)
- (search-spaces-regexp isearch-lazy-highlight-space-regexp))
- (condition-case nil
- (isearch-search-string
- isearch-lazy-highlight-last-string
- (if isearch-forward
- (min (or isearch-lazy-highlight-end-limit (point-max))
+ (condition-case nil
+ (let ((case-fold-search isearch-lazy-highlight-case-fold-search)
+ (isearch-regexp isearch-lazy-highlight-regexp)
+ (search-spaces-regexp isearch-lazy-highlight-space-regexp)
+ (search-invisible nil) ; don't match invisible text
+ (retry t)
+ (success nil)
+ (bound (if isearch-forward
+ (min (or isearch-lazy-highlight-end-limit (point-max))
+ (if isearch-lazy-highlight-wrapped
+ isearch-lazy-highlight-start
+ (window-end)))
+ (max (or isearch-lazy-highlight-start-limit (point-min))
(if isearch-lazy-highlight-wrapped
- isearch-lazy-highlight-start
- (window-end)))
- (max (or isearch-lazy-highlight-start-limit (point-min))
- (if isearch-lazy-highlight-wrapped
- isearch-lazy-highlight-end
- (window-start))))
- t)
- (error nil))))
+ isearch-lazy-highlight-end
+ (window-start))))))
+ ;; Use a loop like in `isearch-search'
+ (while retry
+ (setq success (isearch-search-string
+ isearch-lazy-highlight-last-string bound t))
+ (if (or (not success)
+ (funcall isearch-success-function
+ (match-beginning 0) (match-end 0)))
+ (setq retry nil)))
+ success)
+ (error nil)))
(defun isearch-lazy-highlight-update ()
"Update highlighting of other matches for current search."