;; 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-exit-option t
"Non-nil means random control characters terminate incremental search."
- :type 'boolean
- :group 'isearch)
+ :type 'boolean)
(defcustom search-slow-window-lines 1
"Number of lines in slow search display windows.
These are the short windows used during incremental search on slow terminals.
Negative means put the slow search window at the top (normally it's at bottom)
and the value is minus the number of lines."
- :type 'integer
- :group 'isearch)
+ :type 'integer)
(defcustom search-slow-speed 1200
"Highest terminal speed at which to use \"slow\" style incremental search.
This is the style where a one-line window is created to show the line
that the search has reached."
- :type 'integer
- :group 'isearch)
+ :type 'integer)
(defcustom search-upper-case 'not-yanks
"If non-nil, upper case chars disable case fold searching.
in Isearch mode is always downcased."
:type '(choice (const :tag "off" nil)
(const not-yanks)
- (other :tag "on" t))
- :group 'isearch)
+ (other :tag "on" t)))
(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."
- :type 'boolean
- :group 'isearch)
+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-+")
"If non-nil, regular expression to match a sequence of whitespace chars.
a tab, a carriage return (control-M), a newline, and `]+'."
:type '(choice (const :tag "Match Spaces Literally" nil)
regexp)
- :group 'isearch
:version "24.3")
(defcustom search-invisible 'open
whenever point is in one of them."
:type '(choice (const :tag "Match hidden text" t)
(const :tag "Open overlays" open)
- (const :tag "Don't match hidden text" nil))
- :group 'isearch)
+ (const :tag "Don't match hidden text" nil)))
(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."
- :type 'boolean
- :group 'isearch)
+the search, with the exception of the last successful match, if any."
+ :type 'boolean)
(defcustom isearch-resume-in-command-history nil
"If non-nil, `isearch-resume' commands are added to the command history.
This allows you to resume earlier Isearch sessions through the
command history."
- :type 'boolean
- :group 'isearch)
+ :type 'boolean)
(defvar isearch-mode-hook nil
"Function(s) to call after starting up an incremental search.")
(defcustom search-ring-max 16
"Maximum length of search ring before oldest elements are thrown away."
- :type 'integer
- :group 'isearch)
+ :type 'integer)
(defcustom regexp-search-ring-max 16
"Maximum length of regexp search ring before oldest elements are thrown away."
- :type 'integer
- :group 'isearch)
+ :type 'integer)
(defvar search-ring-yank-pointer nil
"Index in `search-ring' of last string reused.
(defcustom search-ring-update nil
"Non-nil if advancing or retreating in the search ring should cause search.
Default value, nil, means edit the string instead."
- :type 'boolean
- :group 'isearch)
+ :type 'boolean)
+
+(autoload 'character-fold-to-regexp "character-fold")
+
+(defcustom search-default-regexp-mode #'character-fold-to-regexp
+ "Default mode to use when starting isearch.
+Value is nil, t, or a function.
+
+If nil, default to literal searches (note that `case-fold-search'
+and `isearch-lax-whitespace' may still be applied).\\<isearch-mode-map>
+If t, default to regexp searches (as if typing `\\[isearch-toggle-regexp]' during
+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-define-mode-toggle'.
+ :type '(choice (const :tag "Literal search" nil)
+ (const :tag "Regexp search" t)
+ (function :tag "Other"))
+ :version "25.1")
;;; isearch highlight customization.
(defcustom search-highlight t
"Non-nil means incremental search highlights the current match."
- :type 'boolean
- :group 'isearch)
+ :type 'boolean)
(defface isearch
'((((class color) (min-colors 88) (background light))
:foreground "grey")
(t (:inverse-video t)))
"Face for highlighting failed part in Isearch echo-area message."
- :version "23.1"
- :group 'isearch)
+ :version "23.1")
(defcustom isearch-lazy-highlight t
"Controls the lazy-highlighting during incremental search.
(define-key map "\M-\C-s" 'isearch-repeat-forward)
(define-key map "\M-\C-r" 'isearch-repeat-backward)
(define-key map "\177" 'isearch-delete-char)
- (define-key map [backspace] 'isearch-delete-char)
+ (define-key map [backspace] 'undefined) ;bug#20466.
(define-key map "\C-g" 'isearch-abort)
;; This assumes \e is the meta-prefix-char.
(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-sw" 'isearch-toggle-word)
- (define-key map "\M-s_" 'isearch-toggle-symbol)
- (define-key map "\M-s " 'isearch-toggle-lax-whitespace)
+ ;; More toggles defined by `isearch-define-mode-toggle'.
(define-key map [?\M-%] 'isearch-query-replace)
(define-key map [?\C-\M-%] 'isearch-query-replace-regexp)
(defvar isearch-forward nil) ; Searching in the forward direction.
(defvar isearch-regexp nil) ; Searching for a regexp.
-(defvar isearch-word nil
+(defvar isearch-regexp-function nil
"Regexp-based search mode for words/symbols.
-If t, do incremental search for a sequence of words, ignoring punctuation.
-If the value is a function (e.g. `isearch-symbol-regexp'), it is called to
-convert the search string to a regexp used by regexp search functions.
-The property `isearch-message-prefix' put on this function specifies the
-prefix string displayed in the search message.")
+If the value is a function (e.g. `isearch-symbol-regexp'), it is
+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.")
+;; We still support setting this to t for backwards compatibility.
+(define-obsolete-variable-alias 'isearch-word
+ 'isearch-regexp-function "25.1")
(defvar isearch-lax-whitespace t
"If non-nil, a space will match a sequence of whitespace chars.
"Stack of search status elements.
Each element is an `isearch--state' struct where the slots are
[STRING MESSAGE POINT SUCCESS FORWARD OTHER-END WORD
- INVALID-REGEXP WRAPPED BARRIER WITHIN-BRACKETS CASE-FOLD-SEARCH]")
+ ERROR WRAPPED BARRIER CASE-FOLD-SEARCH]")
(defvar isearch-string "") ; The current search string.
(defvar isearch-message "") ; text-char-description version of isearch-string
(nconc minor-mode-alist
(list '(isearch-mode isearch-mode))))
-(defvar isearch-mode nil) ;; Name of the minor mode, if non-nil.
-(make-variable-buffer-local 'isearch-mode)
+(defvar-local isearch-mode nil) ;; Name of the minor mode, if non-nil.
(define-key global-map "\C-s" 'isearch-forward)
(define-key esc-map "\C-s" 'isearch-forward-regexp)
Type \\[isearch-toggle-regexp] to toggle regular-expression mode.
Type \\[isearch-toggle-word] to toggle word mode.
Type \\[isearch-toggle-symbol] to toggle symbol mode.
+Type \\[isearch-toggle-character-fold] to toggle character folding.
Type \\[isearch-toggle-lax-whitespace] to toggle whitespace matching.
In incremental searches, a space or spaces normally matches any whitespace
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.
;; isearch-forward-regexp isearch-backward-regexp)
;; "List of commands for which isearch-mode does not recursive-edit.")
-
-(defun isearch-mode (forward &optional regexp op-fun recursive-edit word)
+(defun isearch-mode (forward &optional regexp op-fun recursive-edit regexp-function)
"Start Isearch minor mode.
It is called by the function `isearch-forward' and other related functions.
To behave this way it enters a recursive-edit and exits it when done
isearching.
-The arg WORD, if t, does incremental search for a sequence of words,
-ignoring punctuation. If the value is a function, it is called to
-convert the search string to a regexp used by regexp search functions."
+The arg REGEXP-FUNCTION, if non-nil, should be a function. It is
+used to set the value of `isearch-regexp-function'."
;; Initialize global vars.
(setq isearch-forward forward
- isearch-regexp regexp
- isearch-word word
+ isearch-regexp (or regexp
+ (and (not regexp-function)
+ (eq search-default-regexp-mode t)))
+ isearch-regexp-function (or regexp-function
+ (and (functionp search-default-regexp-mode)
+ (not regexp)
+ search-default-regexp-mode))
isearch-op-fun op-fun
isearch-last-case-fold-search isearch-case-fold-search
isearch-case-fold-search case-fold-search
;; Some high level utilities. Others below.
+(defvar isearch--current-buffer nil)
(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'."
+ (unless (eq (current-buffer) 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))
+
(if (and (null unread-command-events)
(null executing-kbd-macro))
(progn
(if isearch-resume-in-command-history
(let ((command `(isearch-resume ,isearch-string ,isearch-regexp
- ,isearch-word ,isearch-forward
+ ,isearch-regexp-function ,isearch-forward
,isearch-message
',isearch-case-fold-search)))
(unless (equal (car command-history) command)
(remove-hook 'mouse-leave-buffer-hook 'isearch-done)
(remove-hook 'kbd-macro-termination-hook 'isearch-done)
(setq isearch-lazy-highlight-start nil)
+ (with-current-buffer isearch--current-buffer
+ (setq isearch--current-buffer nil)
+ (setq cursor-sensor-inhibit (delq 'isearch cursor-sensor-inhibit)))
;; Called by all commands that terminate isearch-mode.
;; If NOPUSH is non-nil, we don't push the string on the search ring.
(success isearch-success)
(forward isearch-forward)
(other-end isearch-other-end)
- (word isearch-word)
+ (word isearch-regexp-function)
(error isearch-error)
(wrapped isearch-wrapped)
(barrier isearch-barrier)
isearch-success (isearch--state-success cmd)
isearch-forward (isearch--state-forward cmd)
isearch-other-end (isearch--state-other-end cmd)
- isearch-word (isearch--state-word cmd)
+ isearch-regexp-function (isearch--state-word cmd)
isearch-error (isearch--state-error cmd)
isearch-wrapped (isearch--state-wrapped cmd)
isearch-barrier (isearch--state-barrier cmd)
(if (and search-nonincremental-instead
(= 0 (length isearch-string)))
(let ((isearch-nonincremental t))
- (isearch-edit-string)))
- (isearch-done)
+ (isearch-edit-string)) ;; this calls isearch-done as well
+ (isearch-done))
(isearch-clean-overlays))
(defun isearch-fail-pos (&optional msg)
(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
`isearch-new-string', `isearch-new-message', `isearch-new-forward',
-`isearch-new-word', `isearch-new-case-fold'."
+`isearch-new-regexp-function', `isearch-new-case-fold'."
;; This code is very hairy for several reasons, explained in the code.
;; Mainly, isearch-mode must be terminated while editing and then restarted.
;; If there were a way to catch any change of buffer from the minibuffer,
(isearch-new-string isearch-string)
(isearch-new-message isearch-message)
(isearch-new-forward isearch-forward)
- (isearch-new-word isearch-word)
+ (isearch-new-regexp-function isearch-regexp-function)
(isearch-new-case-fold isearch-case-fold-search)
(isearch-regexp isearch-regexp)
isearch-regexp
isearch-op-fun
nil
- isearch-word)
+ isearch-regexp-function)
;; Copy new local values to isearch globals
(setq isearch-string isearch-new-string
isearch-message isearch-new-message
isearch-forward isearch-new-forward
- isearch-word isearch-new-word
+ isearch-regexp-function isearch-new-regexp-function
isearch-case-fold-search isearch-new-case-fold))
;; Empty isearch-string means use default.
(interactive)
(isearch-repeat 'backward))
-(defun isearch-toggle-regexp ()
- "Toggle regexp searching on or off."
- ;; The status stack is left unchanged.
- (interactive)
+\f
+;;; Toggles for `isearch-regexp-function' and `search-default-regexp-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.%s" mode
+ (if docstring (concat "\n" docstring) ""))
+ (interactive)
+ ,@(when function
+ `((setq isearch-regexp-function
+ (unless (eq isearch-regexp-function #',function)
+ #',function))
+ (when isearch-regexp-function (setq isearch-regexp nil))))
+ ,@body
+ (setq isearch-success t isearch-adjusted t)
+ (isearch-update))
+ (define-key isearch-mode-map ,key #',command-name)
+ ,@(when (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-regexp-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 ")
+
+(isearch-define-mode-toggle regexp "r" nil nil
(setq isearch-regexp (not isearch-regexp))
- (if isearch-regexp (setq isearch-word nil))
- (setq isearch-success t isearch-adjusted t)
- (isearch-update))
-
-(defun isearch-toggle-word ()
- "Toggle word searching on or off."
- ;; The status stack is left unchanged.
- (interactive)
- (setq isearch-word (not isearch-word))
- (if isearch-word (setq isearch-regexp nil))
- (setq isearch-success t isearch-adjusted t)
- (isearch-update))
-
-(defun isearch-toggle-symbol ()
- "Toggle symbol searching on or off."
- (interactive)
- (setq isearch-word (unless (eq isearch-word 'isearch-symbol-regexp)
- 'isearch-symbol-regexp))
- (if isearch-word (setq isearch-regexp nil))
- (setq isearch-success t isearch-adjusted t)
- (isearch-update))
+ (if isearch-regexp (setq isearch-regexp-function nil)))
-(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)))
+(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 [%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))
-
-(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))
- (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))
+ (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))
(let ((search-spaces-regexp search-whitespace-regexp))
(re-search-backward regexp bound noerror count)))
+(dolist (old '(re-search-forward-lax-whitespace search-backward-lax-whitespace
+ search-forward-lax-whitespace re-search-backward-lax-whitespace))
+ (make-obsolete old
+ "instead, use (let ((search-spaces-regexp search-whitespace-regexp))
+ (re-search-... ...))"
+ "25.1"))
+
\f
(defun isearch-query-replace (&optional arg regexp-flag)
"Start `query-replace' with string to replace from last search string.
(query-replace-read-to
isearch-string
(concat "Query replace"
- (if (or delimited isearch-word)
- (let* ((symbol (or delimited isearch-word))
- (string (and symbol (symbolp symbol)
- (get symbol 'isearch-message-prefix))))
- (if (stringp string)
- ;; Move space from the end to the beginning.
- (replace-regexp-in-string "\\(.*\\) \\'" " \\1" string)
- " word"))
- "")
- (if isearch-regexp " regexp" "")
+ (isearch--describe-regexp-mode (or delimited isearch-regexp-function) t)
(if backward " backward" "")
(if (and transient-mark-mode mark-active) " in region" ""))
isearch-regexp)
- t isearch-regexp (or delimited isearch-word) nil nil
+ t isearch-regexp (or delimited isearch-regexp-function) nil nil
(if (and transient-mark-mode mark-active) (region-beginning))
(if (and transient-mark-mode mark-active) (region-end))
backward))
(interactive
(let* ((perform-collect (consp current-prefix-arg))
(regexp (cond
- ((functionp isearch-word)
- (funcall isearch-word isearch-string))
- (isearch-word (word-search-regexp isearch-string))
+ ((functionp isearch-regexp-function)
+ (funcall isearch-regexp-function isearch-string))
+ (isearch-regexp-function (word-search-regexp isearch-string))
(isearch-regexp isearch-string)
(t (regexp-quote isearch-string)))))
(list 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" ())
(isearch-done nil t)
(isearch-clean-overlays))
(require 'hi-lock nil t)
- (let ((regexp (cond ((functionp isearch-word)
- (funcall isearch-word isearch-string))
- (isearch-word (word-search-regexp isearch-string))
+ (let ((regexp (cond ((functionp isearch-regexp-function)
+ (funcall isearch-regexp-function isearch-string))
+ (isearch-regexp-function (word-search-regexp isearch-string))
(isearch-regexp isearch-string)
((if (and (eq isearch-case-fold-search t)
search-upper-case)
(defun isearch-yank-x-selection ()
"Pull current X selection into search string."
(interactive)
- (isearch-yank-string (x-get-selection))
- ;; If `x-get-selection' returned the text from the active region,
+ (isearch-yank-string (gui-get-selection))
+ ;; If `gui-get-selection' returned the text from the active region,
;; then it "used" the mark which we should hence deactivate.
(when select-active-regions (deactivate-mark)))
(setq case-fold-search
(isearch-no-upper-case-p isearch-string isearch-regexp)))
(looking-at (cond
- ((functionp isearch-word)
- (funcall isearch-word isearch-string t))
- (isearch-word (word-search-regexp isearch-string t))
+ ((functionp isearch-regexp-function)
+ (funcall isearch-regexp-function isearch-string t))
+ (isearch-regexp-function (word-search-regexp isearch-string t))
(isearch-regexp isearch-string)
(t (regexp-quote isearch-string)))))
(error nil))
(isearch-message-suffix c-q-hack)))
(if c-q-hack m (let ((message-log-max nil)) (message "%s" m)))))
+(defun isearch--describe-regexp-mode (regexp-function &optional space-before)
+ "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
+ ;; Don't use a description on the default search mode.
+ (cond ((equal regexp-function search-default-regexp-mode) "")
+ (regexp-function
+ (and (symbolp regexp-function)
+ (or (get regexp-function 'isearch-message-prefix)
+ "")))
+ (isearch-regexp "regexp ")
+ ;; We're in literal mode. If the default mode is not
+ ;; literal, then describe it.
+ ((functionp search-default-regexp-mode) "literal "))))
+ (if space-before
+ ;; Move space from the end to the beginning.
+ (replace-regexp-in-string "\\(.*\\) \\'" " \\1" description)
+ description)))
+(define-obsolete-function-alias 'isearch--describe-word-mode
+ 'isearch--describe-regexp-mode "25.1")
+
(defun isearch-message-prefix (&optional ellipsis nonincremental)
;; If about to search, and previous search regexp was invalid,
;; check that it still is. If it is valid now,
(let ((np (cdr (assq 'isearch-message-prefix props))))
(if np (setq prefix (concat np prefix)))))
isearch-filter-predicate)
- prefix)
- (if isearch-word
- (or (and (symbolp isearch-word)
- (get isearch-word 'isearch-message-prefix))
- "word ")
- "")
- (if isearch-regexp "regexp " "")
+ prefix)
+ (isearch--describe-regexp-mode isearch-regexp-function)
(cond
(multi-isearch-file-list "multi-file ")
(multi-isearch-buffer-list "multi-buffer ")
Can be changed via `isearch-search-fun-function' for special needs."
(funcall (or isearch-search-fun-function 'isearch-search-fun-default)))
+(defun isearch--lax-regexp-function-p ()
+ "Non-nil if next regexp-function call should be lax."
+ (not (or isearch-nonincremental
+ (null (car isearch-cmds))
+ (eq (length isearch-string)
+ (length (isearch--state-string
+ (car isearch-cmds)))))))
+
(defun isearch-search-fun-default ()
"Return default functions to use for the search."
- (cond
- (isearch-word
- (lambda (string &optional bound noerror count)
- ;; Use lax versions to not fail at the end of the word while
- ;; the user adds and removes characters in the search string
- ;; (or when using nonincremental word isearch)
- (let ((lax (not (or isearch-nonincremental
- (null (car isearch-cmds))
- (eq (length isearch-string)
- (length (isearch--state-string
- (car isearch-cmds))))))))
- (funcall
- (if isearch-forward #'re-search-forward #'re-search-backward)
- (if (functionp isearch-word)
- (funcall isearch-word string lax)
- (word-search-regexp string lax))
- bound noerror count))))
- ((and isearch-regexp isearch-regexp-lax-whitespace
- search-whitespace-regexp)
- (if isearch-forward
- 're-search-forward-lax-whitespace
- 're-search-backward-lax-whitespace))
- (isearch-regexp
- (if isearch-forward 're-search-forward 're-search-backward))
- ((and isearch-lax-whitespace search-whitespace-regexp)
- (if isearch-forward
- 'search-forward-lax-whitespace
- 'search-backward-lax-whitespace))
- (t
- (if isearch-forward 'search-forward 'search-backward))))
+ (lambda (string &optional bound noerror count)
+ ;; Use lax versions to not fail at the end of the word while
+ ;; the user adds and removes characters in the search string
+ ;; (or when using nonincremental word isearch)
+ (let ((search-spaces-regexp (when (cond
+ (isearch-regexp isearch-regexp-lax-whitespace)
+ (t isearch-lax-whitespace))
+ search-whitespace-regexp)))
+ (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.
((and (not isearch-regexp)
(string-match "\\`Regular expression too big" isearch-error))
(cond
- (isearch-word
+ (isearch-regexp-function
(setq isearch-error "Too many words"))
((and isearch-lax-whitespace search-whitespace-regexp)
(setq isearch-error "Too many spaces for whitespace matching"))))))
;; isearch in their own way, they should set the
;; `isearch-open-invisible-temporary' to a function doing this.
(funcall (overlay-get ov 'isearch-open-invisible-temporary) ov nil)
- ;; Store the values for the `invisible' and `intangible'
- ;; properties, and then set them to nil. This way the text hidden
- ;; by this overlay becomes visible.
+ ;; Store the values for the `invisible' property, and then set it to nil.
+ ;; This way the text hidden by this overlay becomes visible.
- ;; Do we really need to set the `intangible' property to t? Can we
- ;; have the point inside an overlay with an `intangible' property?
;; In 19.34 this does not exist so I cannot test it.
(overlay-put ov 'isearch-invisible (overlay-get ov 'invisible))
- (overlay-put ov 'isearch-intangible (overlay-get ov 'intangible))
- (overlay-put ov 'invisible nil)
- (overlay-put ov 'intangible nil)))
+ (overlay-put ov 'invisible nil)))
;; This is called at the end of isearch. It will open the overlays
;; this function, not by us tweaking the overlay properties.
(fct-temp (overlay-get ov 'isearch-open-invisible-temporary)))
(when (or inside-overlay (not fct-temp))
- ;; restore the values for the `invisible' and `intangible'
- ;; properties
+ ;; restore the values for the `invisible' properties.
(overlay-put ov 'invisible (overlay-get ov 'isearch-invisible))
- (overlay-put ov 'intangible (overlay-get ov 'isearch-intangible))
- (overlay-put ov 'isearch-invisible nil)
- (overlay-put ov 'isearch-intangible nil))
+ (overlay-put ov 'isearch-invisible nil))
(if inside-overlay
(funcall (overlay-get ov 'isearch-open-invisible) ov)
(if fct-temp
;; properties.
(funcall fct-temp ov t)
(overlay-put ov 'invisible (overlay-get ov 'isearch-invisible))
- (overlay-put ov 'intangible (overlay-get ov 'isearch-intangible))
- (overlay-put ov 'isearch-invisible nil)
- (overlay-put ov 'isearch-intangible nil)))))))
+ (overlay-put ov 'isearch-invisible nil)))))))
(defun isearch-range-invisible (beg end)
;; - `isearch-string' is expected to contain the current search
;; string as entered by the user;
;; - the type of the current search is expected to be given by
-;; `isearch-word' and `isearch-regexp';
+;; `isearch-regexp-function' and `isearch-regexp';
;; - the direction of the current search is expected to be given by
;; `isearch-forward';
;; - the variable `isearch-error' is expected to be true
(defvar isearch-lazy-highlight-regexp nil)
(defvar isearch-lazy-highlight-lax-whitespace nil)
(defvar isearch-lazy-highlight-regexp-lax-whitespace nil)
-(defvar isearch-lazy-highlight-word nil)
+(defvar isearch-lazy-highlight-regexp-function nil)
+(define-obsolete-variable-alias 'isearch-lazy-highlight-word
+ 'isearch-lazy-highlight-regexp-function "25.1")
(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 (eq isearch-lazy-highlight-regexp-function
+ isearch-regexp-function))
(not (eq isearch-lazy-highlight-lax-whitespace
isearch-lax-whitespace))
(not (eq isearch-lazy-highlight-regexp-lax-whitespace
isearch-lazy-highlight-regexp isearch-regexp
isearch-lazy-highlight-lax-whitespace isearch-lax-whitespace
isearch-lazy-highlight-regexp-lax-whitespace isearch-regexp-lax-whitespace
- isearch-lazy-highlight-word isearch-word
+ isearch-lazy-highlight-regexp-function isearch-regexp-function
isearch-lazy-highlight-forward isearch-forward)
(unless (equal isearch-string "")
(setq isearch-lazy-highlight-timer
(condition-case nil
(let ((case-fold-search isearch-lazy-highlight-case-fold-search)
(isearch-regexp isearch-lazy-highlight-regexp)
- (isearch-word isearch-lazy-highlight-word)
+ (isearch-regexp-function isearch-lazy-highlight-regexp-function)
(isearch-lax-whitespace
isearch-lazy-highlight-lax-whitespace)
(isearch-regexp-lax-whitespace