[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/relint 9ca2140ab0 1/2: Add defcustom `relint-xr-checks`
From: |
ELPA Syncer |
Subject: |
[elpa] externals/relint 9ca2140ab0 1/2: Add defcustom `relint-xr-checks` for optional noisy xr-lint checks |
Date: |
Tue, 1 Aug 2023 09:58:52 -0400 (EDT) |
branch: externals/relint
commit 9ca2140ab05c5415e56d0bd9117f865275471475
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>
Add defcustom `relint-xr-checks` for optional noisy xr-lint checks
Require xr 1.24 where the CHECKS argument to xr-lint appeared.
Add the new checks in that xr version to README.
---
README | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
relint-test.el | 17 ++++++++++++++++
relint.el | 17 +++++++++++++---
3 files changed, 95 insertions(+), 3 deletions(-)
diff --git a/README b/README
index 1db153a450..ef30ff2545 100644
--- a/README
+++ b/README
@@ -10,6 +10,7 @@ skip-syntax-forward and skip-syntax-backward.
- Usage
- Installation
+ - Configuration
- What the diagnostics mean
- Suppressing diagnostics
- How it works
@@ -57,6 +58,17 @@ skip-syntax-forward and skip-syntax-backward.
it will be installed automatically.
+* Configuration
+
+ No configuration is required.
+
+ There is a single user option, 'relint-xr-checks'.
+ If set to 'all', it enables more thorough checks that detect more
+ errors and performance problems but may also produce more false
+ warnings. The default value is 'nil', limiting warnings to ones that
+ are likely to be accurate.
+
+
* What the diagnostics mean
Tip: if a regexp string is difficult to understand, consider
@@ -118,11 +130,45 @@ skip-syntax-forward and skip-syntax-backward.
consecutive character codes. This is often caused by a misplaced
hyphen.
+ - Range 'A-z' between upper and lower case includes symbols
+
+ A range spans over upper and lower case letters, which also
+ includes some symbols. This is probably unintentional. To cover
+ both upper and lower case letters, use separate ranges, as in
+ [A-Za-z].
+
+ - Suspect character range '+-X': should '-' be literal?
+
+ A range has + as one of its endpoints, which could mean that the
+ hyphen was actually intended to be literal in order to match both
+ + and -.
+ This check is only enable when relint-xr-checks = all.
+
+ - Possibly erroneous '\X' in character alternative
+
+ A character alternative includes something that looks like a
+ escape sequence, but no escape sequences are allowed there since
+ backslash is not a special character in that context.
+ It could also be a caused by too many backslashes.
+
+ For example, "[\\n\\t]" matches the characters 'n', 't' and
+ backslash, but could be an attempt to match newline and tab.
+ This check is only enable when relint-xr-checks = all.
+
- Duplicated character class '[:class:]'
A character class occurs twice in a single character alternative
or skip set.
+ - Or-pattern more efficiently expressed as character alternative
+
+ When an or-pattern can be written as a character alternative, it
+ becomes more efficient and reduces regexp stack usage.
+ For example, a\|b is better written [ab], and \s-\|\sw is usually
+ better written [[:space:][:word:]]. (There is a subtle difference
+ in how syntax properties are handled but it rarely matters.)
+ This check is only enable when relint-xr-checks = all.
+
- Duplicated alternative branch
The same expression occurs in two different branches, like in
@@ -227,6 +273,24 @@ skip-syntax-forward and skip-syntax-backward.
In general, A?, where A matches the empty string, can be
simplified to just A.
+ - Repetition of effective repetition
+
+ A repetition construct is applied to an expression that itself
+ contains a repetition, in addition to some patterns that may match
+ the empty string. This can lead to bad matching performance.
+
+ Example: \(?:a*b+\)* is equivalent to the much faster \(?:a\|b\)* .
+
+ Another example: \(?:a*b+\)+ is better written a*b[ab]* .
+
+ This check is only enable when relint-xr-checks = all.
+
+ - Possibly mistyped ':?' at start of group
+
+ A group starts as \(:? which makes it likely that it was really
+ meant to be \(?: -- ie, a non-capturing group.
+ This check is only enable when relint-xr-checks = all.
+
- Unnecessarily escaped 'X'
A character is backslash-escaped in a skip set despite not being
diff --git a/relint-test.el b/relint-test.el
index 0c1cbf9c92..0b1999cefb 100644
--- a/relint-test.el
+++ b/relint-test.el
@@ -188,4 +188,21 @@ and a path."
)))))
(kill-buffer buf))))
+(ert-deftest relint-xr-checks ()
+ ;; Test optional checks enabled with `relint-xr-checks'.
+ (dolist (checks '(nil all))
+ (let* ((relint-xr-checks checks)
+ (warnings
+ (with-temp-buffer
+ (emacs-lisp-mode)
+ (insert (format "(looking-at %S)\n"
+ "\\(:?xy\\)+"))
+ (let ((text-quoting-style 'grave))
+ (relint-buffer (current-buffer)))))
+ (msg
+ "In call to looking-at: Possibly mistyped `:?' at start of group"))
+ (should (equal warnings
+ (and checks
+ `((,msg 13 17 "\\(:?xy\\)+" 2 warning))))))))
+
(provide 'relint-test)
diff --git a/relint.el b/relint.el
index ef00882282..101429337f 100644
--- a/relint.el
+++ b/relint.el
@@ -4,7 +4,7 @@
;; Author: Mattias Engdegård <mattiase@acm.org>
;; Version: 1.22
-;; Package-Requires: ((xr "1.22") (emacs "26.1"))
+;; Package-Requires: ((xr "1.24") (emacs "26.1"))
;; URL: https://github.com/mattiase/relint
;; Keywords: lisp, regexps
@@ -118,6 +118,15 @@
(require 'cl-lib)
(require 'subr-x)
+(defcustom relint-xr-checks nil
+ "Extra checks to be performed by `xr' for each regexp.
+This is the CHECKS argument passed to `xr-lint' (q.v.).
+It is either nil, meaning the standard set of checks with minimal
+false positives, or `all', enabling all checks."
+ :group 'relint
+ :type '(choice (const :tag "Standard checks only" nil)
+ (const :tag "All checks" all)))
+
(defun relint--get-error-buffer ()
"Buffer to which errors are printed, or nil if noninteractive."
(and (not noninteractive)
@@ -351,10 +360,12 @@ or nil if no position could be determined."
(relint--check-string skip-set-string #'xr-skip-set-lint name pos path))
(defun relint--check-re-string (re name pos path)
- (relint--check-string re #'xr-lint name pos path))
+ (relint--check-string re (lambda (x) (xr-lint x nil relint-xr-checks))
+ name pos path))
(defun relint--check-file-re-string (re name pos path)
- (relint--check-string re (lambda (x) (xr-lint x 'file)) name pos path))
+ (relint--check-string re (lambda (x) (xr-lint x 'file relint-xr-checks))
+ name pos path))
(defun relint--check-syntax-string (syntax name pos path)
(relint--check-string syntax #'relint--syntax-string-lint name pos path))