(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-message-prefix-add nil) ; Additional text for the message prefix
+(defvar isearch-message-suffix-add nil) ; Additional text for the message suffix
(defvar isearch-success t) ; Searching is currently successful.
(defvar isearch-error nil) ; Error message for failed search.
(or (and transient-mark-mode mark-active)
(progn
(push-mark isearch-opoint t)
- (or executing-kbd-macro (> (minibuffer-depth) 0)
+ (or executing-kbd-macro (> (minibuffer-depth) 0) edit
(message "Mark saved where search started")))))
(and (not edit) isearch-recursive-edit (exit-recursive-edit)))
(defvar minibuffer-history-symbol) ;; from external package gmhist.el
-(defun isearch-fail-pos ()
- "Position of first mismatch in search string, or its length if none."
- (let ((cmds isearch-cmds))
- (if (and isearch-success (not isearch-error))
- (length isearch-message)
+(defun isearch-fail-pos (&optional msg)
+ "Return position of first mismatch in search string, or nil if none.
+If MSG is non-nil, use `isearch-message', otherwise `isearch-string'."
+ (let ((cmds isearch-cmds)
+ (curr-msg (if msg isearch-message isearch-string))
+ succ-msg)
+ (when (or (not isearch-success) isearch-error)
(while (or (not (isearch-success-state (car cmds)))
(isearch-error-state (car cmds)))
(pop cmds))
- (let ((succ-msg (and cmds (isearch-message-state (car cmds)))))
- (if (and (stringp succ-msg)
- (< (length succ-msg) (length isearch-message))
- (equal succ-msg
- (substring isearch-message 0 (length succ-msg))))
- (length succ-msg)
- 0)))))
+ (setq succ-msg (and cmds (if msg (isearch-message-state (car cmds))
+ (isearch-string-state (car cmds)))))
+ (if (and (stringp succ-msg)
+ (< (length succ-msg) (length curr-msg))
+ (equal succ-msg
+ (substring curr-msg 0 (length succ-msg))))
+ (length succ-msg)
+ 0))))
(defun isearch-edit-string ()
"Edit the search string in the minibuffer.
\\[isearch-nonincremental-exit-minibuffer] to do one nonincremental search.
\\[isearch-forward-exit-minibuffer] to resume isearching forward.
\\[isearch-reverse-exit-minibuffer] to resume isearching backward.
-\\[isearch-complete-edit] to complete the search string using the search ring.
-\\<isearch-mode-map>
-If first char entered is \\[isearch-yank-word-or-char], then do word search instead."
+\\[isearch-complete-edit] to complete the search string using the search ring."
;; This code is very hairy for several reasons, explained in the code.
;; Mainly, isearch-mode must be terminated while editing and then restarted.
(isearch-new-message isearch-message)
(isearch-new-forward isearch-forward)
(isearch-new-word isearch-word)
+ (isearch-new-case-fold isearch-case-fold-search)
(isearch-regexp isearch-regexp)
(isearch-op-fun isearch-op-fun)
;; Save current configuration so we can restore it here.
(isearch-window-configuration (current-window-configuration))
+ ;; This could protect the index of the search rings,
+ ;; but we can't reliably count the number of typed M-p
+ ;; in `read-from-minibuffer' to adjust the index accordingly.
+ ;; So when the following is commented out, `isearch-mode'
+ ;; below resets the index to the predictable value nil.
+ ;; (search-ring-yank-pointer search-ring-yank-pointer)
+ ;; (regexp-search-ring-yank-pointer regexp-search-ring-yank-pointer)
+
;; Temporarily restore `minibuffer-message-timeout'.
(minibuffer-message-timeout
isearch-original-minibuffer-message-timeout)
(unwind-protect
(let* ((message-log-max nil)
+ ;; Protect global value of search rings from updating
+ ;; by `read-from-minibuffer'. It should be updated only
+ ;; by `isearch-update-ring' in `isearch-done', not here.
+ (search-ring search-ring)
+ (regexp-search-ring regexp-search-ring)
;; Binding minibuffer-history-symbol to nil is a work-around
;; for some incompatibility with gmhist.
(minibuffer-history-symbol))
(setq isearch-new-string
(read-from-minibuffer
(isearch-message-prefix nil nil isearch-nonincremental)
- (cons isearch-string (1+ (isearch-fail-pos)))
+ (cons isearch-string (1+ (or (isearch-fail-pos)
+ (length isearch-string))))
minibuffer-local-isearch-map nil
(if isearch-regexp
(cons 'regexp-search-ring
(setq isearch-string isearch-new-string
isearch-message isearch-new-message
isearch-forward isearch-new-forward
- isearch-word isearch-new-word))
+ isearch-word isearch-new-word
+ isearch-case-fold-search isearch-new-case-fold))
;; Empty isearch-string means use default.
- (if (= 0 (length isearch-string))
- (setq isearch-string (or (car (if isearch-regexp
- regexp-search-ring
- search-ring))
- "")
-
- isearch-message
- (mapconcat 'isearch-text-char-description
- isearch-string ""))
- ;; This used to set the last search string,
- ;; but I think it is not right to do that here.
- ;; Only the string actually used should be saved.
- ))
+ (when (= 0 (length isearch-string))
+ (setq isearch-string (or (car (if isearch-regexp
+ regexp-search-ring
+ search-ring))
+ "")
+
+ isearch-message
+ (mapconcat 'isearch-text-char-description
+ isearch-string ""))
+ ;; After taking the last element, adjust ring to previous one.
+ (isearch-ring-adjust1 nil)))
;; This used to push the state as of before this C-s, but it adds
;; an inconsistent state where part of variables are from the
isearch-message
(mapconcat 'isearch-text-char-description
isearch-string "")
- isearch-case-fold-search isearch-last-case-fold-search))
+ isearch-case-fold-search isearch-last-case-fold-search)
+ ;; After taking the last element, adjust ring to previous one.
+ (isearch-ring-adjust1 nil))
;; If already have what to search for, repeat it.
(or isearch-success
(progn
"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
+is possible only when `isearch-allow-scroll' is non-nil, and it doesn't
+always provide 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))
(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
- ;; `isearch-no-upper-case-p' in `occur-1'
- (search-upper-case nil))
+ ;; Set `search-upper-case' to nil to not call
+ ;; `isearch-no-upper-case-p' in `occur-1'.
+ (search-upper-case nil)
+ (search-spaces-regexp (if isearch-regexp search-whitespace-regexp)))
(occur regexp nlines)))
(declare-function hi-lock-read-face-name "hi-lock" ())
;; Commands which change the window layout
(put 'delete-other-windows 'isearch-scroll t)
(put 'balance-windows 'isearch-scroll t)
+(put 'split-window-right 'isearch-scroll t)
+(put 'split-window-below 'isearch-scroll t)
+(put 'enlarge-window 'isearch-scroll t)
+
+;; Aliases for split-window-*
(put 'split-window-vertically 'isearch-scroll t)
(put 'split-window-horizontally 'isearch-scroll t)
-(put 'enlarge-window 'isearch-scroll t)
;; Universal argument commands
(put 'universal-argument 'isearch-scroll t)
(if (lookup-key global-map key)
(progn
(isearch-done)
+ (setq prefix-arg arg)
(apply 'isearch-unread keylist))
(setq keylist
(listify-key-sequence (lookup-key local-function-key-map key)))
(setq keylist (cdr keylist)))
;; As the remaining keys in KEYLIST can't be handled
;; here, we must reread them.
+ (setq prefix-arg arg)
(apply 'isearch-unread keylist)
(setq keylist nil)))))
(
isearch-other-control-char)))))
(setcar keylist (- main-event (- ?\C-\S-a ?\C-a)))
(cancel-kbd-macro-events)
+ (setq prefix-arg arg)
(apply 'isearch-unread keylist))
((eq search-exit-option 'edit)
+ (setq prefix-arg arg)
(apply 'isearch-unread keylist)
(isearch-edit-string))
;; Handle a scrolling function.
(isearch-edit-string))
(search-exit-option
(let (window)
+ (setq prefix-arg arg)
(isearch-unread-key-sequence keylist)
(setq main-event (car unread-command-events))
()
(set yank-pointer-name
(setq yank-pointer
- (mod (+ (or yank-pointer 0)
+ (mod (+ (or yank-pointer (if advance 0 -1))
(if advance -1 1))
length)))
(setq isearch-string (nth yank-pointer ring)
;; Generate and print the message string.
(let ((cursor-in-echo-area ellipsis)
(m isearch-message)
- (cmds isearch-cmds)
- succ-msg)
- (when (or (not isearch-success) isearch-error)
- ;; Highlight failed part
- (while (or (not (isearch-success-state (car cmds)))
- (isearch-error-state (car cmds)))
- (pop cmds))
- (setq succ-msg (and cmds (isearch-message-state (car cmds)))
- m (copy-sequence m))
- (add-text-properties
- (if (and (stringp succ-msg)
- (< (length succ-msg) (length m))
- (equal succ-msg (substring m 0 (length succ-msg))))
- (length succ-msg)
- 0)
- (length m) '(face isearch-fail) m)
+ (fail-pos (isearch-fail-pos t)))
+ ;; Highlight failed part
+ (when fail-pos
+ (setq m (copy-sequence m))
+ (add-text-properties fail-pos (length m) '(face isearch-fail) m)
;; Highlight failed trailing whitespace
(when (string-match " +$" m)
(add-text-properties (match-beginning 0) (match-end 0)
;; Searching
(defvar isearch-search-fun-function nil
- "Overrides the default `isearch-search-fun' behaviour.
+ "Overrides the default `isearch-search-fun' behavior.
This variable's value should be a function, which will be called
with no arguments, and should return a function that takes three
arguments: STRING, BOUND, and NOERROR.
(defvar isearch-lazy-highlight-case-fold-search nil)
(defvar isearch-lazy-highlight-regexp nil)
(defvar isearch-lazy-highlight-space-regexp nil)
+(defvar isearch-lazy-highlight-word nil)
(defvar isearch-lazy-highlight-forward nil)
(defvar isearch-lazy-highlight-error nil)
isearch-case-fold-search))
(not (eq isearch-lazy-highlight-regexp
isearch-regexp))
+ (not (eq isearch-lazy-highlight-word
+ isearch-word))
(not (= (window-start)
isearch-lazy-highlight-window-start))
(not (= (window-end) ; Window may have been split/joined.
isearch-lazy-highlight-window-end (window-end)
isearch-lazy-highlight-start (point)
isearch-lazy-highlight-end (point)
+ isearch-lazy-highlight-wrapped nil
isearch-lazy-highlight-last-string isearch-string
isearch-lazy-highlight-case-fold-search isearch-case-fold-search
- isearch-lazy-highlight-regexp isearch-regexp
- isearch-lazy-highlight-wrapped nil
+ isearch-lazy-highlight-regexp isearch-regexp
isearch-lazy-highlight-space-regexp search-whitespace-regexp
+ isearch-lazy-highlight-word isearch-word
isearch-lazy-highlight-forward isearch-forward)
(unless (equal isearch-string "")
(setq isearch-lazy-highlight-timer
(let ((case-fold-search isearch-lazy-highlight-case-fold-search)
(isearch-regexp isearch-lazy-highlight-regexp)
(search-spaces-regexp isearch-lazy-highlight-space-regexp)
+ (isearch-word isearch-lazy-highlight-word)
(search-invisible nil) ; don't match invisible text
(retry t)
(success nil)