;; modify the search string before executing the search. There are
;; three commands to terminate the editing: C-s and C-r exit the
;; minibuffer and search forward and reverse respectively, while C-m
-;; exits and does a nonincremental search.
+;; exits and searches in the last search direction.
;; Exiting immediately from isearch uses isearch-edit-string instead
;; of nonincremental-search, if search-nonincremental-instead is non-nil.
"Function to save a function restoring the mode-specific Isearch state
to the search status stack.")
-(defvar isearch-filter-predicate 'isearch-filter-visible
- "Predicate that filters the search hits that would normally be available.
-Search hits that dissatisfy the predicate are skipped. The function
-has two arguments: the positions of start and end of text matched by
-the search. If this function returns nil, continue searching without
-stopping at this match.")
+(defvar isearch-filter-predicates nil
+ "Predicates that filter the search hits that would normally be available.
+Search hits that dissatisfy the list of predicates are skipped.
+Each function in this list has two arguments: the positions of
+start and end of text matched by the search.
+The search loop uses `run-hook-with-args-until-failure' to call
+each predicate in order, and when one of the predicates returns nil,
+skips this match and continues searching for the next match.
+When the list of predicates is empty, `run-hook-with-args-until-failure'
+returns non-nil that means that the found match is accepted.
+The property `isearch-message-prefix' put on the predicate's symbol
+specifies the prefix string displyed in the search message.")
+(define-obsolete-variable-alias 'isearch-filter-predicate
+ 'isearch-filter-predicates
+ "24.4")
;; Search ring.
(define-key map "\M-e" '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-so" 'isearch-occur)
(define-key map "\M-shr" 'isearch-highlight-regexp)
- ;; The key translations defined in the C-x 8 prefix should insert
- ;; characters into the search string. See iso-transl.el.
+ ;; The key translations defined in the C-x 8 prefix should add
+ ;; characters to the search string. See iso-transl.el.
(define-key map "\C-x" nil)
(define-key map [?\C-x t] 'isearch-other-control-char)
(define-key map "\C-x8" nil)
- (define-key map "\C-x8\r" 'isearch-insert-char-by-name)
+ (define-key map "\C-x8\r" 'isearch-char-by-name)
map)
"Keymap for `isearch-mode'.")
(defvar minibuffer-local-isearch-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map minibuffer-local-map)
- (define-key map "\r" 'isearch-nonincremental-exit-minibuffer)
+ (define-key map "\r" 'exit-minibuffer)
(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)
;; case in the search string is ignored.
(defvar isearch-case-fold-search nil)
+;; search-invisible while searching.
+;; either nil, t, or 'open. 'open means the same as t except that
+;; opens hidden overlays.
+(defvar isearch-invisible search-invisible)
+
(defvar isearch-last-case-fold-search nil)
;; Used to save default value while isearch is active
Type \\[isearch-yank-pop] to replace string just yanked into search prompt
with string killed before it.
Type \\[isearch-quote-char] to quote control character to search for it.
+Type \\[isearch-char-by-name] to add a character to search by Unicode name,\
+ with completion.
\\[isearch-abort] while searching or when search has failed cancels input\
back to what has
been found successfully.
nonincremental search.
Type \\[isearch-toggle-case-fold] to toggle search case-sensitivity.
+Type \\[isearch-toggle-invisible] to toggle search in invisible text.
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.
and are then executed normally (depending on `search-exit-option').
Likewise for function keys and mouse button events.
-If this function is called non-interactively, it does not return to
-the calling function until the search is done."
+If this function is called non-interactively with a nil NO-RECURSIVE-EDIT,
+it does not return to the calling function until the search is done.
+See the function `isearch-mode' for more information."
(interactive "P\np")
(isearch-mode t (not (null regexp-p)) nil (not no-recursive-edit)))
(defun isearch-mode (forward &optional regexp op-fun recursive-edit word)
"Start Isearch minor mode.
-It is called by the function `isearch-forward' and other related functions."
+It is called by the function `isearch-forward' and other related functions.
+
+The non-nil arg FORWARD means searching in the forward direction.
+
+The non-nil arg REGEXP does an incremental regular expression search.
+
+The arg OP-FUN is a function to be called after each input character
+is processed. (It is not called after characters that exit the search.)
+
+When the arg RECURSIVE-EDIT is non-nil, this function behaves modally and
+does not return to the calling function until the search is completed.
+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."
;; Initialize global vars.
(setq isearch-forward forward
isearch-op-fun op-fun
isearch-last-case-fold-search isearch-case-fold-search
isearch-case-fold-search case-fold-search
+ isearch-invisible search-invisible
isearch-string ""
isearch-message ""
isearch-cmds nil
(curr-msg (if msg isearch-message isearch-string))
succ-msg)
(when (or (not isearch-success) isearch-error)
- (while (or (not (isearch--state-success (car cmds)))
- (isearch--state-error (car cmds)))
+ (while (and cmds
+ (or (not (isearch--state-success (car cmds)))
+ (isearch--state-error (car cmds))))
(pop cmds))
(setq succ-msg (and cmds (if msg (isearch--state-message (car cmds))
(isearch--state-string (car cmds)))))
The following additional command keys are active while editing.
\\<minibuffer-local-isearch-map>
\\[exit-minibuffer] to resume incremental searching with the edited string.
-\\[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."
(interactive)
(setq isearch-nonincremental t)
(exit-minibuffer))
+;; Changing the value of `isearch-nonincremental' has no effect here,
+;; because `isearch-edit-string' ignores this change. Thus marked as obsolete.
+(make-obsolete 'isearch-nonincremental-exit-minibuffer 'exit-minibuffer "24.4")
(defun isearch-forward-exit-minibuffer ()
+ "Resume isearching forward from the minibuffer that edits the search string."
(interactive)
(setq isearch-new-forward t)
(exit-minibuffer))
(defun isearch-reverse-exit-minibuffer ()
+ "Resume isearching backward from the minibuffer that edits the search string."
(interactive)
(setq isearch-new-forward nil)
(exit-minibuffer))
(isearch-update))
(defun isearch-toggle-case-fold ()
- "Toggle case folding in searching on or off."
+ "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))
(sit-for 1)
(isearch-update))
+(defun isearch-toggle-invisible ()
+ "Toggle searching in invisible text on or off.
+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))
+
\f
;; Word search
;; set `search-upper-case' to nil to not call
;; `isearch-no-upper-case-p' in `perform-replace'
(search-upper-case nil)
+ (search-invisible isearch-invisible)
(replace-lax-whitespace
isearch-lax-whitespace)
(replace-regexp-lax-whitespace
(lambda () (let ((inhibit-field-text-motion t))
(line-end-position (if (eolp) 2 1))))))
-(defun isearch-insert-char-by-name ()
- "Read a character by its Unicode name and insert it into search string."
+(defun isearch-char-by-name ()
+ "Read a character by its Unicode name and add it to the search string.
+Completion is available like in `read-char-by-name' used by `insert-char'."
(interactive)
(with-isearch-suspended
- (let ((char (read-char-by-name "Insert character (Unicode name or hex): ")))
+ (let ((char (read-char-by-name "Add character to search (Unicode name or hex): ")))
(when char
(setq isearch-new-string (concat isearch-string (string char))
isearch-new-message (concat isearch-message
(< (point) isearch-opoint)))
"over")
(if isearch-wrapped "wrapped ")
+ (mapconcat (lambda (s)
+ (and (symbolp s)
+ (get s 'isearch-message-prefix)))
+ (if (consp isearch-filter-predicates)
+ isearch-filter-predicates
+ (list isearch-filter-predicates))
+ "")
(if isearch-word
(or (and (symbolp isearch-word)
(get isearch-word 'isearch-message-prefix))
(setq isearch-case-fold-search
(isearch-no-upper-case-p isearch-string isearch-regexp)))
(condition-case lossage
- (let ((inhibit-point-motion-hooks
- ;; FIXME: equality comparisons on functions is asking for trouble.
- (and (eq isearch-filter-predicate 'isearch-filter-visible)
- search-invisible))
+ (let ((inhibit-point-motion-hooks isearch-invisible)
(inhibit-quit nil)
(case-fold-search isearch-case-fold-search)
+ (search-invisible isearch-invisible)
(retry t))
(setq isearch-error nil)
(while retry
(if (or (not isearch-success)
(bobp) (eobp)
(= (match-beginning 0) (match-end 0))
- (funcall isearch-filter-predicate
- (match-beginning 0) (match-end 0)))
+ ;; When one of filter predicates returns nil,
+ ;; retry the search. Otherwise, act according
+ ;; to search-invisible (open overlays, etc.)
+ (and (run-hook-with-args-until-failure
+ 'isearch-filter-predicates
+ (match-beginning 0) (match-end 0))
+ (or (eq search-invisible t)
+ (not (isearch-range-invisible
+ (match-beginning 0) (match-end 0))))))
(setq retry nil)))
(setq isearch-just-started nil)
(if isearch-success
searched too when `search-invisible' is t."
(or (eq search-invisible t)
(not (isearch-range-invisible beg end))))
+(make-obsolete 'isearch-filter-visible 'isearch-invisible "24.4")
\f
;; General utilities
(if (or (not success)
(= (point) bound) ; like (bobp) (eobp) in `isearch-search'.
(= (match-beginning 0) (match-end 0))
- (funcall isearch-filter-predicate
- (match-beginning 0) (match-end 0)))
+ (and (run-hook-with-args-until-failure
+ 'isearch-filter-predicates
+ (match-beginning 0) (match-end 0))
+ (not (isearch-range-invisible
+ (match-beginning 0) (match-end 0)))))
(setq retry nil)))
success)
(error nil)))