]> git.eshelyaron.com Git - emacs.git/commitdiff
Expand rx definitions inside (not ...)
authorMattias Engdegård <mattiase@acm.org>
Sun, 27 Oct 2019 08:54:54 +0000 (09:54 +0100)
committerMattias Engdegård <mattiase@acm.org>
Sun, 27 Oct 2019 08:54:54 +0000 (09:54 +0100)
* lisp/emacs-lisp/rx.el (rx--translate-not):
* test/lisp/emacs-lisp/rx-tests.el (rx-not, rx-def-in-not):
* doc/lispref/searching.texi (Rx Constructs, Extending Rx):

Allow user-defined rx constructs to be expanded inside (not ...)
forms, for better composability (bug#37849).

doc/lispref/searching.texi
lisp/emacs-lisp/rx.el
test/lisp/emacs-lisp/rx-tests.el

index 5178575a3bb6155727e204f7dac16080da39e0b2..74b15cfc7fd987dd8d9193a360e9a28f109fcdd6 100644 (file)
@@ -1214,7 +1214,7 @@ Corresponding string regexp: @samp{[@dots{}]}
 @item @code{(not @var{charspec})}
 @cindex @code{not} in rx
 Match a character not included in @var{charspec}.  @var{charspec} can
-be an @code{any}, @code{syntax} or @code{category} form, or a
+be an @code{any}, @code{not}, @code{syntax} or @code{category} form, or a
 character class.@*
 Corresponding string regexp: @samp{[^@dots{}]}, @samp{\S@var{code}},
 @samp{\C@var{code}}
@@ -1581,7 +1581,7 @@ when they are used, not when they are defined.
 User-defined forms are allowed wherever arbitrary @code{rx}
 expressions are expected; for example, in the body of a
 @code{zero-or-one} form, but not inside @code{any} or @code{category}
-forms.
+forms.  They are also allowed inside @code{not} forms.
 @end itemize
 
 @defmac rx-define name [arglist] rx-form
index d7677f14443cdbf6f1b738d59dc38fa64dbb843c..52a35ffa2a7797cfa6c5ecb0818ab22c6e4d0051 100644 (file)
@@ -477,6 +477,9 @@ If NEGATED, negate the sense (thus making it positive)."
      ((eq arg 'word-boundary)
       (rx--translate-symbol
        (if negated 'word-boundary 'not-word-boundary)))
+     ((let ((expanded (rx--expand-def arg)))
+        (and expanded
+             (rx--translate-not negated (list expanded)))))
      (t (error "Illegal argument to rx `not': %S" arg)))))
 
 (defun rx--atomic-regexp (item)
index ef2541d83af1f841ae586172effd96cc2dac465c..4ecc805aead1154e36ee051876a63705189da7e8 100644 (file)
   (should (equal (rx (not (syntax punctuation)) (not (syntax escape)))
                  "\\S.\\S\\"))
   (should (equal (rx (not (category tone-mark)) (not (category lao)))
-                 "\\C4\\Co")))
+                 "\\C4\\Co"))
+  (should (equal (rx (not (not ascii)) (not (not (not (any "a-z")))))
+                 "[[:ascii:]][^a-z]")))
 
 (ert-deftest rx-group ()
   (should (equal (rx (group nonl) (submatch "x")
   (should-error (rx-let-eval '((not-char () "x")) nil))
   (should-error (rx-let-eval '((not-char "x")) nil)))
 
+(ert-deftest rx-def-in-not ()
+  "Test definition expansion inside (not ...)."
+  (rx-let ((a alpha)
+           (b (not hex))
+           (c (not (category base)))
+           (d (x) (any ?a x ?z))
+           (e (x) (syntax x))
+           (f (not b)))
+    (should (equal (rx (not a) (not b) (not c) (not f))
+                   "[^[:alpha:]][[:xdigit:]]\\c.[^[:xdigit:]]"))
+    (should (equal (rx (not (d ?m)) (not (e symbol)))
+                   "[^amz]\\S_"))))
+
 (ert-deftest rx-constituents ()
   (let ((rx-constituents
          (append '((beta . gamma)