branch: elpa/flymake-collection
commit e9a1e2ab269f0418963665d991423f8afae6bae6
Author: Mohsin Kaleem <[email protected]>
Commit: Mohsin Kaleem <[email protected]>
Cleanup flymake-rest-define and remove flymake-rest-parse-*
This commit deletes the previous `flymake-rest-parse-rx.el` and
`flymake-rest-parse-enumerate.el` files and adds the functionality
for them into `flymake-rest-define.el`. To use parse-rx use
`flymake-rest-define-rx` and to use parse-enumerate use
`flymake-rest-define-enumerate`.
This was done to make byte compilation cleaner. Now we don't lexically
assign any variables (such as flymake-rest-context) when it will remain
unused for a lot of syntax checkers.
---
checkers/flymake-rest-awk-gawk.el | 14 +-
checkers/flymake-rest-clang.el | 14 +-
checkers/flymake-rest-eslint.el | 48 +--
checkers/flymake-rest-gcc.el | 14 +-
checkers/flymake-rest-html-tidy.el | 12 +-
checkers/flymake-rest-jq.el | 11 +-
checkers/flymake-rest-jsonlint.el | 11 +-
checkers/flymake-rest-less.el | 10 +-
checkers/flymake-rest-lua.el | 16 +-
checkers/flymake-rest-luacheck.el | 14 +-
checkers/flymake-rest-markdownlint.el | 10 +-
checkers/flymake-rest-mypy.el | 14 +-
checkers/flymake-rest-proselint.el | 41 ++-
checkers/flymake-rest-pycodestyle.el | 13 +-
checkers/flymake-rest-pylint.el | 44 +--
checkers/flymake-rest-rubocop.el | 14 +-
checkers/flymake-rest-shellcheck.el | 41 ++-
checkers/flymake-rest-sql-lint.el | 10 +-
checkers/flymake-rest-sqlint.el | 32 +-
checkers/flymake-rest-xmllint.el | 14 +-
checkers/flymake-rest-yamllint.el | 13 +-
flymake-rest-define.el | 599 ++++++++++++++++++++++++----------
flymake-rest-parse-enumerate.el | 56 ----
flymake-rest-parse-rx.el | 164 ----------
flymake-rest.el | 4 +-
25 files changed, 619 insertions(+), 614 deletions(-)
diff --git a/checkers/flymake-rest-awk-gawk.el
b/checkers/flymake-rest-awk-gawk.el
index d1b6a694ab..0f4e3dd77f 100644
--- a/checkers/flymake-rest-awk-gawk.el
+++ b/checkers/flymake-rest-awk-gawk.el
@@ -26,11 +26,10 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
;;;###autoload (autoload 'flymake-rest-awk-gawk "flymake-rest-awk-gawk")
-(flymake-rest-define flymake-rest-awk-gawk
+(flymake-rest-define-rx flymake-rest-awk-gawk
"GNU awk's built-in --lint checker."
:title "gawk-awk"
:pre-let ((gawk-exec (executable-find "gawk")))
@@ -39,14 +38,13 @@
:write-type 'pipe
:command (list gawk-exec
;; Avoid code execution. See
https://github.com/w0rp/ale/pull/1411
- "--source" "'BEGIN{exit} END{exit 1}'"
+ "--source" "BEGIN{exit} END{exit 0}"
"-f" "-"
"--lint"
null-device)
- :error-parser
- (flymake-rest-parse-rx
- ((error bol (? "g") "awk: -:" line ": " (or "fatal" "error") ": "
(message) eol)
- (warning bol (? "g") "awk: -:" line ": " "warning" ": "
(message) eol))))
+ :regexps
+ ((error bol (? "g") "awk: -:" line ": " (or "fatal" "error") ": "
(message) eol)
+ (warning bol (? "g") "awk: -:" line ": " "warning" ": "
(message) eol)))
(provide 'flymake-rest-awk-gawk)
diff --git a/checkers/flymake-rest-clang.el b/checkers/flymake-rest-clang.el
index b80880c8df..41c9b34918 100644
--- a/checkers/flymake-rest-clang.el
+++ b/checkers/flymake-rest-clang.el
@@ -26,8 +26,7 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
(defvar flymake-rest-clang-args
'("-pedantic" "-pedantic-errors")
@@ -37,7 +36,7 @@
"Default include path for gcc in `flymake-rest-clang'.")
;;;###autoload (autoload 'flymake-rest-clang "flymake-rest-clang")
-(flymake-rest-define flymake-rest-clang
+(flymake-rest-define-rx flymake-rest-clang
"A C/C++ syntax checker using Clang.
See URL `http://clang.llvm.org/'."
@@ -63,11 +62,10 @@ See URL `http://clang.llvm.org/'."
('c-mode "c")
((or 'c++-mode _) "c++"))
"-")
- :error-parser
- (flymake-rest-parse-rx
- ((error bol "<stdin>:" line ":" column ": " (or "fatal" "error") ": "
(message) eol)
- (warning bol "<stdin>:" line ":" column ": " "warning" ": "
(message) eol)
- (note bol "<stdin>:" line ":" column ": " "note" ": "
(message) eol))))
+ :regexps
+ ((error bol "<stdin>:" line ":" column ": " (? "fatal ") "error" ": "
(message) eol)
+ (warning bol "<stdin>:" line ":" column ": " "warning" ": "
(message) eol)
+ (note bol "<stdin>:" line ":" column ": " "note" ": "
(message) eol)))
(provide 'flymake-rest-gcc)
diff --git a/checkers/flymake-rest-eslint.el b/checkers/flymake-rest-eslint.el
index f284690523..7ca7288a65 100644
--- a/checkers/flymake-rest-eslint.el
+++ b/checkers/flymake-rest-eslint.el
@@ -26,11 +26,10 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-enumerate))
+ (require 'flymake-rest-define))
;;;###autoload (autoload 'flymake-rest-eslint "flymake-rest-eslint")
-(flymake-rest-define flymake-rest-eslint
+(flymake-rest-define-enumerate flymake-rest-eslint
"A Javascript syntax and style checker using eslint.
See URL `https://eslint.org/'."
@@ -45,25 +44,30 @@ See URL `https://eslint.org/'."
"--stdin"
,@(when-let ((file (buffer-file-name flymake-rest-source)))
(list "--stdin-filename" file)))
- :error-parser
- (flymake-rest-parse-enumerate
- (alist-get
- 'messages
- (caar
- (flymake-rest-parse-json
- (buffer-substring-no-properties
- (point-min) (point-max)))))
- (let-alist it
- (let ((loc (cons (car (flymake-diag-region flymake-rest-source .line
.column))
- (cdr (flymake-diag-region flymake-rest-source .endLine
.endColumn)))))
- (list flymake-rest-source
- (car loc)
- (cdr loc)
- (pcase .severity
- (2 :error)
- (1 :warning)
- (_ :note))
- (concat "[" .ruleId "] " .message))))))
+ :generator
+ (alist-get
+ 'messages
+ (caar
+ (flymake-rest-parse-json
+ (buffer-substring-no-properties
+ (point-min) (point-max)))))
+ :enumerate-parser
+ (let-alist it
+ (let* ((start-loc (flymake-diag-region flymake-rest-source .line .column))
+ (loc (cons (car start-loc)
+ (cdr
+ (if (and .endLine .endColumn)
+ (flymake-diag-region flymake-rest-source
+ .endLine (1- .endColumn))
+ start-loc)))))
+ (list flymake-rest-source
+ (car loc)
+ (cdr loc)
+ (pcase .severity
+ (2 :error)
+ (1 :warning)
+ (_ :note))
+ (concat "[" .ruleId "] " .message)))))
(provide 'flymake-rest-eslint)
diff --git a/checkers/flymake-rest-gcc.el b/checkers/flymake-rest-gcc.el
index bf728f3a4e..16502840f4 100644
--- a/checkers/flymake-rest-gcc.el
+++ b/checkers/flymake-rest-gcc.el
@@ -23,10 +23,9 @@
;;; Code:
(require 'flymake)
-(require 'flymake-rest-define)
(eval-when-compile
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
(defcustom flymake-rest-gcc-args
'("-pedantic" "-pedantic-errors")
@@ -40,7 +39,7 @@
:group 'flymake-rest)
;;;###autoload (autoload 'flymake-rest-gcc "flymake-rest-gcc")
-(flymake-rest-define flymake-rest-gcc
+(flymake-rest-define-rx flymake-rest-gcc
"A C/C++ syntax checker using GCC.
Requires GCC 4.4 or newer. See URL `https://gcc.gnu.org/'."
@@ -67,11 +66,10 @@ Requires GCC 4.4 or newer. See URL `https://gcc.gnu.org/'."
;; code.
"-S" "-o" ,null-device
"-")
- :error-parser
- (flymake-rest-parse-rx
- ((error bol "<stdin>:" line ":" column ": " (or "fatal" "error") ": "
(message) eol)
- (warning bol "<stdin>:" line ":" column ": " "warning" ": "
(message) eol)
- (note bol "<stdin>:" line ":" column ": " "note" ": "
(message) eol))))
+ :regexps
+ ((error bol "<stdin>:" line ":" column ": " (? "fatal ") "error" ": "
(message) eol)
+ (warning bol "<stdin>:" line ":" column ": " "warning" ": "
(message) eol)
+ (note bol "<stdin>:" line ":" column ": " "note" ": "
(message) eol)))
(provide 'flymake-rest-gcc)
diff --git a/checkers/flymake-rest-html-tidy.el
b/checkers/flymake-rest-html-tidy.el
index 6481998a42..41ba2c7000 100644
--- a/checkers/flymake-rest-html-tidy.el
+++ b/checkers/flymake-rest-html-tidy.el
@@ -26,11 +26,10 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
;;;###autoload (autoload 'flymake-rest-html-tidy "flymake-rest-html-tidy")
-(flymake-rest-define flymake-rest-html-tidy
+(flymake-rest-define-rx flymake-rest-html-tidy
"A HTML syntax and style checker using Tidy.
See URL `https://github.com/htacg/tidy-html5'."
@@ -40,10 +39,9 @@ See URL `https://github.com/htacg/tidy-html5'."
(error "Cannot find tidy executable"))
:write-type 'pipe
:command `(,tidy-exec "-lang" "en" "-e" "-q")
- :error-parser
- (flymake-rest-parse-rx
- ((error bol "line " line " column " column " - Error: " (message) eol)
- (warning bol "line " line " column " column " - Warning: " (message)
eol))))
+ :regexps
+ ((error bol "line " line " column " column " - Error: " (message) eol)
+ (warning bol "line " line " column " column " - Warning: " (message) eol)))
(provide 'flymake-rest-html-tidy)
diff --git a/checkers/flymake-rest-jq.el b/checkers/flymake-rest-jq.el
index 3e33cc4e6b..8f0495bd25 100644
--- a/checkers/flymake-rest-jq.el
+++ b/checkers/flymake-rest-jq.el
@@ -26,11 +26,10 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
;;;###autoload (autoload 'flymake-rest-jq "flymake-rest-jq")
-(flymake-rest-define flymake-rest-jq
+(flymake-rest-define-rx flymake-rest-jq
"JSON checker using the jq tool.
This checker accepts multiple consecutive JSON values in a
@@ -43,11 +42,9 @@ See URL `https://stedolan.github.io/jq/'."
(error "Cannot find jq executable"))
:write-type 'pipe
:command (list jq-exec "." "-" null-device)
- :error-parser
- (flymake-rest-parse-rx
- ((error bol "parse error: " (message) " at line " line ", column " column
eol))))
+ :regexps
+ ((error bol "parse error: " (message) " at line " line ", column " column
eol)))
(provide 'flymake-rest-jq)
-
;;; flymake-rest-jq.el ends here
diff --git a/checkers/flymake-rest-jsonlint.el
b/checkers/flymake-rest-jsonlint.el
index 113450b669..a13a8e86dc 100644
--- a/checkers/flymake-rest-jsonlint.el
+++ b/checkers/flymake-rest-jsonlint.el
@@ -26,11 +26,10 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
;;;###autoload (autoload 'flymake-rest-jsonlint "flymake-rest-jsonlint")
-(flymake-rest-define flymake-rest-jsonlint
+(flymake-rest-define-rx flymake-rest-jsonlint
"A JSON syntax and style checker using jsonlint.
See URL `https://github.com/zaach/jsonlint'."
@@ -40,11 +39,9 @@ See URL `https://github.com/zaach/jsonlint'."
(error "Cannot find jsonlint executable"))
:write-type 'file
:command (list jsonlint-exec "-c" "-q" flymake-rest-temp-file)
- :error-parser
- (flymake-rest-parse-rx
- ((error bol (file-name) ": line " line ", col " column ", " (message)
eol))))
+ :regexps
+ ((error bol (file-name) ": line " line ", col " column ", " (message) eol)))
(provide 'flymake-rest-jsonlint)
-
;;; flymake-rest-jsonlint.el ends here
diff --git a/checkers/flymake-rest-less.el b/checkers/flymake-rest-less.el
index 7ad0fa2377..0b3a2edc29 100644
--- a/checkers/flymake-rest-less.el
+++ b/checkers/flymake-rest-less.el
@@ -26,11 +26,10 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
;;;###autoload (autoload 'flymake-rest-less "flymake-rest-less")
-(flymake-rest-define flymake-rest-less
+(flymake-rest-define-rx flymake-rest-less
"A LESS syntax checker using lessc.
Requires lessc 1.4 or newer.
@@ -42,9 +41,8 @@ See URL `http://lesscss.org'."
(error "Cannot find lessc executable"))
:write-type 'pipe
:command (list lessc-exec "--lint" "--no-color" "-")
- :error-parser
- (flymake-rest-parse-rx
- ((error bol (+ not-newline) ": " (message) " in - on line " line ", column
" column ":" eol))))
+ :regexps
+ ((error bol (+ not-newline) ": " (message) " in - on line " line ", column "
column ":" eol)))
(provide 'flymake-rest-less)
diff --git a/checkers/flymake-rest-lua.el b/checkers/flymake-rest-lua.el
index 13630184b4..712c60bf54 100644
--- a/checkers/flymake-rest-lua.el
+++ b/checkers/flymake-rest-lua.el
@@ -26,11 +26,10 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
;;;###autoload (autoload 'flymake-rest-lua "flymake-rest-lua")
-(flymake-rest-define flymake-rest-lua
+(flymake-rest-define-rx flymake-rest-lua
"A Lua syntax checker using the Lua compiler.
See URL `http://www.lua.org/'."
@@ -39,12 +38,11 @@ See URL `http://www.lua.org/'."
(user-error "Cannot find lua compiler executable"))
:write-type 'pipe
:command `(,lua-exec "-p" "-")
- :error-parser
- (flymake-rest-parse-rx
- ((error bol
- ;; Skip the name of the luac executable.
- (minimal-match (zero-or-more not-newline))
- ": stdin:" line ": " (message) eol))))
+ :regexps
+ ((error bol
+ ;; Skip the name of the luac executable.
+ (minimal-match (zero-or-more not-newline))
+ ": stdin:" line ": " (message) eol)))
(provide 'flymake-rest-lua)
diff --git a/checkers/flymake-rest-luacheck.el
b/checkers/flymake-rest-luacheck.el
index 24062b6c49..d34516885f 100644
--- a/checkers/flymake-rest-luacheck.el
+++ b/checkers/flymake-rest-luacheck.el
@@ -26,8 +26,7 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
(defcustom flymake-rest-luacheck-standards nil
"The standards to use in luacheck.
@@ -47,7 +46,7 @@ non-nil, pass the standards via one or more `--std' options."
:group 'flymake-rest)
;;;###autoload (autoload 'flymake-rest-luacheck "flymake-rest-luacheck")
-(flymake-rest-define flymake-rest-luacheck
+(flymake-rest-define-rx flymake-rest-luacheck
"A Lua syntax checker using luacheck.
See URL `https://github.com/mpeterv/luacheck'."
@@ -68,11 +67,10 @@ See URL `https://github.com/mpeterv/luacheck'."
,@(when-let ((file (buffer-file-name flymake-rest-source)))
(list "--filename" file))
"-")
- :error-parser
- (flymake-rest-parse-rx
- ;; NOTE: `luacheck' before 0.11.0 did not output codes for errors, hence
the ID is optional in the error pattern.
- ((warning bol (optional (file-name)) ":" line ":" column ":" " ("
(id "W" (one-or-more digit)) ") " (message) eol)
- (error bol (optional (file-name)) ":" line ":" column ":" (optional " ("
(id "E" (one-or-more digit)) ") ") (message) eol))))
+ :regexps
+ ;; NOTE: `luacheck' before 0.11.0 did not output codes for errors, hence the
ID is optional in the error pattern.
+ ((warning bol (optional (file-name)) ":" line ":" column ":" " ("
(id "W" (one-or-more digit)) ") " (message) eol)
+ (error bol (optional (file-name)) ":" line ":" column ":" (optional " ("
(id "E" (one-or-more digit)) ") ") (message) eol)))
(provide 'flymake-rest-luacheck)
diff --git a/checkers/flymake-rest-markdownlint.el
b/checkers/flymake-rest-markdownlint.el
index 16ca58f893..f8d14d3280 100644
--- a/checkers/flymake-rest-markdownlint.el
+++ b/checkers/flymake-rest-markdownlint.el
@@ -26,8 +26,7 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
(defcustom flymake-rest-markdownlint-style nil
"Path to the style config for markdownlint."
@@ -35,7 +34,7 @@
:group 'flymake-rest)
;;;###autoload (autoload 'flymake-rest-markdownlint
"flymake-rest-markdownlint")
-(flymake-rest-define flymake-rest-markdownlint
+(flymake-rest-define-rx flymake-rest-markdownlint
"Markdown checker using mdl.
See URL `https://github.com/markdownlint/markdownlint'."
@@ -47,9 +46,8 @@ See URL `https://github.com/markdownlint/markdownlint'."
:command `(,mdl-exec
,@(and flymake-rest-markdownlint-style
`("--style" ,flymake-rest-markdownlint-style)))
- :error-parser
- (flymake-rest-parse-rx
- ((error bol "(stdin):" line ": " (id "MD" (+ digit)) " " (message) eol))))
+ :regexps
+ ((error bol "(stdin):" line ": " (id "MD" (+ digit)) " " (message) eol)))
(provide 'flymake-rest-markdownlint)
diff --git a/checkers/flymake-rest-mypy.el b/checkers/flymake-rest-mypy.el
index 212be607f1..0f3b451e54 100644
--- a/checkers/flymake-rest-mypy.el
+++ b/checkers/flymake-rest-mypy.el
@@ -26,11 +26,10 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
;;;###autoload (autoload 'flymake-rest-mypy "flymake-rest-mypy")
-(flymake-rest-define flymake-rest-mypy
+(flymake-rest-define-rx flymake-rest-mypy
"Mypy syntax and type checker. Requires mypy>=0.580.
See URL `http://mypy-lang.org/'."
@@ -47,11 +46,10 @@ See URL `http://mypy-lang.org/'."
"--show-absolute-path"
"--show-error-codes"
flymake-rest-temp-file)
- :error-parser
- (flymake-rest-parse-rx
- ((error bol (file-name) ":" line ":" column ": error: " (message) eol)
- (warning bol (file-name) ":" line ":" column ": warning: " (message) eol)
- (note bol (file-name) ":" line ":" column ": note: " (message)
eol))))
+ :regexps
+ ((error bol (file-name) ":" line ":" column ": error: " (message) eol)
+ (warning bol (file-name) ":" line ":" column ": warning: " (message) eol)
+ (note bol (file-name) ":" line ":" column ": note: " (message) eol)))
(provide 'flymake-rest-mypy)
diff --git a/checkers/flymake-rest-proselint.el
b/checkers/flymake-rest-proselint.el
index dacfc7f886..6443315ff6 100644
--- a/checkers/flymake-rest-proselint.el
+++ b/checkers/flymake-rest-proselint.el
@@ -26,11 +26,10 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-enumerate))
+ (require 'flymake-rest-define))
;;;###autoload (autoload 'flymake-rest-proselint "flymake-rest-proselint")
-(flymake-rest-define flymake-rest-proselint
+(flymake-rest-define-enumerate flymake-rest-proselint
"Flymake checker using Proselint.
See URL `http://proselint.com/'."
@@ -40,25 +39,23 @@ See URL `http://proselint.com/'."
(error "Cannot find proselint executable"))
:write-type 'pipe
:command `(,proselint-exec "--json" "-")
- :error-parser
- (flymake-rest-parse-enumerate
- (alist-get 'errors
- (alist-get 'data
- (car
- (flymake-rest-parse-json
- (buffer-substring-no-properties
- (point-min) (point-max))))))
- (let-alist it
- ;; (cons (car (flymake-diag-region flymake-rest-source .line .column))
- ;; (cdr (flymake-diag-region flymake-rest-source .endLine
.endColumn)))
- (list flymake-rest-source
- .start
- .end
- (pcase .severity
- ("suggestion" :note)
- ("warning" :warning)
- ((or "error" _) :error))
- (concat (propertize .check 'face 'flymake-rest-diag-id) " "
.message)))))
+ :generator
+ (alist-get 'errors
+ (alist-get 'data
+ (car
+ (flymake-rest-parse-json
+ (buffer-substring-no-properties
+ (point-min) (point-max))))))
+ :enumerate-parser
+ (let-alist it
+ (list flymake-rest-source
+ .start
+ .end
+ (pcase .severity
+ ("suggestion" :note)
+ ("warning" :warning)
+ ((or "error" _) :error))
+ (concat (propertize .check 'face 'flymake-rest-diag-id) " "
.message))))
(provide 'flymake-rest-proselint)
diff --git a/checkers/flymake-rest-pycodestyle.el
b/checkers/flymake-rest-pycodestyle.el
index 34854ae80c..5531efc900 100644
--- a/checkers/flymake-rest-pycodestyle.el
+++ b/checkers/flymake-rest-pycodestyle.el
@@ -26,11 +26,13 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
;;;###autoload (autoload 'flymake-rest-pycodestyle "flymake-rest-pycodestyle")
-(flymake-rest-define flymake-rest-pycodestyle
+(flymake-rest-define-rx flymake-rest-pycodestyle
+ "Python style guide checker.
+
+See URL `https://github.com/PyCQA/pycodestyle'."
:title "pycodestyle"
:pre-let ((pycodestyle-exec (executable-find "pycodestyle")))
:pre-check
@@ -39,9 +41,8 @@
:write-type 'file
:source-inplace t
:command (list pycodestyle-exec flymake-rest-temp-file)
- :error-parser
- (flymake-rest-parse-rx
- ((error bol (file-name) ":" line ":" column ": " (id (or "E" "W")
(one-or-more digit)) " " (message) eol))))
+ :regexps
+ ((error bol (file-name) ":" line ":" column ": " (id (or "E" "W")
(one-or-more digit)) " " (message) eol)))
(provide 'flymake-rest-pycodestyle)
diff --git a/checkers/flymake-rest-pylint.el b/checkers/flymake-rest-pylint.el
index 05315cbccd..d967591b30 100644
--- a/checkers/flymake-rest-pylint.el
+++ b/checkers/flymake-rest-pylint.el
@@ -26,11 +26,15 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-enumerate))
+ (require 'flymake-rest-define))
;;;###autoload (autoload 'flymake-rest-pylint "flymake-rest-pylint")
-(flymake-rest-define flymake-rest-pylint
+(flymake-rest-define-enumerate flymake-rest-pylint
+ "A Python syntax and style checker using Pylint.
+
+This syntax checker requires Pylint 1.0 or newer.
+
+See URL `https://www.pylint.org/'."
:title "pylint"
:pre-let ((python-exec (executable-find "python3"))
(pylint-exec (executable-find "pylint"))
@@ -49,23 +53,23 @@
"--output-format=json"
"--from-stdin"
file-name)
- :error-parser
- (flymake-rest-parse-enumerate
- (car
- (flymake-rest-parse-json
- (buffer-substring-no-properties
- (point-min) (point-max))))
- (let-alist it
- (let ((loc (flymake-diag-region flymake-rest-source .line .column)))
- (list flymake-rest-source
- (car loc)
- (cdr loc)
- (pcase .type
- ;; See "pylint/utils.py"
- ((or "fatal" "error") :error)
- ((or "warning" "refactor" "convention") :warning)
- ((or "info" _) :note))
- (concat (propertize .message-id 'face 'flymake-rest-diag-id) " "
.message))))))
+ :generator
+ (car
+ (flymake-rest-parse-json
+ (buffer-substring-no-properties
+ (point-min) (point-max))))
+ :enumerate-parser
+ (let-alist it
+ (let ((loc (flymake-diag-region flymake-rest-source .line .column)))
+ (list flymake-rest-source
+ (car loc)
+ (cdr loc)
+ (pcase .type
+ ;; See "pylint/utils.py"
+ ((or "fatal" "error") :error)
+ ((or "warning" "refactor" "convention") :warning)
+ ((or "info" _) :note))
+ (concat (propertize .message-id 'face 'flymake-rest-diag-id) " "
.message)))))
(provide 'flymake-rest-pylint)
diff --git a/checkers/flymake-rest-rubocop.el b/checkers/flymake-rest-rubocop.el
index 0cf09a3c82..be91eafd50 100644
--- a/checkers/flymake-rest-rubocop.el
+++ b/checkers/flymake-rest-rubocop.el
@@ -26,8 +26,7 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
(defcustom flymake-rest-rubocop-use-bundler t
"When true use bundle exec for rubocop checks."
@@ -35,7 +34,7 @@
:group 'flymake-rest)
;;;###autoload (autoload 'flymake-rest-rubocop "flymake-rest-rubocop")
-(flymake-rest-define flymake-rest-rubocop
+(flymake-rest-define-rx flymake-rest-rubocop
"A Ruby syntax checker using rubocop.
See URL `https://github.com/rubocop/rubocop'."
@@ -68,11 +67,10 @@ See URL `https://github.com/rubocop/rubocop'."
;; Rubocop takes the original file name as argument when reading
;; from standard input
"--stdin" ,file-name)
- :error-parser
- (flymake-rest-parse-rx
- ((error bol (file-name) ":" line ":" column ": " (or "E" "F") ": " (?
"[Correctable] ") (message) eol)
- (warning bol (file-name) ":" line ":" column ": " "C" ": " (?
"[Correctable] ") (message) eol)
- (note bol (file-name) ":" line ":" column ": " "W" ": " (?
"[Correctable] ") (message) eol))))
+ :regexps
+ ((error bol (file-name) ":" line ":" column ": " (or "E" "F") ": " (?
"[Correctable] ") (message) eol)
+ (warning bol (file-name) ":" line ":" column ": " "C" ": " (?
"[Correctable] ") (message) eol)
+ (note bol (file-name) ":" line ":" column ": " "W" ": " (?
"[Correctable] ") (message) eol)))
(provide 'flymake-rest-rubocop)
diff --git a/checkers/flymake-rest-shellcheck.el
b/checkers/flymake-rest-shellcheck.el
index 9cf9cbc51d..f71ad410a1 100644
--- a/checkers/flymake-rest-shellcheck.el
+++ b/checkers/flymake-rest-shellcheck.el
@@ -26,18 +26,17 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-enumerate))
+ (require 'flymake-rest-define))
(defcustom flymake-rest-shellcheck-follow-sources t
- "Whether to follow"
+ "Whether to follow sources in `flymake-rest-shellcheck'."
:type '(choice (const :tag "Follow source files" t)
(const :tag "Follow source files and lint them" lint)
(const :tag "Do not follow source files" nil))
:group 'flymake-rest)
;;;###autoload (autoload 'flymake-rest-shellcheck "flymake-rest-shellcheck")
-(flymake-rest-define flymake-rest-shellcheck
+(flymake-rest-define-enumerate flymake-rest-shellcheck
"A shell script syntax and style checker using Shellcheck.
See URL `https://github.com/koalaman/shellcheck/'."
@@ -55,23 +54,23 @@ See URL `https://github.com/koalaman/shellcheck/'."
,@(when (eq flymake-rest-shellcheck-follow-sources 'lint)
'("--check-sourced"))))
"-")
- :error-parser
- (flymake-rest-parse-enumerate
- (car
- (flymake-rest-parse-json
- (buffer-substring-no-properties
- (point-min) (point-max))))
- (let-alist it
- (let ((loc (cons (car (flymake-diag-region flymake-rest-source .line
.column))
- (cdr (flymake-diag-region flymake-rest-source .endLine
.endColumn)))))
- (list flymake-rest-source
- (car loc)
- (cdr loc)
- (pcase .level
- ("error" :error)
- ("warning" :warning)
- ((or "info" "style" _) :note))
- (concat (propertize (format "SC%s" .code) 'face
'flymake-rest-diag-id) " " .message))))))
+ :generator
+ (car
+ (flymake-rest-parse-json
+ (buffer-substring-no-properties
+ (point-min) (point-max))))
+ :enumerate-parser
+ (let-alist it
+ (let ((loc (cons (car (flymake-diag-region flymake-rest-source .line
.column))
+ (cdr (flymake-diag-region flymake-rest-source .endLine
.endColumn)))))
+ (list flymake-rest-source
+ (car loc)
+ (cdr loc)
+ (pcase .level
+ ("error" :error)
+ ("warning" :warning)
+ ((or "info" "style" _) :note))
+ (concat (propertize (format "SC%s" .code) 'face
'flymake-rest-diag-id) " " .message)))))
(provide 'flymake-rest-shellcheck)
diff --git a/checkers/flymake-rest-sql-lint.el
b/checkers/flymake-rest-sql-lint.el
index 17b12dc142..fa47fc85c7 100644
--- a/checkers/flymake-rest-sql-lint.el
+++ b/checkers/flymake-rest-sql-lint.el
@@ -26,8 +26,7 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
(defcustom flymake-rest-sql-lint-driver nil
"The SQL driver to pass to sql-lint."
@@ -38,7 +37,7 @@
:group 'flymake-rest)
;;;###autoload (autoload 'flymake-rest-sql-lint "flymake-rest-sql-lint")
-(flymake-rest-define flymake-rest-sql-lint
+(flymake-rest-define-rx flymake-rest-sql-lint
"A SQL syntax checker using the sql-lint tool.
See URL `https://github.com/joereynolds/sql-lint'."
@@ -50,9 +49,8 @@ See URL `https://github.com/joereynolds/sql-lint'."
:command `(,lint-exec
,@(when flymake-rest-sql-lint-driver
`("--driver" ,flymake-rest-sql-lint-driver)))
- :error-parser
- (flymake-rest-parse-rx
- ((warning bol "stdin:" line " [sql-lint: " (id (one-or-more (any alnum
"-"))) "] " (message) eol))))
+ :regexps
+ ((warning bol "stdin:" line " [sql-lint: " (id (one-or-more (any alnum
"-"))) "] " (message) eol)))
(provide 'flymake-rest-sql-lint)
diff --git a/checkers/flymake-rest-sqlint.el b/checkers/flymake-rest-sqlint.el
index ffd933d903..8be965d594 100644
--- a/checkers/flymake-rest-sqlint.el
+++ b/checkers/flymake-rest-sqlint.el
@@ -26,11 +26,10 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
;;;###autoload (autoload 'flymake-rest-sqlint "flymake-rest-sqlint")
-(flymake-rest-define flymake-rest-sqlint
+(flymake-rest-define-rx flymake-rest-sqlint
"A SQL syntax checker using the sqlint tool.
See URL `https://github.com/purcell/sqlint'."
@@ -40,20 +39,19 @@ See URL `https://github.com/purcell/sqlint'."
(error "Cannot find sqlint executable"))
:write-type 'pipe
:command (list lint-exec)
- :error-parser
- (flymake-rest-parse-rx
- ((warning bol "stdin:" line ":" column ":WARNING "
- (message (one-or-more not-newline)
- (zero-or-more "\n"
- (one-or-more " ")
- (one-or-more not-newline)))
- eol)
- (error bol "stdin:" line ":" column ":ERROR "
- (message (one-or-more not-newline)
- (zero-or-more "\n"
- (one-or-more " ")
- (one-or-more not-newline)))
- eol))))
+ :regexps
+ ((warning bol "stdin:" line ":" column ":WARNING "
+ (message (one-or-more not-newline)
+ (zero-or-more "\n"
+ (one-or-more " ")
+ (one-or-more not-newline)))
+ eol)
+ (error bol "stdin:" line ":" column ":ERROR "
+ (message (one-or-more not-newline)
+ (zero-or-more "\n"
+ (one-or-more " ")
+ (one-or-more not-newline)))
+ eol)))
(provide 'flymake-rest-sqlint)
diff --git a/checkers/flymake-rest-xmllint.el b/checkers/flymake-rest-xmllint.el
index 5d54fb8503..6d7ca9e7c7 100644
--- a/checkers/flymake-rest-xmllint.el
+++ b/checkers/flymake-rest-xmllint.el
@@ -26,15 +26,13 @@
(require 'flymake-rest)
(eval-when-compile
- (require 'flymake-rest-define)
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
;;;###autoload (autoload 'flymake-rest-xmllint "flymake-rest-xmllint")
-(flymake-rest-define flymake-rest-xmllint
+(flymake-rest-define-rx flymake-rest-xmllint
"A XML syntax checker and validator using the xmllint utility.
-The xmllint is part of libxml2, see URL
-`http://www.xmlsoft.org/'."
+The xmllint is part of libxml2, see URL `http://www.xmlsoft.org/'."
:title "xmllint"
:pre-let ((xmllint-exec (executable-find "xmllint")))
:pre-check
@@ -42,11 +40,9 @@ The xmllint is part of libxml2, see URL
(error "Cannot find xmllint executable"))
:write-type 'pipe
:command `(,xmllint-exec "--noout" "-")
- :error-parser
- (flymake-rest-parse-rx
- ((error bol "-:" line ": " (message) eol))))
+ :regexps
+ ((error bol "-:" line ": " (message) eol)))
(provide 'flymake-rest-xmllint)
-;;; flymake-rest-xml.el ends here
;;; flymake-rest-xmllint.el ends here
diff --git a/checkers/flymake-rest-yamllint.el
b/checkers/flymake-rest-yamllint.el
index 4e091f026c..01e545472c 100644
--- a/checkers/flymake-rest-yamllint.el
+++ b/checkers/flymake-rest-yamllint.el
@@ -23,14 +23,14 @@
;;; Code:
(require 'flymake)
-(require 'flymake-rest-define)
(eval-when-compile
- (require 'flymake-rest-parse-rx))
+ (require 'flymake-rest-define))
;;;###autoload (autoload 'flymake-rest-yamllint "flymake-rest-yamllint")
-(flymake-rest-define flymake-rest-yamllint
+(flymake-rest-define-rx flymake-rest-yamllint
"A YAML syntax checker using YAMLLint.
+
See URL `https://github.com/adrienverge/yamllint'."
:title "yamllint"
:pre-let ((yamllint-exec (executable-find "yamllint")))
@@ -38,10 +38,9 @@ See URL `https://github.com/adrienverge/yamllint'."
(error "Cannot find yamllint executable"))
:write-type 'pipe
:command (list yamllint-exec "-f" "parsable" "-")
- :error-parser
- (flymake-rest-parse-rx
- ((error bol "stdin:" line ":" column ": " "[error] " (message) eol)
- (warning bol "stdin:" line ":" column ": " "[warning] " (message) eol))))
+ :regexps
+ ((error bol "stdin:" line ":" column ": " "[error] " (message) eol)
+ (warning bol "stdin:" line ":" column ": " "[warning] " (message) eol)))
(provide 'flymake-rest-yamllint)
diff --git a/flymake-rest-define.el b/flymake-rest-define.el
index e3bd813aae..35749edc04 100644
--- a/flymake-rest-define.el
+++ b/flymake-rest-define.el
@@ -22,14 +22,29 @@
;;; Commentary:
-;; This file provides a macro, adapted heavily from
[[https://github.com/karlotness/flymake-quickdef/blob/150c5839768a3d32f988f9dc08052978a68f2ad7/flymake-quickdef.el][flymake-quickdef]],
to allow
-;; streamlined syntax-checker definitions. The intended purpose is to abstract
-;; the process creation, management and cleanup for a checker as much as
possible,
-;; leaving the developer to only have to specify what command to run and how
-;; to parse its output.
+;; This file provides a macro `flymake-rest-define', adapted heavily from
+;;
[[https://github.com/karlotness/flymake-quickdef/blob/150c5839768a3d32f988f9dc08052978a68f2ad7/flymake-quickdef.el][flymake-quickdef]],
to allow streamlined syntax-checker definitions. The
+;; intended purpose is to abstract the process creation, management and cleanup
+;; for a checker as much as possible, leaving the developer to only have to
+;; specify what command to run and how to parse its output.
+
+;; Also in this file you'll find helper macros to parse diagnostics using
+;; regexps and simplify JSON processing.
+;;
+;; `flymake-rest-define-rx' works by defining some regular expressions (one for
+;; each severity level of the checker) and then matching each line of the
output
+;; to a regular expression. Special capture groups have been setup by the
parser
+;; that should be used by any calling checkers to ensure the correct fields
from
+;; the output can be parsed. The approach for this was heavily inspired by
+;; flychecks :error-parsers feature.
+;;
+;; `flymake-rest-define' can be used to parse JSON output from the checker into
+;; flymake diagnostics. This works by parsing the entire JSON input into a list
+;; of diagnostic related data, and then iteratively parsing it into
diagnostics.
;;; Code:
+(require 'cl-lib)
(require 'flymake)
;;;###autoload
@@ -40,205 +55,445 @@ finished its removed and killed. In the very often
circumstance where a
new check is begun while an old check is still pending, the old check is
killed and replaced with the new check.")
-(defmacro flymake-rest-define (name &optional docstring &rest defs)
- "Quickly define a backend for use with Flymake.
-This macro creates a new function NAME which is suitable for use with the
-variable `flymake-diagnostic-functions'. DOCSTRING if given will become the
-docstring of the checker function.
+
+;;; `flymake-rest-define'
+
+(defun flymake-rest-define--temp-file (temp-dir temp-file source-inplace)
+ "Let forms for defining a temporary directory and file.
+TEMP-DIR and TEMP-FILE are the symbols used for the corresponding variables.
+SOURCE-INPLACE specifies whether the TEMP-DIR should be in the same working
+directory as the current buffer."
+ `((,temp-dir
+ ,@(let ((forms
+ (append
+ (when source-inplace
+ '((when-let ((dir (or (when-let ((file (buffer-file-name)))
+ (file-name-directory file))
+ default-directory)))
+ (unless (file-exists-p dir)
+ (error "Checker needs to be run in the cwd, but the cwd
\
+doesn't exist: %s" dir))
+ dir)))
+ '((make-temp-file "flymake-" t)))))
+ (if (> (length forms) 1)
+ `((or ,@forms))
+ forms)))
+ (,temp-file
+ (let ((temporary-file-directory ,temp-dir)
+ (basename (file-name-nondirectory (or (buffer-file-name)
+ (buffer-name)))))
+ (make-temp-file ".flymake_" nil (concat "_" basename))))))
-DEFS is a plist of values used to setup the backend. The only required fields
-in DEFS is :command and :error-parser.
+(defmacro flymake-rest-define--parse-diags
+ (title proc-symb diags-symb current-diag-symb source-symb error-parser)
+ "Helper macro to parse diagnostics into DIAGS-SYMB.
+TITLE is the title of the current syntax checker. PROC-SYMB, DIAGS-SYMB,
+CURRENT-DIAGS-SYMB, SOURCE-SYMB, ERROR-PARSER are all described in
+`flymake-rest-define'."
+ `(with-current-buffer ,source-symb
+ (save-restriction
+ (widen)
+ (with-current-buffer (process-buffer ,proc-symb)
+ (goto-char (point-min))
+ (save-match-data
+ (while (setq ,current-diag-symb (progn ,error-parser))
+ (let* ((diag-beg (nth 1 ,current-diag-symb))
+ (diag-end (nth 2 ,current-diag-symb))
+ (diag-type (nth 3 ,current-diag-symb)))
+ (if (and (integer-or-marker-p diag-beg)
+ (integer-or-marker-p diag-end))
+ ;; Skip any diagnostics with a type of nil. This makes it
+ ;; easier to filter some out.
+ (when diag-type
+ ;; Include the checker title in the message.
+ ,@(when title
+ `((setf (nth 4 ,current-diag-symb)
+ (concat
+ (nth 4 ,current-diag-symb)
+ ,(concat
+ " ("
+ (propertize title 'face
'flymake-rest-checker)
+ ")")))))
+ (push (apply #'flymake-make-diagnostic
+ ,current-diag-symb)
+ ,diags-symb))
+ (with-current-buffer ,source-symb
+ (flymake-log
+ :error
+ "Got invalid buffer position %s or %s in %s"
+ diag-beg diag-end ,proc-symb))))))))
+ (setq ,diags-symb (nreverse ,diags-symb))))
+
+;; WARN: I can't seem to make docstring optional and use keys, because
+;; the key for the first keyword argument will become the docstring if
+;; there's no docstring.
+(cl-defmacro flymake-rest-define
+ (name docstring
+ &optional &key title command error-parser write-type
+ source-inplace pre-let pre-check)
+ "Quickly define a backend function for use with Flymake.
+Define a function NAME which is suitable for use with the variable
+`flymake-diagnostic-functions'. DOCSTRING if given will become the
+docstring of the checker function.
Available Variables
+-------------------
+Within the body of NAME several macro specific variables will be
+made available for use with ERROR-PARSER or COMMAND, and other
+optional arguments such as PRE-LET. This includes:
+* flymake-rest-source
+ The the buffer where the syntax check originally began.
+* flymake-rest-temp-file
+ A temporary file where the contents of the current buffer were
+ written (only if WRITE-TYPE is 'file)
+* flymake-rest-temp-dir
+ The dirname of flymake-rest-temp-file.
+
+Body Execution
+--------------
+The overall execution of the generated function NAME first makes use
+of (1) WRITE-TYPE, (2) SOURCE-INPLACE, (3) PRE-LET, and (4) PRE-CHECK.
+Then a process is created using (4) COMMAND. Once the process finishes
+ERROR-PARSER is called (until it returns nil) to get the next
+diagnostic which is then provided to `flymake'. TITLE if provided is
+used to suffix the message for each diagnostic.
+
+WRITE-TYPE specifies how the process for a syntax check should recieve
+the input. It should one of 'pipe or 'file (defaulting to 'pipe).
+When set to 'file a temporary file will ve created, copying the contents
+of the `current-buffer'. The variable flymake-rest-temp-file and
+flymake-rest-temp-dir will be bound in the body of NAME and provide
+access to this temp-file.
+When set to 'pipe, all of the `current-buffer' will be passed to the
+process on its standard-input stream after it has begun.
+
+SOURCE-INPLACE determines whether to also create a temporary directory
+for a temporary file (when using a WRITE-TYPE of 'file) or whether to
+place the temporary file in the same directory as the file being checked.
+This can be useful if the syntax checker also resolves imports or packages
+and thus needs to be in the same directory. This is disabled by default
+meaning the file is placed in folder in the systems temporary directory.
+
+PRE-LET is a `let*' form that is assigned after any checker agnostic
+variables. Place anything you want exposed to everything else in the
+checker here.
-flymake-rest-source, flymake-rest-temp-file, fmdq-temp-dir,
flymake-rest-context.
-Within the body of :error-parser and :command, several macro specific variables
-are made available. This includes (1) `flymake-rest-source',
-(2) `flymake-rest-temp-file', (3) `flymake-rest-temp-dir', (4)
`flymake-rest-context'.
-
-Body Definitions
-
-The overall execution of the produced function first makes use of (1)
-:write-type, (2) :source-inplace, (3) :pre-let, and (3) :pre-check. Next
-a process is created using (4) :command. Once the process is finished
-:error-parser is called (until it returns nil) to get the next diagnostic
-which is then provided to flymake. (5) :title if provided is used to
-suffix the messages for each diagnostic.
-
-:write-type specifies how the process for flymake should recieve the input.
-It should be one of 'pipe or 'file (defaulting to 'pipe). When set to file
-a temporary file will be created copying the contents of the `current-buffer'.
-The variable flymake-rest-temp-file and flymake-rest-temp-dir will be bound in
the body
-of the rest of the keywords that provide access to the temp-file. When set
-to pipe after the process has been started all of the current buffers input
-will be passed to the process through standard-input.
-
-:source-inplace is a boolean that sets flymake-rest-temp-dir to the current
working
-directory. By default this is nil and the temp-file used for :write-type 'file
-will be set to a folder in the systems temporary directory.
-
-:pre-let is a `let*' form that is assigned after any backend-agnostic let
-forms have been setup.
-
-:pre-check is a Lisp form that will be executed immeadiately before any pending
-checker processes are killed and a new process is begun. It can check
conditions
-to ensure launching the checker program is possible. If something is wrong it
-should signal an error.
-
-:command is a lip form which evaluates to a list of strings that will be used
to
-start the checker process. It should be suitable for use as the :command
argument
-to the `make-process' function.
-
-:error-parser is a lisp-form that should, each time it is evaluated, return the
-next diagnostic from the checker output. The result should be a value that can
-be passed to the `flymake-make-diagnostic' function. Once there're no more
-diagnostics to parse this form should evaluate to nil."
+PRE-CHECK is a Lisp form that will be executed immeadiately before any
+pending checker processes are killed and a new process is begun. It can
+check conditions to ensure launching the checker program is possible. If
+something is wrong it should signal an error.
+
+COMMAND is a Lisp form which evaluates to a list of strings that will be
+used to start the checker process. It should be suitable for use as the
+:command argument to the `make-process' function.
+
+ERROR-PARSER is a lisp-form that should, each time it is evaluated,
+return the next diagnostic from the checker output. The result should be
+a value that can be passed to the `flymake-make-diagnostic' function. Once
+there're no more diagnostics to parse this form should evaluate to nil."
(declare (indent defun) (doc-string 2))
(unless lexical-binding
(error "Need lexical-binding for flymake-rest-define (%s)" name))
- (or (stringp docstring)
- (setq defs (cons docstring defs)
- docstring nil))
- (dolist (elem '(:command :error-parser))
- (unless (plist-get defs elem)
- (error "Missing flymake backend definition `%s'" elem)))
- (let* ((write-type (or (eval (plist-get defs :write-type)) 'pipe))
- (source-inplace (plist-get defs :source-inplace))
- (temp-dir-symb (intern "flymake-rest-temp-dir"))
- (temp-file-symb (intern "flymake-rest-temp-file"))
- (err-symb (intern "flymake-rest-err"))
- (diags-symb (intern "diags"))
- (proc-symb (intern "proc"))
- (source-symb (intern "flymake-rest-source"))
- (current-diags-symb (intern "diag"))
+ (dolist (elem (list (cons 'command command)
+ (cons 'error-parser error-parser)))
+ (unless (cdr elem)
+ (error "Missing flymake backend definition `%s'" (car elem))))
+
+ (setq write-type (or (eval write-type) 'pipe))
+ (setq source-inplace (eval source-inplace))
+
+ (unless (memq write-type '(file pipe))
+ (error "Invalid `:write-type' value `%s'" write-type))
+
+ (let* ((temp-dir-symb 'flymake-rest-temp-dir)
+ (temp-file-symb 'flymake-rest-temp-file)
+ (proc-symb 'proc)
+ (err-symb 'flymake-rest-err)
+ (source-symb 'flymake-rest-source)
+ (diags-symb 'diags)
+ (current-diag-symb 'diag)
(cleanup-form (when (eq write-type 'file)
(if source-inplace
`((delete-file ,temp-file-symb))
`((delete-directory ,temp-dir-symb t)))))
- (not-obsolete-form `((eq ,proc-symb (plist-get (buffer-local-value
'flymake-rest-define--procs ,source-symb) ',name)))))
- ;; Sanitise parsed inputs from `defs'.
- (unless (memq write-type '(file pipe nil))
- (error "Invalid `:write-type' value `%s'" write-type))
-
+ (not-obsolete-form
+ `((eq ,proc-symb
+ (plist-get (buffer-local-value 'flymake-rest-define--procs
+ ,source-symb)
+ ',name)))))
`(defun ,name (report-fn &rest _args)
,docstring
(let* ((,source-symb (current-buffer))
- (flymake-rest-context nil)
,@(when (eq write-type 'file)
- `((,temp-dir-symb
- ,@(let ((forms (append (when source-inplace
- `((when-let ((dir (or (when-let
((file (buffer-file-name)))
-
(file-name-directory file))
-
default-directory)))
- (unless (file-exists-p dir)
- (error "Checker needs to
be run in the cwd, but the cwd doesn't exist: %s" dir))
- dir)))
- '((make-temp-file "flymake-" t)))))
- (if (> (length forms) 1)
- `((or ,@forms))
- forms)))
- (,temp-file-symb
- (let ((temporary-file-directory ,temp-dir-symb)
- (basename (file-name-nondirectory (or
(buffer-file-name)
-
(buffer-name)))))
- (make-temp-file ".flymake_"
- nil
- (concat "_" basename))))))
- ,@(plist-get defs :pre-let))
- ;; With vars defined, do :pre-check.
- ,@(when-let ((pre-check (plist-get defs :pre-check)))
+ (flymake-rest-define--temp-file
+ temp-dir-symb temp-file-symb source-inplace))
+ ,@pre-let)
+ ;; With vars defined, do pre-check.
+ ,@(when pre-check
`((condition-case ,err-symb
- (progn ,pre-check)
+ ,pre-check
(error ,@cleanup-form
(signal (car ,err-symb) (cdr ,err-symb))))))
- ;; Kill any running (obsolete) processes for current checker and
buffer.
+ ;; Kill any running (obsolete) checkers for current checker and
buffer.
(let ((,proc-symb (plist-get flymake-rest-define--procs ',name)))
(when (process-live-p ,proc-symb)
- (kill-process ,proc-symb)
- (flymake-log :debug "Killing earlier checker process %s"
,proc-symb)))
-
+ (flymake-log :debug "Killing earlier checker process %s"
,proc-symb)
+ (kill-process ,proc-symb)))
;; Kick-start checker process.
(save-restriction
(widen)
- ;; Write the current file out before starting checker.
,@(when (eq write-type 'file)
`((write-region nil nil ,temp-file-symb nil 'silent)))
- (let (proc)
- (setq proc
- (make-process
- :name ,(concat (symbol-name name) "-flymake")
- :noquery t
- :connection-type 'pipe
- :buffer (generate-new-buffer ,(concat " *" (symbol-name
name) "-flymake*"))
- :command
- (let ((cmd ,(plist-get defs :command)))
- (prog1 cmd
- (flymake-log :debug "Checker command is %s" cmd)))
- :sentinel
- (lambda (,proc-symb _event)
- (unless (process-live-p ,proc-symb)
- (unwind-protect
- (if ,@not-obsolete-form
- (with-current-buffer ,source-symb
- ;; First read diagnostics from process
buffer referencing the source buffer.
- (let ((,diags-symb nil) ,current-diags-symb)
- ;; Widen the source buffer to ensure
`flymake-diag-region' is correct.
- (save-restriction
- (widen)
- (with-current-buffer (process-buffer
,proc-symb)
- (goto-char (point-min))
- (save-match-data
- (while (setq ,current-diags-symb
,(plist-get defs :error-parser))
- (let* ((diag-beg (nth 1
,current-diags-symb))
- (diag-end (nth 2
,current-diags-symb))
- (diag-type (nth 3
,current-diags-symb)))
- (if (and (integer-or-marker-p
diag-beg)
- (integer-or-marker-p
diag-end))
- ;; Skip any diagnostics with
a type of nil
- ;; This makes it easier to
filter some out.
- (when diag-type
- ;; Include the checker
name/title in the message.
- ,@(when (plist-get defs
:title)
- `((setf (nth 4
,current-diags-symb)
- (concat (nth 4
,current-diags-symb)
-
,(concat
- " ("
-
(propertize (plist-get defs :title)
-
'face 'flymake-rest-checker)
-
")")))))
-
- (push (apply
#'flymake-make-diagnostic ,current-diags-symb)
- ,diags-symb))
- (with-current-buffer
,source-symb
- (flymake-log :error "Got
invalid buffer position %s or %s in %s"
- diag-beg
diag-end ,proc-symb))))))))
- ;; Pass reports back to the
callback-function when still not-obsolete.
- (if ,@not-obsolete-form
- (progn
- (let ((status (process-exit-status
,proc-symb)))
- (when (and (eq (length
,diags-symb) 0)
- (not (eq status 0)))
- (flymake-log :warning
- "Checker gave no
diagnostics but had a non-zero exit status %d\nStderr:" status
-
(with-current-buffer (process-buffer ,proc-symb)
- (format "%s"
(buffer-substring-no-properties
-
(point-min) (point-max)))))))
- (funcall report-fn (nreverse
,diags-symb)))
- ;; In case the check was cancelled after
processing began but before it finished.
- (flymake-log :warning "Canceling
obsolete check %s" ,proc-symb)))
- (flymake-log :warning "Canceling obsolete
check %s" ,proc-symb)))
- ;; Finished linting, cleanup any temp-files and then
kill proc buffer.
- ,@cleanup-form
- (kill-buffer (process-buffer ,proc-symb)))))))
+ (let (,proc-symb)
+ (setq
+ ,proc-symb
+ (make-process
+ :name ,(concat (symbol-name name) "-flymake")
+ :noquery t
+ :connection-type 'pipe
+ :buffer (generate-new-buffer
+ ,(concat " *" (symbol-name name) "-flymake*"))
+ :command
+ (prog1 ,command
+ (flymake-log :debug "Checker command is %s" ,command))
+ :sentinel
+ (lambda (,proc-symb _event)
+ (unless (process-live-p ,proc-symb)
+ (unwind-protect
+ (if ,@not-obsolete-form
+ (let ((,diags-symb nil) ,current-diag-symb)
+ (flymake-rest-define--parse-diags
+ ,title
+ ,proc-symb
+ ,diags-symb
+ ,current-diag-symb
+ ,source-symb
+ ,error-parser)
+ ;; Report diagnostics when still not-obsolete.
+ (if ,@not-obsolete-form
+ (progn
+ (let ((status (process-exit-status
,proc-symb)))
+ (when (and (eq (length ,diags-symb) 0)
+ (not (eq status 0)))
+ (flymake-log
+ :warning
+ "Checker gave no diagnostics but had a
non-zero \
+exit status %d\nStderr: %s"
+ status
+ (with-current-buffer (process-buffer
,proc-symb)
+ (format "%s"
(buffer-substring-no-properties
+ (point-min)
(point-max)))))))
+ (funcall report-fn ,diags-symb))
+ ;; In case the check was cancelled after
processing began
+ ;; but before it finished.
+ (flymake-log :warning "Canceling obsolete check
%s" ,proc-symb)))
+ (flymake-log :warning "Canceling obsolete check %s"
,proc-symb))
+ ;; Finished linting, cleanup any temp-files and then kill
+ ;; the process buffer.
+ ,@cleanup-form
+ (kill-buffer (process-buffer ,proc-symb)))))))
;; Push the new-process to the process to the process alist.
(setq flymake-rest-define--procs
(plist-put flymake-rest-define--procs ',name ,proc-symb))
;; If piping, send data to the process.
,@(when (eq write-type 'pipe)
- `((process-send-region proc (point-min) (point-max))
- (process-send-eof proc)))
+ `((process-send-region ,proc-symb (point-min) (point-max))
+ (process-send-eof ,proc-symb)))
+ ;; Return value of syntax-checker is checker function.
,proc-symb))))))
+
+;;; `flymake-rest-define-rx'
+
+(eval-when-compile
+ (require 'rx))
+
+(defconst flymake-rest-parse-rx-constituents
+ `((file-name ,(lambda (body)
+ (rx-to-string
+ `(group-n 1 ,@(or (cdr body)
+ '((minimal-match
+ (one-or-more not-newline)))))
+ t))
+ 0 nil) ;; group 1
+ (line . ,(rx (group-n 2 (one-or-more digit))))
+ (column . ,(rx (group-n 3 (one-or-more digit))))
+ (message ,(lambda (body)
+ (rx-to-string
+ `(group-n 4 ,@(or (cdr body)
+ '((minimal-match
+ (one-or-more not-newline)))))
+ t))
+ 0 nil)
+ (id ,(lambda (body)
+ (rx-to-string `(group-n 5 ,@(cdr body)) t))
+ 0 nil)
+ (end-line . ,(rx (group-n 6 (one-or-more digit))))
+ (end-column . ,(rx (group-n 7 (one-or-more digit))))))
+
+(defmacro flymake-rest-define--parse-rx (regexps)
+ "`flymake-rest-define' parser using regular expressions.
+
+This macro generates a parser that for each line of output from the
+checker process, matches one or more regular expressions and then
+converts the result to a valid flymake diagnostic that can be
+passed back to `flymake-make-diagnostic'.
+
+REGEXPS should be an alist with the car of each entry being the
+severity of the diagnostic it matches (as a symbol that will be
+turned into a keyword by this macro) and the cdr should be a
+sequence of entries that can be interpreted by the `rx' macro.
+To simplify matching specific fields in the parsed output several
+helper extensions to `rx' have been defined such as file-name or
+line. For a list of these see `flymake-rest-parse-rx-constituents'.
+The only required fields that MUST be parsed are the line number
+and message. If these are ommited the matched diagnostic will be
+skipped.
+
+WARN: You should not try to capture any extra fields outside of
+the special ones described above. This is because any extra capture
+groups are used to associate the severity of the diagnostic to the
+regexp that matched it (as a performance improvement).
+
+For an example of this macro in action, see `flymake-rest-pycodestyle'."
+ (unless (> (length regexps) 0)
+ (error "Must supply at least one regexp for error, warning or note"))
+
+ (let* ((group-count (length flymake-rest-parse-rx-constituents))
+ (regexps
+ ;; To avoid having to rematch each diagnostic more than once we
append
+ ;; a special extra capture group (greater than all the ones above)
that
+ ;; simply matches the empty string. Then we can index the groups
after
+ ;; the ones above and use that to determine the severity of the
symbol.
+ (cl-loop for (severity . regex) in regexps
+ with count = group-count
+ do (setq count (1+ count))
+ collect (cons `(seq ,@regex (group-n ,count ""))
+ (intern (concat ":" (symbol-name
severity))))))
+ (combined-regex
+ (let ((rx-constituents (append flymake-rest-parse-rx-constituents
+ (bound-and-true-p rx-constituents)
nil)))
+ (rx-to-string `(or ,@(mapcar #'car regexps))
+ 'no-group)))
+ (severity-seq (mapcar #'cdr regexps)))
+ ;; Because if this evaluates to nil `flymake-rest-define' thinks there
+ ;; are no-more diagnostics to be parsed, we wrap it in a loop that exits
+ ;; the moment we find a match, but otherwise keeps moving through
diagnostics
+ ;; until there actually aren't any more to match.
+ `(let (res ; file-name
+ line column message id end-line end-column severity-ix)
+ (while (and (not res)
+ (search-forward-regexp ,combined-regex nil t))
+ (setq
+ res
+ (save-match-data
+ (save-excursion
+ (setq ; file-name (match-string 1)
+ line (match-string 2)
+ column (match-string 3)
+ message (match-string 4)
+ id (match-string 5)
+ end-line (match-string 6)
+ end-column (match-string 7)
+ severity-ix (- (seq-find #'match-string
+ (number-sequence ,(1+ group-count)
+ ,(+ group-count
(length regexps))))
+ ,(1+ group-count)))
+ (cond
+ ;; Log an error when any of the required fields are missing.
+ ,@(cl-loop for it in '(severity-ix line message)
+ collect
+ `((not ,it)
+ (flymake-log :error
+ ,(format
+ "Matched diagnostic didn't capture
a %s group"
+ (symbol-name it)))
+ nil))
+ (t
+ (let ((loc (flymake-diag-region flymake-rest-source
+ (string-to-number line)
+ (when column
+ (string-to-number column))))
+ (loc-end (when end-line
+ (flymake-diag-region flymake-rest-source
+ (string-to-number
end-line)
+ (when end-column
+ (string-to-number
end-column))))))
+ (when loc-end
+ (setcdr loc (cdr loc-end)))
+ (list flymake-rest-source
+ (car loc)
+ (cdr loc)
+ (nth severity-ix (quote ,severity-seq))
+ (concat
+ (when id
+ (concat (propertize id 'face 'flymake-rest-diag-id)
" "))
+ message)))))))))
+ res)))
+
+(cl-defmacro flymake-rest-define-rx
+ (name docstring
+ &optional &key title command write-type source-inplace pre-let
pre-check regexps)
+ "`flymake-rest-define' helper using `rx' syntax to parse diagnostics.
+This helper macro adapts `flymake-rest-define' to use an error-parser built
+from a collections of REGEXPS (see `flymake-rest-define--parse-rx').
+
+See `flymake-rest-define' for a description of NAME, DOCSTRING, TITLE, COMMAND,
+WRITE-TYPE, SOURCE-INPLACE, PRE-LET, and PRE-CHECK."
+ (declare (indent defun) (doc-string 2))
+ `(flymake-rest-define ,name
+ ,docstring
+ :title ,title
+ :command ,command
+ :write-type ,write-type
+ :source-inplace ,source-inplace
+ :pre-let ,pre-let
+ :pre-check ,pre-check
+ :error-parser
+ (flymake-rest-define--parse-rx ,regexps)))
+
+
+;;; `flymake-rest-define-enumerate'
+
+(cl-defmacro flymake-rest-define-enumerate
+ (name docstring
+ &optional &key title command write-type source-inplace
+ pre-let pre-check generator enumerate-parser)
+ "`flymake-rest-define' helper for dealing with serialised diagnostics.
+This helper parses a collection of diagnostics using GENERATOR and then
+enumerates through it, entry by entry using ENUMERATE-PARSER. This is useful
+for linters that produce output such as JSON, to avoid having to reparse the
+output again and again.
+
+The value of the current entry from GENERATOR in ENUMERATE-PARSER will be set
to
+the variable `it'. ENUMERATE-PARSER should evaluate to a form that can be
passed
+to `flymake-make-diagnostic'."
+ (declare (indent defun) (doc-string 2))
+ (let ((entries-var 'flymake-rest-entries)
+ (parsed-var 'flymake-rest-parsed))
+ `(flymake-rest-define ,name
+ ,docstring
+ :title ,title
+ :command ,command
+ :write-type ,write-type
+ :source-inplace ,source-inplace
+ :pre-let ,(append `((,entries-var)
+ (,parsed-var))
+ pre-let)
+ :pre-check ,pre-check
+ :error-parser
+ (progn
+ (unless ,parsed-var
+ (setq ,entries-var ,generator
+ ,parsed-var t))
+ (let (it res)
+ ;; While we haven't found a new diagnostic to return, BUT there're
+ ;; still diagnostics that can be found in the parsed checker output.
+ (while (and (not res)
+ (setq it (pop ,entries-var)))
+ (setq res ,enumerate-parser))
+ res)))))
+
(provide 'flymake-rest-define)
;;; flymake-rest-define.el ends here
diff --git a/flymake-rest-parse-enumerate.el b/flymake-rest-parse-enumerate.el
deleted file mode 100644
index 6f7f0657df..0000000000
--- a/flymake-rest-parse-enumerate.el
+++ /dev/null
@@ -1,56 +0,0 @@
-;;; flymakflymake-backend-parse-enumerate!to simplify checker creation -*-
lexical-binding: t -*-
-
-;; Copyright (c) 2021 Mohsin Kaleem
-
-;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;; of this software and associated documentation files (the "Software"), to
deal
-;; in the Software without restriction, including without limitation the rights
-;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;; copies of the Software, and to permit persons to whom the Software is
-;; furnished to do so, subject to the following conditions:
-
-;; The above copyright notice and this permission notice shall be included in
all
-;; copies or substantial portions of the Software.
-
-;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
-;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE
-;; SOFTWARE.
-
-;;; Commentary:
-;; This file defines an error-parser for `flymake-rest-define' which can be
used
-;; to parse JSON output from the checker into flymake diagnostics. This works
by
-;; parsing the entire JSON input into a list of diagnostic related data, and
then
-;; iteratively parsing it into diagnostics.
-
-;;; Code:
-
-;;;###autoload
-(defmacro flymake-rest-parse-enumerate (gen &rest body)
- "Error parser for `flymake-backend-define' which parses all of
-the diagnostics at once using GEN and then prepares them one-at-a-time
-with BODY.
-
-The value of the current entry from GEN in BODY will be set to the variable
-`it'. BODY should evaluate to a form that can be passed to
-`flymake-make-diagnostic'."
- (declare (indent 1))
- (let ((context-var (intern "flymake-rest-context")))
- `(progn
- (unless (alist-get 'enumerated ,context-var)
- (push (cons 'entries ,gen) ,context-var)
- (push '(enumerated t) ,context-var))
- (let (it res)
- ;; While we haven't found a new diagnostic to return, BUT there're
- ;; still diagnostics that can be found in the parsed checker output.
- (while (and (not res)
- (setq it (pop (alist-get 'entries ,context-var))))
- (setq res ,@body))
- res))))
-
-(provide 'flymake-rest-parse-enumerate)
-
-;;; flymake-rest-parse-enumerate.el ends here
diff --git a/flymake-rest-parse-rx.el b/flymake-rest-parse-rx.el
deleted file mode 100644
index f2a710ae34..0000000000
--- a/flymake-rest-parse-rx.el
+++ /dev/null
@@ -1,164 +0,0 @@
-;;; flymake-rest-rest.el --- A macro to simplify checker creation -*-
lexical-binding: t -*-
-
-;; Copyright (c) 2021 Mohsin Kaleem
-
-;; Permission is hereby granted, free of charge, to any person obtaining a copy
-;; of this software and associated documentation files (the "Software"), to
deal
-;; in the Software without restriction, including without limitation the rights
-;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-;; copies of the Software, and to permit persons to whom the Software is
-;; furnished to do so, subject to the following conditions:
-
-;; The above copyright notice and this permission notice shall be included in
all
-;; copies or substantial portions of the Software.
-
-;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
-;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE
-;; SOFTWARE.
-
-;;; Commentary:
-;; This file defines an error-parser for `flymake-rest-define' which can be
used
-;; to parse plaintext output from the checker into flymake diagnostics. This
works
-;; by defining some regular expressions (one for each severity level of the
checker)
-;; and then matching each line of the output to a regular expression. Special
-;; capture groups have been setup by the parser that should be used by any
calling
-;; checkers to ensure the correct fields from the output can be parsed.
-;;
-;; The approach implemented here was heavily inspired by flychecks
:error-parsers
-;; feature.
-
-;;; Code:
-
-(require 'rx)
-
-(defconst flymake-rest-parse-rx-constituents
- `((file-name ,(lambda (body)
- (rx-to-string
- `(group-n 1 ,@(or (cdr body)
- '((minimal-match
- (one-or-more not-newline)))))
- t))
- 0 nil) ;; group 1
- (line . ,(rx (group-n 2 (one-or-more digit))))
- (column . ,(rx (group-n 3 (one-or-more digit))))
- (message ,(lambda (body)
- (rx-to-string
- `(group-n 4 ,@(or (cdr body)
- '((minimal-match
- (one-or-more not-newline)))))
- t))
- 0 nil)
- (id ,(lambda (body)
- (rx-to-string `(group-n 5 ,@(cdr body)) t))
- 0 nil)
- (end-line . ,(rx (group-n 6 (one-or-more digit))))
- (end-column . ,(rx (group-n 7 (one-or-more digit))))))
-
-;;;###autoload
-(defmacro flymake-rest-parse-rx (regexps)
- "`flymake-rest-define' parser using regular expressions.
-
-This macro generates a parser that for each line of output from the
-checker process, matches one or more regular expressions and then
-converts the result to a valid flymake diagnostic that can be
-passed back to `flymake-make-diagnostic'.
-
-REGEXPS should be an alist with the car of each entry being the
-severity of the diagnostic it matches (as a symbol that will be
-turned into a keyword by this macro) and the cdr should be a
-sequence of entries that can be interpreted by the `rx' macro.
-To simplify matching specific fields in the parsed output several
-helper extensions to `rx' have been defined such as file-name or
-line. For a list of these see `flymake-rest-parse-rx-constituents'.
-The only required fields that MUST be parsed are the line number
-and message. If these are ommited the matched diagnostic will be
-skipped.
-
-WARN: You should not try to capture any extra fields outside of
-the special ones described above. This is because any extra capture
-groups are used to associate the severity of the diagnostic to the
-regexp that matched it (as a performance improvement).
-
-For an example of this macro in action, see `flymake-rest-pycodestyle'."
- (unless (> (length regexps) 0)
- (error "Must supply at least one regexp for error, warning or note"))
-
- (let* ((group-count (length flymake-rest-parse-rx-constituents))
- (regexps
- ;; To avoid having to rematch each diagnostic more than once we
append
- ;; a special extra capture group (greater than all the ones above)
that
- ;; simply matches the empty string. Then we can index the groups
after
- ;; the ones above and use that to determine the severity of the
symbol.
- (cl-loop for (severity . regex) in regexps
- with count = group-count
- do (setq count (1+ count))
- collect (cons `(seq ,@regex (group-n ,count ""))
- (intern (concat ":" (symbol-name
severity))))))
- (combined-regex
- (let ((rx-constituents (append flymake-rest-parse-rx-constituents
- rx-constituents nil)))
- (rx-to-string `(or ,@(mapcar #'car regexps))
- 'no-group)))
- (severity-seq (mapcar #'cdr regexps)))
- ;; Because if this evaluates to nil `flymake-rest-define' thinks there
- ;; are no-more diagnostics to be parsed, we wrap it in a loop that exits
- ;; the moment we find a match, but otherwise keeps moving through
diagnostics
- ;; until there actually aren't any more to match.
- `(let (res ; file-name
- line column message id end-line end-column severity-ix)
- (while (and (not res)
- (search-forward-regexp ,combined-regex nil t))
- (setq
- res
- (save-match-data
- (save-excursion
- (setq ; file-name (match-string 1)
- line (match-string 2)
- column (match-string 3)
- message (match-string 4)
- id (match-string 5)
- end-line (match-string 6)
- end-column (match-string 7)
- severity-ix (- (seq-find #'match-string
- (number-sequence ,(1+ group-count)
- ,(+ group-count
(length regexps))))
- ,(1+ group-count)))
- (cond
- ;; Log an error when any of the required fields are missing.
- ,@(cl-loop for it in '(severity-ix line message)
- collect
- `((not ,it)
- (flymake-log :error
- ,(format
- "Matched diagnostic didn't capture
a %s group"
- (symbol-name it)))
- nil))
- (t
- (let ((loc (flymake-diag-region flymake-rest-source
- (string-to-number line)
- (when column
- (string-to-number column))))
- (loc-end (when end-line
- (flymake-diag-region flymake-rest-source
- (string-to-number
end-line)
- (when end-column
- (string-to-number
end-column))))))
- (when loc-end
- (setcdr loc (cdr loc-end)))
- (list flymake-rest-source
- (car loc)
- (cdr loc)
- (nth severity-ix (quote ,severity-seq))
- (concat
- (when id
- (concat (propertize id 'face 'flymake-rest-diag-id)
" "))
- message)))))))))
- res)))
-
-(provide 'flymake-rest-parse-rx)
-
-;;; flymake-rest-parse-rx.el ends here
diff --git a/flymake-rest.el b/flymake-rest.el
index 7dc1128dc3..f72fe3e0df 100644
--- a/flymake-rest.el
+++ b/flymake-rest.el
@@ -6,7 +6,7 @@
;; Created: 15 June 2021
;; Homepage: https://github.com/mohkale/flymake-rest
;; Keywords: language tools
-;; Package-Requires: ((emacs "27.1"))
+;; Package-Requires: ((emacs "27.1") (let-alist "1.0"))
;; SPDX-License-Identifier: MIT
;; Version: 1.0.0
@@ -61,7 +61,7 @@
"Id of a diagnostic.")
(defun flymake-rest-parse-json (output)
- "Helper for `flymake-rest-define' to parse JSON output OUTPUT.
+ "Helper for `flymake-rest-define' to parse JSON OUTPUT.
Adapted from `flycheck-parse-json'. This reads a bunch of JSON-Lines
like output from OUTPUT into a list and then returns it."