diff options
| author | Mark Oteiza | 2017-10-28 20:32:50 -0400 |
|---|---|---|
| committer | Mark Oteiza | 2017-10-28 20:32:50 -0400 |
| commit | 2ebdde6e9cfe5bba337cad0a8be695f1e2bce7f8 (patch) | |
| tree | ad7bff22d699c0d848d07444c96d78e4a5a74d9c | |
| parent | 5b5984179122eca63a2e778e1a36c0c2bb24ad88 (diff) | |
| download | emacs-2ebdde6e9cfe5bba337cad0a8be695f1e2bce7f8.tar.gz emacs-2ebdde6e9cfe5bba337cad0a8be695f1e2bce7f8.zip | |
Add ChkTeX flymake backend for latex-mode
* lisp/textmodes/tex-mode.el (tex-flymake): New custom group.
(tex-chktex-program, tex-chktex-extra-flags): New custom variables.
(latex-mode): Add backend to flymake-diagnostic-functions.
(tex-chktex--process): New variable.
(tex-chktex-command, tex-chktex): New functions.
| -rw-r--r-- | lisp/textmodes/tex-mode.el | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el index 948743e8e5b..3da6e4e1124 100644 --- a/lisp/textmodes/tex-mode.el +++ b/lisp/textmodes/tex-mode.el | |||
| @@ -55,6 +55,11 @@ | |||
| 55 | :prefix "tex-" | 55 | :prefix "tex-" |
| 56 | :group 'tex) | 56 | :group 'tex) |
| 57 | 57 | ||
| 58 | (defgroup tex-flymake nil | ||
| 59 | "Flymake backend for linting TeX files." | ||
| 60 | :prefix "tex-" | ||
| 61 | :group 'tex) | ||
| 62 | |||
| 58 | ;;;###autoload | 63 | ;;;###autoload |
| 59 | (defcustom tex-shell-file-name nil | 64 | (defcustom tex-shell-file-name nil |
| 60 | "If non-nil, the shell file name to run in the subshell used to run TeX." | 65 | "If non-nil, the shell file name to run in the subshell used to run TeX." |
| @@ -259,6 +264,17 @@ measured relative to that of the normal text." | |||
| 259 | (float :tag "Superscript")) | 264 | (float :tag "Superscript")) |
| 260 | :version "23.1") | 265 | :version "23.1") |
| 261 | 266 | ||
| 267 | (defcustom tex-chktex-program "chktex" | ||
| 268 | "ChkTeX executable to use for linting TeX files." | ||
| 269 | :type 'string | ||
| 270 | :link '(url-link "man:chktex(1)") | ||
| 271 | :group 'tex-flymake) | ||
| 272 | |||
| 273 | (defcustom tex-chktex-extra-flags nil | ||
| 274 | "Extra command line flags for `tex-chktex-program'." | ||
| 275 | :type '(repeat string) | ||
| 276 | :group 'tex-flymake) | ||
| 277 | |||
| 262 | (defvar tex-last-temp-file nil | 278 | (defvar tex-last-temp-file nil |
| 263 | "Latest temporary file generated by \\[tex-region] and \\[tex-buffer]. | 279 | "Latest temporary file generated by \\[tex-region] and \\[tex-buffer]. |
| 264 | Deleted when the \\[tex-region] or \\[tex-buffer] is next run, or when the | 280 | Deleted when the \\[tex-region] or \\[tex-buffer] is next run, or when the |
| @@ -1154,6 +1170,7 @@ subshell is initiated, `tex-shell-hook' is run." | |||
| 1154 | (setq-local fill-indent-according-to-mode t) | 1170 | (setq-local fill-indent-according-to-mode t) |
| 1155 | (add-hook 'completion-at-point-functions | 1171 | (add-hook 'completion-at-point-functions |
| 1156 | #'latex-complete-data nil 'local) | 1172 | #'latex-complete-data nil 'local) |
| 1173 | (add-hook 'flymake-diagnostic-functions 'tex-chktex nil t) | ||
| 1157 | (setq-local outline-regexp latex-outline-regexp) | 1174 | (setq-local outline-regexp latex-outline-regexp) |
| 1158 | (setq-local outline-level #'latex-outline-level) | 1175 | (setq-local outline-level #'latex-outline-level) |
| 1159 | (setq-local forward-sexp-function #'latex-forward-sexp) | 1176 | (setq-local forward-sexp-function #'latex-forward-sexp) |
| @@ -3465,6 +3482,52 @@ There might be text before point." | |||
| 3465 | ;; Don't compose inside verbatim blocks. | 3482 | ;; Don't compose inside verbatim blocks. |
| 3466 | (eq 2 (nth 7 (syntax-ppss)))))))) | 3483 | (eq 2 (nth 7 (syntax-ppss)))))))) |
| 3467 | 3484 | ||
| 3485 | |||
| 3486 | ;;; Flymake support | ||
| 3487 | |||
| 3488 | (defvar-local tex-chktex--process nil) | ||
| 3489 | |||
| 3490 | (defun tex-chktex-command () | ||
| 3491 | "Return a list of command arguments for invoking ChkTeX." | ||
| 3492 | `(,tex-chktex-program ,@tex-chktex-extra-flags | ||
| 3493 | "--quiet" "--verbosity=0" "--inputfiles")) | ||
| 3494 | |||
| 3495 | (defun tex-chktex (report-fn &rest _args) | ||
| 3496 | "Flymake backend for linting TeX buffers with ChkTeX." | ||
| 3497 | (unless (executable-find tex-chktex-program) | ||
| 3498 | (error "Cannot find a suitable TeX checker")) | ||
| 3499 | (when (process-live-p tex-chktex--process) | ||
| 3500 | (kill-process tex-chktex--process)) | ||
| 3501 | (let ((source (current-buffer)) | ||
| 3502 | (re "^stdin:\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\):\\(.*\\)$")) | ||
| 3503 | (save-restriction | ||
| 3504 | (widen) | ||
| 3505 | (setq tex-chktex--process | ||
| 3506 | (make-process | ||
| 3507 | :name "tex-chktex" | ||
| 3508 | :buffer (generate-new-buffer "*tex-chktex*") | ||
| 3509 | :command (tex-chktex-command) | ||
| 3510 | :noquery t :connection-type 'pipe | ||
| 3511 | :sentinel | ||
| 3512 | (lambda (process _event) | ||
| 3513 | (when (eq (process-status process) 'exit) | ||
| 3514 | (unwind-protect | ||
| 3515 | (when (eq process tex-chktex--process) | ||
| 3516 | (with-current-buffer (process-buffer process) | ||
| 3517 | (goto-char (point-min)) | ||
| 3518 | (cl-loop | ||
| 3519 | while (search-forward-regexp re nil t) | ||
| 3520 | for msg = (match-string 4) | ||
| 3521 | for line = (string-to-number (match-string 1)) | ||
| 3522 | for col = (string-to-number (match-string 2)) | ||
| 3523 | for (beg . end) = (flymake-diag-region source line col) | ||
| 3524 | collect (flymake-make-diagnostic source beg end :warning msg) | ||
| 3525 | into diags | ||
| 3526 | finally (funcall report-fn diags)))) | ||
| 3527 | (kill-buffer (process-buffer process))))))) | ||
| 3528 | (process-send-region tex-chktex--process (point-min) (point-max)) | ||
| 3529 | (process-send-eof tex-chktex--process)))) | ||
| 3530 | |||
| 3468 | (run-hooks 'tex-mode-load-hook) | 3531 | (run-hooks 'tex-mode-load-hook) |
| 3469 | 3532 | ||
| 3470 | (provide 'tex-mode) | 3533 | (provide 'tex-mode) |