;;; isearch.el --- incremental search minor mode
-;; Copyright (C) 1992-1997, 1999-2015 Free Software Foundation, Inc.
+;; Copyright (C) 1992-1997, 1999-2016 Free Software Foundation, Inc.
;; Author: Daniel LaLiberte <liberte@cs.uiuc.edu>
;; Maintainer: emacs-devel@gnu.org
;; is completed. It uses a recursive-edit to behave this way.
;; The key bindings active within isearch-mode are defined below in
-;; `isearch-mode-map' which is given bindings close to the default
-;; characters of the original isearch.el. With `isearch-mode',
-;; however, you can bind multi-character keys and it should be easier
-;; to add new commands. One bug though: keys with meta-prefix cannot
-;; be longer than two chars. Also see minibuffer-local-isearch-map
+;; `isearch-mode-map'. Also see minibuffer-local-isearch-map
;; for bindings active during `isearch-edit-string'.
;; isearch-mode should work even if you switch windows with the mouse,
(defcustom search-nonincremental-instead t
"If non-nil, do a nonincremental search instead of exiting immediately.
-Actually, `isearch-edit-string' is called to let you enter the search
-string, and RET terminates editing and does a nonincremental search."
+This affects the behavior of `isearch-exit' and any key bound to that
+command: if this variable is nil, `isearch-exit' always exits the search;
+if the value is non-nil, and the search string is empty, `isearch-exit'
+starts a nonincremental search instead. (Actually, `isearch-edit-string'
+is called to let you enter the search string, and RET terminates editing
+and does a nonincremental search.)"
:type 'boolean)
(defcustom search-whitespace-regexp (purecopy "\\s-+")
(defcustom isearch-hide-immediately t
"If non-nil, re-hide an invisible match right away.
This variable makes a difference when `search-invisible' is set to `open'.
+If non-nil, invisible matches are re-hidden as soon as the match moves
+off the invisible text surrounding the match.
If nil then do not re-hide opened invisible text when the match moves.
Whatever the value, all opened invisible text is hidden again after exiting
-the search."
+the search, with the exception of the last successful match, if any."
:type 'boolean)
(defcustom isearch-resume-in-command-history nil
(autoload 'character-fold-to-regexp "character-fold")
-(defcustom search-default-regexp-mode #'character-fold-to-regexp
+(defcustom search-default-mode nil
"Default mode to use when starting isearch.
Value is nil, t, or a function.
isearch).
If a function, use that function as an `isearch-regexp-function'.
-Example functions are `word-search-regexp' \(`\\[isearch-toggle-word]'),
-`isearch-symbol-regexp' \(`\\[isearch-toggle-symbol]'), and
-`character-fold-to-regexp' \(`\\[isearch-toggle-character-fold]')."
- ;; :type is set below by `isearch-specify-regexp-function'.
+Example functions (and the keys to toggle them during isearch)
+are `word-search-regexp' \(`\\[isearch-toggle-word]'), `isearch-symbol-regexp'
+\(`\\[isearch-toggle-symbol]'), and `character-fold-to-regexp' \(`\\[isearch-toggle-character-fold]')."
+ ;; :type is set below by `isearch-define-mode-toggle'.
:type '(choice (const :tag "Literal search" nil)
(const :tag "Regexp search" t)
(function :tag "Other"))
(define-key map "\M-r" 'isearch-toggle-regexp)
(define-key map "\M-e" 'isearch-edit-string)
- (put 'isearch-toggle-case-fold :advertised-binding "\M-sc")
- (put 'isearch-toggle-regexp :advertised-binding "\M-sr")
(put 'isearch-edit-string :advertised-binding "\M-se")
(define-key map "\M-se" 'isearch-edit-string)
- (define-key map "\M-sc" 'isearch-toggle-case-fold)
- (define-key map "\M-si" 'isearch-toggle-invisible)
- (define-key map "\M-sr" 'isearch-toggle-regexp)
- (define-key map "\M-s " 'isearch-toggle-lax-whitespace)
- ;; More toggles defined by `isearch-specify-regexp-function'.
+ ;; More toggles defined by `isearch-define-mode-toggle'.
(define-key map [?\M-%] 'isearch-query-replace)
(define-key map [?\C-\M-%] 'isearch-query-replace-regexp)
called to convert a plain search string to a regexp used by
regexp search functions.
The symbol property `isearch-message-prefix' put on this function
-specifies the prefix string displayed in the search message.")
+specifies the prefix string displayed in the search message.
+
+This variable is set and changed during isearch. To change the
+default behaviour used for searches, see `search-default-mode'
+instead.")
;; We still support setting this to t for backwards compatibility.
(define-obsolete-variable-alias 'isearch-word
'isearch-regexp-function "25.1")
In incremental searches, a space or spaces normally matches any
whitespace defined by the variable `search-whitespace-regexp'.
To search for a literal space and nothing else, enter C-q SPC.
-To toggle whitespace matching, use `isearch-toggle-lax-whitespace'."
+To toggle whitespace matching, use `isearch-toggle-lax-whitespace'.
+This command does not support character folding."
(interactive "P\np")
(isearch-mode t (null not-regexp) nil (not no-recursive-edit)))
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."
+See the command `isearch-forward' for more information.
+This command does not support character folding, and lax space matching
+has no effect on it."
(interactive "P\np")
(isearch-mode t nil nil (not no-recursive-edit) (null not-word)))
The prefix argument is currently unused.
Like ordinary incremental search except that your input is treated
as a symbol surrounded by symbol boundary constructs \\_< and \\_>.
-See the command `isearch-forward' for more information."
+See the command `isearch-forward' for more information.
+This command does not support character folding, and lax space matching
+has no effect on it."
(interactive "P\np")
(isearch-mode t nil nil (not no-recursive-edit) 'isearch-symbol-regexp))
"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 the command `isearch-forward' for more information."
+as a regexp. See the command `isearch-forward-regexp' for more information."
(interactive "P\np")
(isearch-mode nil (null not-regexp) nil (not no-recursive-edit)))
(isearch-update)))))
\f
-(defvar cursor-sensor-inhibit)
;; isearch-mode only sets up incremental search for the minor mode.
;; All the work is done by the isearch-mode commands.
(setq isearch-forward forward
isearch-regexp (or regexp
(and (not regexp-function)
- (eq search-default-regexp-mode t)))
+ (eq search-default-mode t)))
isearch-regexp-function (or regexp-function
- (and (functionp search-default-regexp-mode)
+ (and (functionp search-default-mode)
(not regexp)
- search-default-regexp-mode))
+ search-default-mode))
isearch-op-fun op-fun
isearch-last-case-fold-search isearch-case-fold-search
isearch-case-fold-search case-fold-search
(defun isearch-update ()
"This is called after every isearch command to update the display.
-The last thing it does is to run `isearch-update-post-hook'."
+The second last thing it does is to run `isearch-update-post-hook'.
+The last thing is to trigger a new round of lazy highlighting."
(unless (eq (current-buffer) isearch--current-buffer)
- (when isearch--current-buffer
+ (when (buffer-live-p isearch--current-buffer)
(with-current-buffer isearch--current-buffer
(setq cursor-sensor-inhibit (delq 'isearch cursor-sensor-inhibit))))
(setq isearch--current-buffer (current-buffer))
(make-local-variable 'cursor-sensor-inhibit)
- (unless (boundp 'cursor-sensor-inhibit)
- (setq cursor-sensor-inhibit nil))
;; Suspend things like cursor-intangible during Isearch so we can search
;; even within intangible text.
(push 'isearch cursor-sensor-inhibit))
(null executing-kbd-macro))
(progn
(if (not (input-pending-p))
- (if isearch-message-function
- (funcall isearch-message-function)
- (isearch-message)))
+ (funcall (or isearch-message-function #'isearch-message)))
(if (and isearch-slow-terminal-mode
(not (or isearch-small-window
- (pos-visible-in-window-p))))
+ (pos-visible-in-window-group-p))))
(let ((found-point (point)))
(setq isearch-small-window t)
(move-to-window-line 0)
(let ((current-scroll (window-hscroll))
visible-p)
(set-window-hscroll (selected-window) isearch-start-hscroll)
- (setq visible-p (pos-visible-in-window-p nil nil t))
+ (setq visible-p (pos-visible-in-window-group-p nil nil t))
(if (or (not visible-p)
;; When point is not visible because of hscroll,
- ;; pos-visible-in-window-p returns non-nil, but
+ ;; pos-visible-in-window-group-p returns non-nil, but
;; the X coordinate it returns is 1 pixel beyond
;; the last visible one.
(>= (car visible-p) (window-body-width nil t)))
(setq ;; quit-flag nil not for isearch-mode
isearch-adjusted nil
isearch-yank-flag nil)
- (when isearch-lazy-highlight
- (isearch-lazy-highlight-new-loop))
;; We must prevent the point moving to the end of composition when a
;; part of the composition has just been searched.
(setq disable-point-adjustment t)
- (run-hooks 'isearch-update-post-hook))
+ (run-hooks 'isearch-update-post-hook)
+ (when isearch-lazy-highlight
+ (isearch-lazy-highlight-new-loop)))
(defun isearch-done (&optional nopush edit)
"Exit Isearch mode.
(setq minibuffer-message-timeout isearch-original-minibuffer-message-timeout)
(isearch-dehighlight)
(lazy-highlight-cleanup lazy-highlight-cleanup)
- (let ((found-start (window-start))
+ (let ((found-start (window-group-start))
(found-point (point)))
(when isearch-window-configuration
(set-window-configuration isearch-window-configuration)
;; 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))))
+ (set-window-group-start (selected-window) found-start t))))
(setq isearch-mode nil)
(if isearch-input-method-local-p
(length succ-msg)
0))))
+(defvar isearch-new-regexp-function nil
+ "Holds the next `isearch-regexp-function' inside `with-isearch-suspended'.
+If this is set inside code wrapped by the macro
+`with-isearch-suspended', then the value set will be used as the
+`isearch-regexp-function' once isearch resumes.")
+(define-obsolete-variable-alias 'isearch-new-word
+ 'isearch-new-regexp-function "25.1")
+
(defmacro with-isearch-suspended (&rest body)
"Exit Isearch mode, run BODY, and reinvoke the pending search.
You can update the global isearch variables by setting new values to
(unwind-protect
(progn ,@body)
- ;; Set point at the start (end) of old match if forward (backward),
- ;; so after exiting minibuffer isearch resumes at the start (end)
- ;; of this match and can find it again.
- (if (and old-other-end (eq old-point (point))
- (eq isearch-forward isearch-new-forward))
- (goto-char old-other-end))
-
;; Always resume isearching by restarting it.
(isearch-mode isearch-forward
isearch-regexp
isearch-message isearch-new-message
isearch-forward isearch-new-forward
isearch-regexp-function isearch-new-regexp-function
- isearch-case-fold-search isearch-new-case-fold))
+ isearch-case-fold-search isearch-new-case-fold)
+
+ ;; Restore the minibuffer message before moving point.
+ (funcall (or isearch-message-function #'isearch-message) nil t)
+
+ ;; Set point at the start (end) of old match if forward (backward),
+ ;; so after exiting minibuffer isearch resumes at the start (end)
+ ;; of this match and can find it again.
+ (if (and old-other-end (eq old-point (point))
+ (eq isearch-forward isearch-new-forward))
+ (goto-char old-other-end)))
;; Empty isearch-string means use default.
(when (= 0 (length isearch-string))
(interactive)
(isearch-repeat 'backward))
-(defun isearch-toggle-regexp ()
- "Toggle regexp searching on or off."
- ;; The status stack is left unchanged.
- (interactive)
- (setq isearch-regexp (not isearch-regexp))
- (if isearch-regexp (setq isearch-regexp-function nil))
- (setq isearch-success t isearch-adjusted t)
- (isearch-update))
-
-;;; Toggles for `isearch-regexp-function' and `search-default-regexp-mode'.
-(defmacro isearch-specify-regexp-function (mode function key)
- "Define a search MODE in which `isearch-regexp-function' is set to FUNCTION.
-Define a command called `isearch-toggle-MODE' and bind it to
-`isearch-mode-map' under `M-s KEY'.
-Also set the `isearch-message-prefix' property of FUNCTION."
- (let ((command-name (intern (format "isearch-toggle-%s" mode))))
+\f
+;;; Toggles for `isearch-regexp-function' and `search-default-mode'.
+(defmacro isearch-define-mode-toggle (mode key function &optional docstring &rest body)
+ "Define a command called `isearch-toggle-MODE' and bind it to `M-s KEY'.
+The first line of the command's docstring is auto-generated, the
+remainder may be provided in DOCSTRING.
+If FUNCTION is a symbol, this command first toggles the value of
+`isearch-regexp-function' between nil and FUNCTION. Also set the
+`isearch-message-prefix' property of FUNCTION.
+The command then executes BODY and updates the isearch prompt."
+ (declare (indent defun))
+ (let ((command-name (intern (format "isearch-toggle-%s" mode)))
+ (key (concat "\M-s" key)))
`(progn
(defun ,command-name ()
- ,(format "Toggle %s searching on or off." mode)
+ ,(format "Toggle %s searching on or off.%s" mode
+ (if docstring (concat "\n" docstring) ""))
(interactive)
- (setq isearch-regexp-function
- (unless (eq isearch-regexp-function #',function)
- #',function))
- (when isearch-regexp-function (setq isearch-regexp nil))
+ ,@(when function
+ `((setq isearch-regexp-function
+ (unless (eq isearch-regexp-function #',function)
+ #',function))
+ (setq isearch-regexp nil)))
+ ,@body
(setq isearch-success t isearch-adjusted t)
(isearch-update))
- (define-key isearch-mode-map ,(concat "\M-s" key) #',command-name)
- (put ',function 'isearch-message-prefix ,(format "%s " mode))
- (cl-callf (lambda (types) (cons 'choice
- (cons '(const :tag ,(capitalize (format "%s search" mode)) ,function)
- (cdr types))))
- (get 'search-default-regexp-mode 'custom-type)))))
-
-(isearch-specify-regexp-function word word-search-regexp "w")
-(isearch-specify-regexp-function symbol isearch-symbol-regexp "_")
-(isearch-specify-regexp-function character-fold character-fold-to-regexp "'")
+ (define-key isearch-mode-map ,key #',command-name)
+ ,@(when (and function (symbolp function))
+ `((put ',function 'isearch-message-prefix ,(format "%s " mode))
+ (put ',function :advertised-binding ,key)
+ (cl-callf (lambda (types) (cons 'choice
+ (cons '(const :tag ,(capitalize (format "%s search" mode)) ,function)
+ (cdr types))))
+ (get 'search-default-mode 'custom-type)))))))
+
+(isearch-define-mode-toggle word "w" word-search-regexp "\
+Turning on word search turns off regexp mode.")
+(isearch-define-mode-toggle symbol "_" isearch-symbol-regexp "\
+Turning on symbol search turns off regexp mode.")
+(isearch-define-mode-toggle character-fold "'" character-fold-to-regexp "\
+Turning on character-folding turns off regexp mode.")
(put 'character-fold-to-regexp 'isearch-message-prefix "char-fold ")
-(defun isearch-toggle-lax-whitespace ()
- "Toggle whitespace matching in searching on or off.
-In ordinary search, toggles the value of the variable
-`isearch-lax-whitespace'. In regexp search, toggles the
-value of the variable `isearch-regexp-lax-whitespace'."
- (interactive)
- (if isearch-regexp
- (setq isearch-regexp-lax-whitespace (not isearch-regexp-lax-whitespace))
- (setq isearch-lax-whitespace (not isearch-lax-whitespace)))
- (let ((message-log-max nil))
- (message "%s%s [%s]"
- (isearch-message-prefix nil isearch-nonincremental)
- isearch-message
- (if (if isearch-regexp
- isearch-regexp-lax-whitespace
- isearch-lax-whitespace)
- "match spaces loosely"
- "match spaces literally")))
- (setq isearch-success t isearch-adjusted t)
- (sit-for 1)
- (isearch-update))
+(isearch-define-mode-toggle regexp "r" nil nil
+ (setq isearch-regexp (not isearch-regexp))
+ (if isearch-regexp (setq isearch-regexp-function nil)))
-(defun isearch-toggle-case-fold ()
- "Toggle case folding in searching on or off.
-Toggles the value of the variable `isearch-case-fold-search'."
- (interactive)
- (setq isearch-case-fold-search
- (if isearch-case-fold-search nil 'yes))
+(defun isearch--momentary-message (string)
+ "Print STRING at the end of the isearch prompt for 1 second"
(let ((message-log-max nil))
- (message "%s%s [case %ssensitive]"
- (isearch-message-prefix nil isearch-nonincremental)
- isearch-message
- (if isearch-case-fold-search "in" "")))
- (setq isearch-success t isearch-adjusted t)
- (sit-for 1)
- (isearch-update))
+ (message "%s%s [%s]"
+ (isearch-message-prefix nil isearch-nonincremental)
+ isearch-message
+ string))
+ (sit-for 1))
-(defun isearch-toggle-invisible ()
- "Toggle searching in invisible text on or off.
+(isearch-define-mode-toggle lax-whitespace " " nil
+ "In ordinary search, toggles the value of the variable
+`isearch-lax-whitespace'. In regexp search, toggles the
+value of the variable `isearch-regexp-lax-whitespace'."
+ (isearch--momentary-message
+ (if (if isearch-regexp
+ (setq isearch-regexp-lax-whitespace (not isearch-regexp-lax-whitespace))
+ (setq isearch-lax-whitespace (not isearch-lax-whitespace)))
+ "match spaces loosely"
+ "match spaces literally")))
+
+(isearch-define-mode-toggle case-fold "c" nil
+ "Toggles the value of the variable `isearch-case-fold-search'."
+ (isearch--momentary-message
+ (if (setq isearch-case-fold-search
+ (if isearch-case-fold-search nil 'yes))
+ "case insensitive"
+ "case sensitive")))
+
+(isearch-define-mode-toggle invisible "i" nil
+ "This determines whether to search inside invisible text or not.
Toggles the variable `isearch-invisible' between values
nil and a non-nil value of the option `search-invisible'
\(or `open' if `search-invisible' is nil)."
- (interactive)
- (setq isearch-invisible
- (if isearch-invisible nil (or search-invisible 'open)))
- (let ((message-log-max nil))
- (message "%s%s [match %svisible text]"
- (isearch-message-prefix nil isearch-nonincremental)
- isearch-message
- (if isearch-invisible "in" "")))
- (setq isearch-success t isearch-adjusted t)
- (sit-for 1)
- (isearch-update))
+ "match %svisible text"
+ (isearch--momentary-message
+ (if (setq isearch-invisible
+ (if isearch-invisible
+ nil (or search-invisible 'open)))
+ "match invisible text"
+ "match visible text")))
\f
;; Word search
Relies on the function `word-search-regexp' to convert a sequence
of words in STRING to a regexp used to search words without regard
-to punctuation."
+to punctuation.
+This command does not support character folding, and lax space matching
+has no effect on it."
(interactive "sWord search backward: ")
(re-search-backward (word-search-regexp string nil) bound noerror count))
Relies on the function `word-search-regexp' to convert a sequence
of words in STRING to a regexp used to search words without regard
-to punctuation."
+to punctuation.
+This command does not support character folding, and lax space matching
+has no effect on it."
(interactive "sWord search: ")
(re-search-forward (word-search-regexp string nil) bound noerror count))
Relies on the function `word-search-regexp' to convert a sequence
of words in STRING to a regexp used to search words without regard
-to punctuation."
+to punctuation.
+This command does not support character folding, and lax space matching
+has no effect on it."
(interactive "sWord search backward: ")
(re-search-backward (word-search-regexp string t) bound noerror count))
Relies on the function `word-search-regexp' to convert a sequence
of words in STRING to a regexp used to search words without regard
-to punctuation."
+to punctuation.
+This command does not support character folding, and lax space matching
+has no effect on it."
(interactive "sWord search: ")
(re-search-forward (word-search-regexp string t) bound noerror count))
isearch-string
(concat "Query replace"
(isearch--describe-regexp-mode (or delimited isearch-regexp-function) t)
- (if isearch-regexp " regexp" "")
(if backward " backward" "")
(if (and transient-mark-mode mark-active) " in region" ""))
isearch-regexp)
isearch-regexp-lax-whitespace
isearch-lax-whitespace)
search-whitespace-regexp)))
- (occur regexp nlines)))
+ (occur (if isearch-regexp-function
+ (propertize regexp
+ 'isearch-string isearch-string
+ 'isearch-regexp-function-descr
+ (isearch--describe-regexp-mode isearch-regexp-function))
+ regexp)
+ nlines)))
(declare-function hi-lock-read-face-name "hi-lock" ())
(length isearch-string))))
isearch-message (mapconcat 'isearch-text-char-description
isearch-string "")))
+ ;; Do the following before moving point.
+ (funcall (or isearch-message-function #'isearch-message) nil t)
;; Use the isearch-other-end as new starting point to be able
;; to find the remaining part of the search string again.
;; This is like what `isearch-search-and-update' does,
(setq isearch-case-fold-search
(isearch-no-upper-case-p isearch-string isearch-regexp))))
;; Not regexp, not reverse, or no match at point.
+ ;; Do the following before moving point.
+ (funcall (or isearch-message-function #'isearch-message) nil t)
(if (and isearch-other-end (not isearch-adjusted))
(goto-char (if isearch-forward isearch-other-end
(min isearch-opoint
together with as much of the search string as will fit; the symbol
`above' if we need to scroll the text downwards; the symbol `below',
if upwards."
- (let ((w-start (window-start))
- (w-end (window-end nil t))
- (w-L1 (save-excursion (move-to-window-line 1) (point)))
- (w-L-1 (save-excursion (move-to-window-line -1) (point)))
+ (let ((w-start (window-group-start))
+ (w-end (window-group-end nil t))
+ (w-L1 (save-excursion
+ (save-selected-window (move-to-window-group-line 1) (point))))
+ (w-L-1 (save-excursion
+ (save-selected-window (move-to-window-group-line -1) (point))))
start end) ; start and end of search string in buffer
(if isearch-forward
(setq end isearch-point start (or isearch-other-end isearch-point))
(if above
(progn
(goto-char start)
- (recenter 0)
- (when (>= isearch-point (window-end nil t))
+ (recenter-window-group 0)
+ (when (>= isearch-point (window-group-end nil t))
(goto-char isearch-point)
- (recenter -1)))
+ (recenter-window-group -1)))
(goto-char end)
- (recenter -1)
- (when (< isearch-point (window-start))
+ (recenter-window-group -1)
+ (when (< isearch-point (window-group-start))
(goto-char isearch-point)
- (recenter 0))))
+ (recenter-window-group 0))))
(goto-char isearch-point))
(defvar isearch-pre-scroll-point nil)
(isearch-ring-adjust1 advance)
(if search-ring-update
(progn
+ (funcall (or isearch-message-function #'isearch-message) nil t)
(isearch-search)
(isearch-push-state)
(isearch-update))
(defun isearch-message (&optional c-q-hack ellipsis)
;; Generate and print the message string.
+
+ ;; N.B.: This function should always be called with point at the
+ ;; search point, because in certain (rare) circumstances, undesired
+ ;; scrolling can happen when point is elsewhere. These
+ ;; circumstances are when follow-mode is active, the search string
+ ;; spans two (or several) windows, and the message about to be
+ ;; displayed will cause the echo area to expand.
(let ((cursor-in-echo-area ellipsis)
(m isearch-message)
(fail-pos (isearch-fail-pos t)))
"Make a string for describing REGEXP-FUNCTION.
If SPACE-BEFORE is non-nil, put a space before, instead of after,
the word mode."
+ (when (eq regexp-function t)
+ (setq regexp-function #'word-search-regexp))
(let ((description
- (cond ((and (symbolp regexp-function)
- (get regexp-function 'isearch-message-prefix))
- (get regexp-function 'isearch-message-prefix))
- (regexp-function "word ")
- (t ""))))
+ (cond
+ ;; 1. Do not use a description on the default search mode,
+ ;; but only if the default search mode is non-nil.
+ ((or (and search-default-mode
+ (equal search-default-mode regexp-function))
+ ;; Special case where `search-default-mode' is t
+ ;; (defaults to regexp searches).
+ (and (eq search-default-mode t)
+ (eq search-default-mode isearch-regexp))) "")
+ ;; 2. Use the `isearch-message-prefix' set for
+ ;; `regexp-function' if available.
+ (regexp-function
+ (and (symbolp regexp-function)
+ (or (get regexp-function 'isearch-message-prefix)
+ "")))
+ ;; 3. Else if `isearch-regexp' is non-nil, set description
+ ;; to "regexp ".
+ (isearch-regexp "regexp ")
+ ;; 4. Else if we're in literal mode (and if the default
+ ;; mode is also not literal), describe it.
+ ((functionp search-default-mode) "literal ")
+ ;; 5. And finally, if none of the above is true, set the
+ ;; description to an empty string.
+ (t ""))))
(if space-before
;; Move space from the end to the beginning.
(replace-regexp-in-string "\\(.*\\) \\'" " \\1" description)
isearch-filter-predicate)
prefix)
(isearch--describe-regexp-mode isearch-regexp-function)
- (if isearch-regexp "regexp " "")
(cond
(multi-isearch-file-list "multi-file ")
(multi-isearch-buffer-list "multi-buffer ")
"Non-default value overrides the behavior of `isearch-search-fun-default'.
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.
+arguments: STRING, BOUND, and NOERROR. STRING is the string to
+be searched for. See `re-search-forward' for the meaning of
+BOUND and NOERROR arguments.
This returned function will be used by `isearch-search-string' to
-search for the first occurrence of STRING or its translation.")
+search for the first occurrence of STRING.")
(defun isearch-search-fun ()
"Return the function to use for the search.
(isearch-regexp isearch-regexp-lax-whitespace)
(t isearch-lax-whitespace))
search-whitespace-regexp)))
- (funcall
- (if isearch-forward #'re-search-forward #'re-search-backward)
- (cond (isearch-regexp-function
- (let ((lax (isearch--lax-regexp-function-p)))
- (if (functionp isearch-regexp-function)
- (funcall isearch-regexp-function string lax)
- (word-search-regexp string lax))))
- (isearch-regexp string)
- (t (regexp-quote string)))
- bound noerror count))))
+ (condition-case er
+ (funcall
+ (if isearch-forward #'re-search-forward #'re-search-backward)
+ (cond (isearch-regexp-function
+ (let ((lax (isearch--lax-regexp-function-p)))
+ (if (functionp isearch-regexp-function)
+ (funcall isearch-regexp-function string lax)
+ (word-search-regexp string lax))))
+ (isearch-regexp string)
+ (t (regexp-quote string)))
+ bound noerror count)
+ (search-failed
+ (signal (car er)
+ (let ((prefix (get isearch-regexp-function 'isearch-message-prefix)))
+ (if (and isearch-regexp-function (stringp prefix))
+ (list (format "%s [using %ssearch]" string prefix))
+ (cdr er)))))))))
(defun isearch-search-string (string bound noerror)
"Search for the first occurrence of STRING or its translation.
+STRING's characters are translated using `translation-table-for-input'
+if that is non-nil.
If found, move point to the end of the occurrence,
-update the match data, and return point."
+update the match data, and return point.
+An optional second argument bounds the search; it is a buffer position.
+The match found must not extend after that position.
+Optional third argument, if t, means if fail just return nil (no error).
+ If not nil and not t, move to limit of search and return nil."
(let* ((func (isearch-search-fun))
(pos1 (save-excursion (funcall func string bound noerror)))
pos2)
(defun isearch-search ()
;; Do the search with the current search string.
- (if isearch-message-function
- (funcall isearch-message-function nil t)
- (isearch-message nil t))
(if (and (eq isearch-case-fold-search t) search-upper-case)
(setq isearch-case-fold-search
(isearch-no-upper-case-p isearch-string isearch-regexp)))
(defvar isearch-lazy-highlight-timer nil)
(defvar isearch-lazy-highlight-last-string nil)
(defvar isearch-lazy-highlight-window nil)
+(defvar isearch-lazy-highlight-window-group nil)
(defvar isearch-lazy-highlight-window-start nil)
(defvar isearch-lazy-highlight-window-end nil)
(defvar isearch-lazy-highlight-case-fold-search nil)
(sit-for 0) ;make sure (window-start) is credible
(or (not (equal isearch-string
isearch-lazy-highlight-last-string))
- (not (eq (selected-window)
- isearch-lazy-highlight-window))
+ (not (memq (selected-window)
+ isearch-lazy-highlight-window-group))
(not (eq isearch-lazy-highlight-case-fold-search
isearch-case-fold-search))
(not (eq isearch-lazy-highlight-regexp
isearch-lax-whitespace))
(not (eq isearch-lazy-highlight-regexp-lax-whitespace
isearch-regexp-lax-whitespace))
- (not (= (window-start)
+ (not (= (window-group-start)
isearch-lazy-highlight-window-start))
- (not (= (window-end) ; Window may have been split/joined.
+ (not (= (window-group-end) ; Window may have been split/joined.
isearch-lazy-highlight-window-end))
(not (eq isearch-forward
isearch-lazy-highlight-forward))
(not (equal isearch-error
isearch-lazy-highlight-error))))
;; something important did indeed change
- (lazy-highlight-cleanup t) ;kill old loop & remove overlays
+ (lazy-highlight-cleanup t) ;kill old loop & remove overlays
(setq isearch-lazy-highlight-error isearch-error)
;; It used to check for `(not isearch-error)' here, but actually
;; lazy-highlighting might find matches to highlight even when
(setq isearch-lazy-highlight-start-limit beg
isearch-lazy-highlight-end-limit end)
(setq isearch-lazy-highlight-window (selected-window)
- isearch-lazy-highlight-window-start (window-start)
- isearch-lazy-highlight-window-end (window-end)
+ isearch-lazy-highlight-window-group (selected-window-group)
+ isearch-lazy-highlight-window-start (window-group-start)
+ isearch-lazy-highlight-window-end (window-group-end)
;; Start lazy-highlighting at the beginning of the found
;; match (`isearch-other-end'). If no match, use point.
;; One of the next two variables (depending on search direction)
isearch-lazy-highlight-regexp-lax-whitespace isearch-regexp-lax-whitespace
isearch-lazy-highlight-regexp-function isearch-regexp-function
isearch-lazy-highlight-forward isearch-forward)
- (unless (equal isearch-string "")
- (setq isearch-lazy-highlight-timer
- (run-with-idle-timer lazy-highlight-initial-delay nil
- 'isearch-lazy-highlight-update)))))
+ (unless (equal isearch-string "")
+ (setq isearch-lazy-highlight-timer
+ (run-with-idle-timer lazy-highlight-initial-delay nil
+ 'isearch-lazy-highlight-update)))))
(defun isearch-lazy-highlight-search ()
"Search ahead for the next or previous match, for lazy highlighting.
(+ isearch-lazy-highlight-start
;; Extend bound to match whole string at point
(1- (length isearch-lazy-highlight-last-string)))
- (window-end)))
+ (window-group-end)))
(max (or isearch-lazy-highlight-start-limit (point-min))
(if isearch-lazy-highlight-wrapped
(- isearch-lazy-highlight-end
;; Extend bound to match whole string at point
(1- (length isearch-lazy-highlight-last-string)))
- (window-start))))))
+ (window-group-start))))))
;; Use a loop like in `isearch-search'.
(while retry
(setq success (isearch-search-string
(with-local-quit
(save-selected-window
(if (and (window-live-p isearch-lazy-highlight-window)
- (not (eq (selected-window) isearch-lazy-highlight-window)))
+ (not (memq (selected-window) isearch-lazy-highlight-window-group)))
(select-window isearch-lazy-highlight-window))
(save-excursion
(save-match-data
(if isearch-lazy-highlight-forward
(if (= mb (if isearch-lazy-highlight-wrapped
isearch-lazy-highlight-start
- (window-end)))
+ (window-group-end)))
(setq found nil)
(forward-char 1))
(if (= mb (if isearch-lazy-highlight-wrapped
isearch-lazy-highlight-end
- (window-start)))
+ (window-group-start)))
(setq found nil)
(forward-char -1)))
;; 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 'window (selected-window))))
+ (overlay-put ov 'face lazy-highlight-face)))
+ ;(overlay-put ov 'window (selected-window))))
;; Remember the current position of point for
;; the next call of `isearch-lazy-highlight-update'
;; when `lazy-highlight-max-at-a-time' is too small.
(setq isearch-lazy-highlight-wrapped t)
(if isearch-lazy-highlight-forward
(progn
- (setq isearch-lazy-highlight-end (window-start))
+ (setq isearch-lazy-highlight-end (window-group-start))
(goto-char (max (or isearch-lazy-highlight-start-limit (point-min))
- (window-start))))
- (setq isearch-lazy-highlight-start (window-end))
+ (window-group-start))))
+ (setq isearch-lazy-highlight-start (window-group-end))
(goto-char (min (or isearch-lazy-highlight-end-limit (point-max))
- (window-end))))))))
+ (window-group-end))))))))
(unless nomore
(setq isearch-lazy-highlight-timer
(run-at-time lazy-highlight-interval nil