spaces are treated normally in regexp incremental search if they
occur in a regexp construct like [...] or *, + or ?.
-If the value is a string, it applies to both ordinary and regexp
-incremental search. If the value is nil, each space you type
-matches literally, against one space.
-
-The value can also be a cons cell (REGEXP-1 . REGEXP-2). In that
-case, REGEXP-1 is used as the value for ordinary incremental
-search, and REGEXP-2 is used for regexp incremental search.
+If the value is a string, it applies to both ordinary and
+regexp incremental search. If the value is nil, or
+`isearch-lax-whitespace' is nil for ordinary incremental search, or
+`isearch-regexp-lax-whitespace' is nil for regexp incremental search,
+then each space you type matches literally, against one space.
You might want to use something like \"[ \\t\\r\\n]+\" instead.
In the Customization buffer, that is `[' followed by a space,
a tab, a carriage return (control-M), a newline, and `]+'."
- :type '(choice (const :tag "Treat Spaces Literally" nil)
- (cons (choice :tag "For Ordinary Isearch"
- regexp
- (const :tag "Treat Spaces Literally" nil))
- (choice :tag "For Regexp Isearch"
- regexp
- (const :tag "Treat Spaces Literally" nil)))
+ :type '(choice (const :tag "Match Spaces Literally" nil)
regexp)
:group 'isearch
:version "24.3")
(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)
(define-key map [?\M-%] 'isearch-query-replace)
(define-key map [?\C-\M-%] 'isearch-query-replace-regexp)
The property `isearch-message-prefix' put on this function specifies the
prefix string displayed in the search message.")
+(defvar isearch-lax-whitespace t
+ "If non-nil, a space will match a sequence of whitespace chars.
+When you enter a space or spaces in ordinary incremental search, it
+will match any sequence matched by the regexp defined by the variable
+`search-whitespace-regexp'. If the value is nil, each space you type
+matches literally, against one space. You can toggle the value of this
+variable by the command `isearch-toggle-lax-whitespace'.")
+
+(defvar isearch-regexp-lax-whitespace nil
+ "If non-nil, a space will match a sequence of whitespace chars.
+When you enter a space or spaces in regexp incremental search, it
+will match any sequence matched by the regexp defined by the variable
+`search-whitespace-regexp'. If the value is nil, each space you type
+matches literally, against one space. You can toggle the value of this
+variable by the command `isearch-toggle-lax-whitespace'.")
+
(defvar isearch-cmds nil
"Stack of search status sets.
Each set is a vector of the form:
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-lax-whitespace] to toggle whitespace matching.
+In incremental searches, a space or spaces normally matches any whitespace
+defined by the variable `search-whitespace-regexp'; see also the variables
+`isearch-lax-whitespace' and `isearch-regexp-lax-whitespace'.
+
Type \\[isearch-edit-string] to edit the search string in the minibuffer.
Also supported is a search ring of the previous 16 search strings.
Type \\[isearch-describe-key] to display documentation of Isearch key.
Type \\[isearch-describe-mode] to display documentation of Isearch mode.
-In incremental searches, a space or spaces normally matches any
-whitespace; see the variable `search-whitespace-regexp'.
-
If an input method is turned on in the current buffer, that input
method is also active while you are typing characters to search.
To toggle the input method, type \\[isearch-toggle-input-method]. \
as a regexp. See the command `isearch-forward' for more information.
In incremental searches, a space or spaces normally matches any
-whitespace; see the variable `search-whitespace-regexp'. To
-search for a literal space and nothing else, enter C-q SPC."
+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'."
(interactive "P\np")
(isearch-mode t (null not-regexp) nil (not no-recursive-edit)))
(setq isearch-success t isearch-adjusted t)
(isearch-update))
+(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))
+
(defun isearch-toggle-case-fold ()
"Toggle case folding in searching on or off."
(interactive)
(put 'isearch-symbol-regexp 'isearch-message-prefix "symbol ")
+;; Search with lax whitespace
+
+(defun search-forward-lax-whitespace (string &optional bound noerror count)
+ "Search forward for STRING, matching a sequence of whitespace chars."
+ (let ((search-spaces-regexp search-whitespace-regexp))
+ (re-search-forward (regexp-quote string) bound noerror count)))
+
+(defun search-backward-lax-whitespace (string &optional bound noerror count)
+ "Search backward for STRING, matching a sequence of whitespace chars."
+ (let ((search-spaces-regexp search-whitespace-regexp))
+ (re-search-backward (regexp-quote string) bound noerror count)))
+
+(defun re-search-forward-lax-whitespace (regexp &optional bound noerror count)
+ "Search forward for REGEXP, matching a sequence of whitespace chars."
+ (let ((search-spaces-regexp search-whitespace-regexp))
+ (re-search-forward regexp bound noerror count)))
+
+(defun re-search-backward-lax-whitespace (regexp &optional bound noerror count)
+ "Search backward for REGEXP, matching a sequence of whitespace chars."
+ (let ((search-spaces-regexp search-whitespace-regexp))
+ (re-search-backward regexp bound noerror count)))
+
\f
(defun isearch-query-replace (&optional delimited regexp-flag)
"Start `query-replace' with string to replace from last search string.
;; set `search-upper-case' to nil to not call
;; `isearch-no-upper-case-p' in `perform-replace'
(search-upper-case nil)
+ (replace-search-function
+ (if (and isearch-lax-whitespace (not regexp-flag))
+ #'search-forward-lax-whitespace
+ replace-search-function))
+ (replace-re-search-function
+ (if (and isearch-regexp-lax-whitespace regexp-flag)
+ #'re-search-forward-lax-whitespace
+ replace-re-search-function))
;; 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.
(list current-prefix-arg))
(isearch-query-replace delimited t))
-(defun isearch-whitespace-regexp ()
- "Return the value of `search-whitespace-regexp' for the current search."
- (cond ((not (consp search-whitespace-regexp))
- search-whitespace-regexp)
- (isearch-regexp
- (cdr search-whitespace-regexp))
- (t
- (car search-whitespace-regexp))))
-
(defun isearch-occur (regexp &optional nlines)
"Run `occur' using the last search string as the regexp.
Interactively, REGEXP is constructed using the search string from the
;; Set `search-upper-case' to nil to not call
;; `isearch-no-upper-case-p' in `occur-1'.
(search-upper-case nil)
- (search-spaces-regexp (isearch-whitespace-regexp)))
+ (search-spaces-regexp
+ (if (if isearch-regexp
+ isearch-regexp-lax-whitespace
+ isearch-lax-whitespace)
+ search-whitespace-regexp)))
(occur regexp nlines)))
(declare-function hi-lock-read-face-name "hi-lock" ())
;; Assume character codes 0200 - 0377 stand for characters in some
;; single-byte character set, and convert them to Emacs
;; characters.
- (if (and isearch-regexp (= char ?\s))
+ (if (and isearch-regexp isearch-regexp-lax-whitespace (= char ?\s))
(if (subregexp-context-p isearch-string (length isearch-string))
(isearch-process-search-string "[ ]" " ")
(isearch-process-search-char char))
(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 'isearch-search-forward 'isearch-search-backward))))
-
-(defun isearch-search-forward (string &optional bound noerror count)
- (re-search-forward (regexp-quote string) bound noerror count))
-
-(defun isearch-search-backward (string &optional bound noerror count)
- (re-search-backward (regexp-quote string) bound noerror count))
+ (if isearch-forward 'search-forward 'search-backward))))
(defun isearch-search-string (string bound noerror)
"Search for the first occurrence of STRING or its translation.
search-invisible))
(inhibit-quit nil)
(case-fold-search isearch-case-fold-search)
- (search-spaces-regexp (isearch-whitespace-regexp))
(retry t))
(setq isearch-error nil)
(while retry
(defvar isearch-lazy-highlight-window-end nil)
(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-lax-whitespace nil)
+(defvar isearch-lazy-highlight-regexp-lax-whitespace nil)
(defvar isearch-lazy-highlight-word nil)
(defvar isearch-lazy-highlight-forward nil)
(defvar isearch-lazy-highlight-error nil)
isearch-regexp))
(not (eq isearch-lazy-highlight-word
isearch-word))
+ (not (eq isearch-lazy-highlight-lax-whitespace
+ isearch-lax-whitespace))
+ (not (eq isearch-lazy-highlight-regexp-lax-whitespace
+ isearch-regexp-lax-whitespace))
(not (= (window-start)
isearch-lazy-highlight-window-start))
(not (= (window-end) ; Window may have been split/joined.
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-space-regexp (isearch-whitespace-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-forward isearch-forward)
(unless (equal isearch-string "")
(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)
(isearch-word isearch-lazy-highlight-word)
(search-invisible nil) ; don't match invisible text
(retry t)