diff options
| author | Mattias EngdegÄrd | 2019-12-13 13:10:58 +0100 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2019-12-13 13:30:14 +0100 |
| commit | 82b4e48c590cf2c0448a751e641b0ee7a6a02438 (patch) | |
| tree | 55da830604ce9ebe4a5aa626bec285fb688578a3 /lisp | |
| parent | b04086adf649b18cf5309dd43aa638fc7b3cd4a0 (diff) | |
| download | emacs-82b4e48c590cf2c0448a751e641b0ee7a6a02438.tar.gz emacs-82b4e48c590cf2c0448a751e641b0ee7a6a02438.zip | |
Allow characters and single-char strings in rx charsets
The `not' and `intersection' forms, and `or' inside these forms,
now accept characters and single-character strings as arguments.
Previously, they had to be wrapped in `any' forms.
This does not add expressive power but is a convenience and is easily
understood.
* doc/lispref/searching.texi (Rx Constructs): Amend the documentation.
* etc/NEWS: Announce the change.
* lisp/emacs-lisp/rx.el (rx--charset-p, rx--translate-not)
(rx--charset-intervals, rx): Accept characters and 1-char strings in
more places.
* test/lisp/emacs-lisp/rx-tests.el (rx-not, rx-charset-or)
(rx-def-in-charset-or, rx-intersection): Test the change.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/emacs-lisp/rx.el | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index a5cab1db888..43f7a4e2752 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el | |||
| @@ -309,6 +309,8 @@ and set operations." | |||
| 309 | (rx--every (lambda (x) (not (symbolp x))) (cdr form))) | 309 | (rx--every (lambda (x) (not (symbolp x))) (cdr form))) |
| 310 | (and (memq (car form) '(not or | intersection)) | 310 | (and (memq (car form) '(not or | intersection)) |
| 311 | (rx--every #'rx--charset-p (cdr form))))) | 311 | (rx--every #'rx--charset-p (cdr form))))) |
| 312 | (characterp form) | ||
| 313 | (and (stringp form) (= (length form) 1)) | ||
| 312 | (and (or (symbolp form) (consp form)) | 314 | (and (or (symbolp form) (consp form)) |
| 313 | (let ((expanded (rx--expand-def form))) | 315 | (let ((expanded (rx--expand-def form))) |
| 314 | (and expanded | 316 | (and expanded |
| @@ -521,6 +523,11 @@ If NEGATED, negate the sense (thus making it positive)." | |||
| 521 | ((eq arg 'word-boundary) | 523 | ((eq arg 'word-boundary) |
| 522 | (rx--translate-symbol | 524 | (rx--translate-symbol |
| 523 | (if negated 'word-boundary 'not-word-boundary))) | 525 | (if negated 'word-boundary 'not-word-boundary))) |
| 526 | ((characterp arg) | ||
| 527 | (rx--generate-alt (not negated) (list (cons arg arg)) nil)) | ||
| 528 | ((and (stringp arg) (= (length arg) 1)) | ||
| 529 | (let ((char (string-to-char arg))) | ||
| 530 | (rx--generate-alt (not negated) (list (cons char char)) nil))) | ||
| 524 | ((let ((expanded (rx--expand-def arg))) | 531 | ((let ((expanded (rx--expand-def arg))) |
| 525 | (and expanded | 532 | (and expanded |
| 526 | (rx--translate-not negated (list expanded))))) | 533 | (rx--translate-not negated (list expanded))))) |
| @@ -571,8 +578,8 @@ If NEGATED, negate the sense (thus making it positive)." | |||
| 571 | (defun rx--charset-intervals (charset) | 578 | (defun rx--charset-intervals (charset) |
| 572 | "Return a sorted list of non-adjacent disjoint intervals from CHARSET. | 579 | "Return a sorted list of non-adjacent disjoint intervals from CHARSET. |
| 573 | CHARSET is any expression allowed in a character set expression: | 580 | CHARSET is any expression allowed in a character set expression: |
| 574 | either `any' (no classes permitted), or `not', `or' or `intersection' | 581 | characters, single-char strings, `any' forms (no classes permitted), |
| 575 | forms whose arguments are charsets." | 582 | or `not', `or' or `intersection' forms whose arguments are charsets." |
| 576 | (pcase charset | 583 | (pcase charset |
| 577 | (`(,(or 'any 'in 'char) . ,body) | 584 | (`(,(or 'any 'in 'char) . ,body) |
| 578 | (let ((parsed (rx--parse-any body))) | 585 | (let ((parsed (rx--parse-any body))) |
| @@ -584,6 +591,11 @@ forms whose arguments are charsets." | |||
| 584 | (`(not ,x) (rx--complement-intervals (rx--charset-intervals x))) | 591 | (`(not ,x) (rx--complement-intervals (rx--charset-intervals x))) |
| 585 | (`(,(or 'or '|) . ,body) (rx--charset-union body)) | 592 | (`(,(or 'or '|) . ,body) (rx--charset-union body)) |
| 586 | (`(intersection . ,body) (rx--charset-intersection body)) | 593 | (`(intersection . ,body) (rx--charset-intersection body)) |
| 594 | ((pred characterp) | ||
| 595 | (list (cons charset charset))) | ||
| 596 | ((guard (and (stringp charset) (= (length charset) 1))) | ||
| 597 | (let ((char (string-to-char charset))) | ||
| 598 | (list (cons char char)))) | ||
| 587 | (_ (let ((expanded (rx--expand-def charset))) | 599 | (_ (let ((expanded (rx--expand-def charset))) |
| 588 | (if expanded | 600 | (if expanded |
| 589 | (rx--charset-intervals expanded) | 601 | (rx--charset-intervals expanded) |
| @@ -1161,10 +1173,12 @@ CHAR Match a literal character. | |||
| 1161 | character, a string, a range as string \"A-Z\" or cons | 1173 | character, a string, a range as string \"A-Z\" or cons |
| 1162 | (?A . ?Z), or a character class (see below). Alias: in, char. | 1174 | (?A . ?Z), or a character class (see below). Alias: in, char. |
| 1163 | (not CHARSPEC) Match one character not matched by CHARSPEC. CHARSPEC | 1175 | (not CHARSPEC) Match one character not matched by CHARSPEC. CHARSPEC |
| 1164 | can be (any ...), (or ...), (intersection ...), | 1176 | can be a character, single-char string, (any ...), (or ...), |
| 1165 | (syntax ...), (category ...), or a character class. | 1177 | (intersection ...), (syntax ...), (category ...), |
| 1166 | (intersection CHARSET...) Intersection of CHARSETs. | 1178 | or a character class. |
| 1167 | CHARSET is (any...), (not...), (or...) or (intersection...). | 1179 | (intersection CHARSET...) Match all CHARSETs. |
| 1180 | CHARSET is (any...), (not...), (or...) or (intersection...), | ||
| 1181 | a character or a single-char string. | ||
| 1168 | not-newline Match any character except a newline. Alias: nonl. | 1182 | not-newline Match any character except a newline. Alias: nonl. |
| 1169 | anychar Match any character. Alias: anything. | 1183 | anychar Match any character. Alias: anything. |
| 1170 | unmatchable Never match anything at all. | 1184 | unmatchable Never match anything at all. |