unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Stefan Monnier <monnier@iro.umontreal.ca>
Subject: C-q SPC in isearch
Date: Sun, 05 Dec 2004 20:37:20 -0500	[thread overview]
Message-ID: <87hdn02oyz.fsf-monnier+emacs@gnu.org> (raw)


The recent change to C-q SPC in isearch fixes the problem of searching for
a b [ C-q SPC ] but not the case of a b \ C-q SPC which will end up
searching for "ab\\[ ]".

I suggest the patch below which additionally introduces the function
subregexp-context-p which can be used at other places that need the same
kind of information (e.g. regexp-opt).

Any objection?


        Stefan


Index: lisp/subr.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/subr.el,v
retrieving revision 1.428
diff -u -r1.428 subr.el
--- lisp/subr.el	23 Nov 2004 15:23:57 -0000	1.428
+++ lisp/subr.el	6 Dec 2004 01:32:31 -0000
@@ -2188,6 +2188,46 @@
       ;; Reconstruct a string from the pieces.
       (setq matches (cons (substring string start l) matches)) ; leftover
       (apply #'concat (nreverse matches)))))
+
+(defun subregexp-context-p (regexp pos &optional start)
+  "Return non-nil if POS is in a normal subregexp context in REGEXP.
+A subregexp context is one where a sub-regexp can appear.
+A non-subregexp context is for example within brackets, or within a repetition
+bounds operator \\{..\\}, or right after a \\.
+If START is non-nil, it should be a position in REGEXP, smaller than POS,
+and known to be in a subregexp context."
+  ;; Here's one possible implementation, with the great benefit that it
+  ;; reuses the regexp-matcher's own parser, so it understands all the
+  ;; details of the syntax.  A disadvantage is that it needs to match the
+  ;; error string.
+  (condition-case err
+      (progn
+        (string-match (substring regexp (or start 0) pos) "")
+        t)
+    (invalid-regexp
+     (not (member (cadr err) '("Unmatched [ or [^"
+                               "Unmatched \\{"
+                               "Trailing backslash")))))
+  ;; An alternative implementation:
+  ;; (defconst re-context-re
+  ;;   (let* ((harmless-ch "[^\\[]")
+  ;;          (harmless-esc "\\\\[^{]")
+  ;;          (class-harmless-ch "[^][]")
+  ;;          (class-lb-harmless "[^]:]")
+  ;;          (class-lb-colon-maybe-charclass ":\\([a-z]+:]\\)?")
+  ;;          (class-lb (concat "\\[\\(" class-lb-harmless
+  ;;                            "\\|" class-lb-colon-maybe-charclass "\\)"))
+  ;;          (class
+  ;;           (concat "\\[^?]?"
+  ;;                   "\\(" class-harmless-ch
+  ;;                   "\\|" class-lb "\\)*"
+  ;;                   "\\[?]"))     ; special handling for bare [ at end of re
+  ;;          (braces "\\\\{[0-9,]+\\\\}"))
+  ;;     (concat "\\`\\(" harmless-ch "\\|" harmless-esc
+  ;;             "\\|" class "\\|" braces "\\)*\\'"))
+  ;;   "Matches any prefix that corresponds to a normal subregexp context.")
+  ;; (string-match re-context-re (substring regexp (or start 0) pos))
+  )
 \f
 (defun shell-quote-argument (argument)
   "Quote an argument for passing as argument to an inferior shell."
Index: lisp/isearch.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/isearch.el,v
retrieving revision 1.243
diff -u -r1.243 isearch.el
--- lisp/isearch.el	3 Dec 2004 00:27:11 -0000	1.243
+++ lisp/isearch.el	6 Dec 2004 01:32:32 -0000
@@ -1682,13 +1682,9 @@
     ;; single-byte character set, and convert them to Emacs
     ;; characters.
     (if (and isearch-regexp (= char ?\ ))
-	(if (condition-case err
-		(progn
-		  (string-match isearch-string "")
-		  nil)
-	      (error (equal (cadr err) "Unmatched [ or [^")))
-	    (isearch-process-search-char char)
-	  (isearch-process-search-string "[ ]" " "))
+	(if (subregexp-context-p isearch-string pos)
+	    (isearch-process-search-string "[ ]" " ")
+	  (isearch-process-search-char char))
       (and enable-multibyte-characters
 	   (>= char ?\200)
 	   (<= char ?\377)
Index: regexp-opt.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/emacs-lisp/regexp-opt.el,v
retrieving revision 1.26
diff -u -u -b -r1.26 regexp-opt.el
--- regexp-opt.el	1 Sep 2003 15:45:22 -0000	1.26
+++ regexp-opt.el	6 Dec 2004 01:38:26 -0000
@@ -110,24 +112,6 @@
 	   (re (regexp-opt-group sorted-strings open)))
       (if words (concat "\\<" re "\\>") re))))
 
-(defconst regexp-opt-not-groupie*-re
-  (let* ((harmless-ch "[^\\\\[]")
-         (esc-pair-not-lp "\\\\[^(]")
-         (class-harmless-ch "[^][]")
-         (class-lb-harmless "[^]:]")
-         (class-lb-colon-maybe-charclass ":\\([a-z]+:]\\)?")
-         (class-lb (concat "\\[\\(" class-lb-harmless
-                           "\\|" class-lb-colon-maybe-charclass "\\)"))
-         (class
-          (concat "\\[^?]?"
-                  "\\(" class-harmless-ch
-                  "\\|" class-lb "\\)*"
-                  "\\[?]"))         ; special handling for bare [ at end of re
-         (shy-lp "\\\\(\\?:"))
-    (concat "\\(" harmless-ch "\\|" esc-pair-not-lp
-            "\\|" class "\\|" shy-lp "\\)*"))
-  "Matches any part of a regular expression EXCEPT for non-shy \"\\\\(\"s")
-
 ;;;###autoload
 (defun regexp-opt-depth (regexp)
   "Return the depth of REGEXP.
@@ -137,13 +121,15 @@
     ;; Hack to signal an error if REGEXP does not have balanced parentheses.
     (string-match regexp "")
     ;; Count the number of open parentheses in REGEXP.
-    (let ((count 0) start)
-      (while
-          (progn
-            (string-match regexp-opt-not-groupie*-re regexp start)
-            (setq start ( + (match-end 0) 2))  ; +2 for "\\(" after match-end.
-            (<= start (length regexp)))
-        (setq count (1+ count)))
+    (let ((count 0) start last)
+      (while (string-match "\\\\(\\(\\?:\\)?" regexp start)
+	(setq start (match-end 0))	      ; Start of next search.
+	(when (and (not (match-beginning 1))
+		   (subregexp-context-p regexp (match-beginning 0) last))
+	  ;; It's not a shy group and it's not inside brackets or after
+	  ;; a backslash: it's really a group-open marker.
+	  (setq last start)	    ; Speed up next regexp-opt-re-context-p.
+	  (setq count (1+ count))))
       count)))
 \f
 ;;; Workhorse functions.

             reply	other threads:[~2004-12-06  1:37 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-12-06  1:37 Stefan Monnier [this message]
2004-12-08  0:59 ` C-q SPC in isearch Juri Linkov
2004-12-08  1:38   ` Stefan Monnier

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

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87hdn02oyz.fsf-monnier+emacs@gnu.org \
    --to=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 public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).