From: Juri Linkov <juri@jurta.org>
To: Chong Yidong <cyd@gnu.org>
Cc: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org
Subject: Re: Interpretation of a space in regexp isearch?
Date: Sat, 01 Sep 2012 14:50:45 +0300 [thread overview]
Message-ID: <87k3we0xnu.fsf@mail.jurta.org> (raw)
In-Reply-To: <87ehmm77sx.fsf@gnu.org> (Chong Yidong's message of "Sat, 01 Sep 2012 11:15:10 +0800")
> Right, but the phrase "ignore whitespace" seems to indicate completely
> ignoring whitespace differences *in the search string*, including empty
> whitespace differences. So it is a poor name.
In Diff this option is called --ignore-space-change
that ignores changes in the amount of white space,
but this name is too long.
> How about -lazy-whitespace or -lax-whitespace? Then the command would
> be isearch-toggle-lazy-whitespace or isearch-toggle-lax-whitespace.
Then the names of search functions would be:
lax-whitespace-search-forward - for simple search, and
re-lax-whitespace-search-forward - for regexp search.
And "re-lax" is not a synonym for "lazy" :-) In programming
"lazy" means delayed evaluation, so it's not applicable here
(but isearch-lazy-highlight fits this definition because
it delays the evaluation of highlighting for other matches).
Using the same naming convention as in word-search-forward-lax
like whitespace-search-forward-lax or whitespace-lax-search-forward
is also not possible because as you said the whitespace- prefix
is reserved for whitespace.el.
Thus the remaining possibility is to add -lax-whitespace
as the suffix like:
search-forward-lax-whitespace
re-search-forward-lax-whitespace
that is implemented in the patch below.
If it's basically OK then I'd like to install it,
so you could make more necessary changes.
>> So the question was rather do we need to support lax whitespace in
>> regexp mode at all?
>
> I don't think we should remove the feature outright, so there ought to
> be some way to enable it for regexp mode. Adding some complication to
> the code for this purpose is fine.
>
> That is to say, even if we change things so that C-M-s does not do lax
> space matching by default, it should be easy to get the feature back (by
> customizing a variable), just in case some user somewhere depends on the
> feature.
With a separate variable for regexp lax matching like
`isearch-regexp-lax-whitespace' it will be easy to enable/disable it
and also easier to mark it obsolete later before removing the feature.
=== modified file 'lisp/isearch.el'
--- lisp/isearch.el 2012-08-27 04:08:32 +0000
+++ lisp/isearch.el 2012-09-01 11:47:01 +0000
@@ -120,20 +120,10 @@ (defcustom search-whitespace-regexp (pur
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.
-
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)))
regexp)
:group 'isearch
:version "24.3")
@@ -510,6 +512,7 @@ (defvar isearch-mode-map
(define-key map "\M-r" 'isearch-toggle-regexp)
(define-key map "\M-e" 'isearch-edit-string)
+ (define-key map "\M-s " 'isearch-toggle-lax-whitespace)
(define-key map "\M-sc" 'isearch-toggle-case-fold)
(define-key map "\M-sr" 'isearch-toggle-regexp)
(define-key map "\M-sw" 'isearch-toggle-word)
@@ -556,6 +564,17 @@ (defvar isearch-word nil
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 the incremental search, it
+will match any sequence matched by the regexp in the variable
+`search-whitespace-regexp'.
+If the value is nil, each space you type matches literally,
+against one space.")
+
+(defvar isearch-regexp-lax-whitespace nil
+ "Like `isearch-lax-whitespace' but for regexp mode.")
+
(defvar isearch-cmds nil
"Stack of search status sets.
Each set is a vector of the form:
@@ -1409,6 +1434,24 @@ (defun isearch-toggle-case-fold ()
(sit-for 1)
(isearch-update))
+(defun isearch-toggle-lax-whitespace ()
+ "Toggle whitespace matching in searching on or off."
+ (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))
\f
;; Word search
@@ -1506,6 +1560,24 @@ (defun isearch-symbol-regexp (string &op
(put 'isearch-symbol-regexp 'isearch-message-prefix "symbol ")
+;; Search with lax whitespace
+
+(defun search-forward-lax-whitespace (string &optional bound noerror count)
+ (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)
+ (let ((search-spaces-regexp search-whitespace-regexp))
+ (re-search-backward (regexp-quote string) bound noerror count)))
+
+(defun re-search-forward-lax-whitespace (string &optional bound noerror count)
+ (let ((search-spaces-regexp search-whitespace-regexp))
+ (re-search-forward string bound noerror count)))
+
+(defun re-search-backward-lax-whitespace (string &optional bound noerror count)
+ (let ((search-spaces-regexp search-whitespace-regexp))
+ (re-search-backward string bound noerror count)))
+
\f
(defun isearch-query-replace (&optional delimited regexp-flag)
"Start `query-replace' with string to replace from last search string.
@@ -1522,6 +1594,14 @@ (defun isearch-query-replace (&optional
;; 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.
@@ -1558,15 +1638,6 @@ (defun isearch-query-replace-regexp (&op
(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
@@ -1606,7 +1677,11 @@ (defun isearch-occur (regexp &optional n
;; 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" ())
@@ -2203,7 +2285,7 @@ (defun isearch-quote-char ()
;; 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))
@@ -2443,16 +2533,19 @@ (defun isearch-search-fun-default ()
(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.
@@ -2503,17 +2596,13 @@ (defun isearch-search ()
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
@@ -2805,7 +2941,8 @@ (defvar isearch-lazy-highlight-window-st
(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)
@@ -2847,6 +2984,10 @@ (defun isearch-lazy-highlight-new-loop (
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.
@@ -2873,7 +3014,8 @@ (defun isearch-lazy-highlight-new-loop (
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 "")
@@ -2887,7 +3029,6 @@ (defun isearch-lazy-highlight-search ()
(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)
next prev parent reply other threads:[~2012-09-01 11:50 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-15 4:40 Interpretation of a space in regexp isearch? Dmitry Gutov
2012-08-15 5:27 ` Bastien
2012-08-15 9:11 ` Dani Moncayo
2012-08-15 9:13 ` Dani Moncayo
2012-08-15 9:19 ` Dani Moncayo
2012-08-15 13:59 ` Drew Adams
2012-08-15 14:31 ` Davis Herring
2012-08-15 16:43 ` Drew Adams
2012-08-15 17:54 ` Davis Herring
2012-08-15 22:53 ` Dmitry Gutov
2012-08-15 23:21 ` Drew Adams
2012-08-16 2:25 ` Dmitry Gutov
2012-08-16 5:37 ` Drew Adams
2012-08-26 4:06 ` Chong Yidong
2012-08-26 6:59 ` Bastien
2012-08-26 15:19 ` Dani Moncayo
2012-08-26 17:31 ` Dani Moncayo
2012-08-28 8:28 ` Juri Linkov
2012-08-28 9:07 ` Dani Moncayo
2012-08-28 23:01 ` Juri Linkov
2012-08-27 18:34 ` Johan Bockgård
2012-08-28 8:30 ` Juri Linkov
2012-08-28 12:53 ` Stefan Monnier
2012-08-28 22:54 ` Juri Linkov
2012-08-28 23:52 ` Drew Adams
2012-08-29 8:38 ` Juri Linkov
2012-08-29 16:01 ` Drew Adams
2012-08-29 23:49 ` Juri Linkov
2012-08-30 8:19 ` Chong Yidong
2012-08-30 8:31 ` Chong Yidong
2012-08-30 8:54 ` Juri Linkov
2012-08-30 14:47 ` Stefan Monnier
2012-08-31 0:02 ` Juri Linkov
2012-08-31 0:07 ` Juri Linkov
2012-08-31 5:40 ` Chong Yidong
2012-08-31 9:31 ` Juri Linkov
2012-08-31 14:55 ` Chong Yidong
2012-09-01 0:47 ` Juri Linkov
2012-09-01 3:15 ` Chong Yidong
2012-09-01 11:50 ` Juri Linkov [this message]
2012-09-01 16:02 ` Chong Yidong
2012-08-29 6:46 ` Chong Yidong
2012-08-29 8:28 ` Juri Linkov
2012-08-29 13:55 ` Stefan Monnier
2012-08-29 15:11 ` Dani Moncayo
2012-08-29 23:51 ` Juri Linkov
2012-08-28 8:27 ` Juri Linkov
2012-08-29 6:59 ` Chong Yidong
2012-08-29 8:34 ` Juri Linkov
2012-08-30 9:01 ` Chong Yidong
2012-08-30 9:18 ` Juri Linkov
-- strict thread matches above, loose matches on Subject: below --
2012-08-14 23:45 Dmitry Gutov
2012-08-14 23:03 Bastien
2012-08-14 23:45 ` Davis Herring
2012-08-14 23:53 ` Bastien
2012-08-15 3:42 ` Chong Yidong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87k3we0xnu.fsf@mail.jurta.org \
--to=juri@jurta.org \
--cc=cyd@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=monnier@iro.umontreal.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.