Allow zero-argument rx or' and seq' forms

Make the rx `or' and `seq' forms accept zero arguments to produce a
never-matching regexp and an empty string, respectively.

* lisp/emacs-lisp/rx.el (rx-constituents, rx-or): Permit zero args.
(rx): Amend doc string for `or' and `seq'.
* test/lisp/emacs-lisp/rx-tests.el (rx-or, rx-seq): Test the change.
* etc/NEWS (Changes in Specialized Modes and Packages): Mention the change.
This commit is contained in:
Mattias Engdegård 2019-05-15 22:44:00 +02:00
parent e9f9827eb0
commit b552fc05c2
3 changed files with 21 additions and 6 deletions

View file

@ -110,11 +110,11 @@
;; FIXME: support macros.
(defvar rx-constituents ;Not `const' because some modes extend it.
'((and . (rx-and 1 nil))
'((and . (rx-and 0 nil))
(seq . and) ; SRE
(: . and) ; SRE
(sequence . and) ; sregex
(or . (rx-or 1 nil))
(or . (rx-or 0 nil))
(| . or) ; SRE
(not-newline . ".")
(nonl . not-newline) ; SRE
@ -390,9 +390,11 @@ FORM is of the form `(and FORM1 ...)'."
"Parse and produce code from FORM, which is `(or FORM1 ...)'."
(rx-check form)
(rx-group-if
(if (memq nil (mapcar 'stringp (cdr form)))
(mapconcat (lambda (x) (rx-form x '|)) (cdr form) "\\|")
(cond
((null (cdr form)) regexp-unmatchable)
((cl-every #'stringp (cdr form))
(regexp-opt (cdr form) nil t))
(t (mapconcat (lambda (x) (rx-form x '|)) (cdr form) "\\|")))
(and (memq rx-parent '(: * t)) rx-parent)))
@ -1121,6 +1123,7 @@ CHAR
`(seq SEXP1 SEXP2 ...)'
`(sequence SEXP1 SEXP2 ...)'
matches what SEXP1 matches, followed by what SEXP2 matches, etc.
Without arguments, matches the empty string.
`(submatch SEXP1 SEXP2 ...)'
`(group SEXP1 SEXP2 ...)'
@ -1136,7 +1139,7 @@ CHAR
`(| SEXP1 SEXP2 ...)'
matches anything that matches SEXP1 or SEXP2, etc. If all
args are strings, use `regexp-opt' to optimize the resulting
regular expression.
regular expression. Without arguments, never matches anything.
`(minimal-match SEXP)'
produce a non-greedy regexp for SEXP. Normally, regexps matching