diff options
| author | mgmarlow <graham@mgmarlow.com> | 2023-06-12 19:59:44 -0700 |
|---|---|---|
| committer | mgmarlow <graham@mgmarlow.com> | 2023-06-12 19:59:44 -0700 |
| commit | 217ff0ca6e4d4f9e1290d830456a82312cd2b008 (patch) | |
| tree | 747f7cdc042b87434b1c24a6572851431d99d8eb | |
| parent | 3b136e9ce8905740d076e5222599dc59decba32c (diff) | |
| parent | 8f735f72bd109745fa7032502aa253759c661850 (diff) | |
| download | flymake-clippy-217ff0ca6e4d4f9e1290d830456a82312cd2b008.tar.gz | |
Merge branch 'clippy-flymake'
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | README.md | 22 | ||||
| -rw-r--r-- | clippy-flymake.el | 58 |
3 files changed, 85 insertions, 2 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3acc1df --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +.PHONY: build clean + +build: clean + emacs -batch -L . -f batch-byte-compile clippy-flymake.el + +clean: + rm -f clippy-flymake.elc @@ -1,3 +1,23 @@ # flymake-clippy -A Flymake backend for Clippy. +A Flymake backend for [Clippy](https://doc.rust-lang.org/stable/clippy/index.html), the Rust linter. + +## Instructions + +Use with [rust-mode](https://elpa.nongnu.org/nongnu/rust-mode.html): + +```elisp +(add-hook 'rust-mode-hook #'clippy-flymake-setup-backend) +``` + +## Eglot users + +Eglot [fully manages Flymake](https://github.com/joaotavora/eglot/issues/268) so you'll need some extra code to make it cooperate: + +```elisp +(add-to-list 'eglot-stay-out-of 'flymake) + +(add-hook 'eglot--managed-mode-hook + (lambda () + (add-hook 'flymake-diagnostic-functions #'eglot-flymake-backend nil t))) +``` diff --git a/clippy-flymake.el b/clippy-flymake.el index df5624a..e268c63 100644 --- a/clippy-flymake.el +++ b/clippy-flymake.el @@ -1,4 +1,8 @@ +<<<<<<< HEAD ;;; flymake-clippy.el --- Flymake backend for Clippy -*- lexical-binding: t; -*- +======= +;;; flymake-clippy.el --- Flymake backend for cargo clippy -*- lexical-binding: t; -*- +>>>>>>> @{-1} ;; Copyright (C) 2023 Graham Marlow @@ -20,9 +24,61 @@ ;;; Commentary: -;; Flymake backend for Clippy. +;; Flymake backend for Clippy, the Rust linter. +;; https://doc.rust-lang.org/stable/clippy/index.html ;;; Code: +(defun clippy-flymake (report-fn &rest _args) + "Flymake backend for cargo clippy." + (unless (executable-find "cargo") + (error "Cannot find cargo")) + + (let* ((source (current-buffer)) + (filename (file-name-nondirectory (buffer-file-name source)))) + (save-restriction + (widen) + (setq clippy--flymake-proc + (make-process + :name "clippy-flymake" :noquery t :connection-type 'pipe + :buffer (generate-new-buffer "*clippy-flymake*") + :command '("cargo" "clippy") + :sentinel + (lambda (proc _event) + (when (memq (process-status proc) '(exit signal)) + (unwind-protect + (if (with-current-buffer source (eq proc clippy--flymake-proc)) + (with-current-buffer (process-buffer proc) + (goto-char (point-min)) + ;; Collect output buffer into diagnostic messages/locations, + ;; exposing them via `report-fn'. + (cl-loop + while (search-forward-regexp + ;; Capture group source example: + ;; "warning: ..." + ;; --> src/filename.rs + ;; 98 | ... + (concat "^\\(warning:.*\\)\n\\(.*" filename "\\):\\([0-9]+\\):\\([0-9]+\\)$") + nil t) + for msg = (match-string 1) + for (beg . end) = (flymake-diag-region + source + (string-to-number (match-string 3))) + for type = (if (string-match "^warning" msg) + :warning + :error) + collect (flymake-make-diagnostic source beg end type msg) + into diags + finally (funcall report-fn diags))) + (flymake-log :warning "Canceling obsolete check %s" proc)) + ;; Cleanup temp buffer. + (kill-buffer (process-buffer proc))))))) + (process-send-region clippy--flymake-proc (point-min) (point-max)) + (process-send-eof clippy--flymake-proc)))) + +(defun clippy-flymake-setup-backend () + "Add `clippy-flymake' to `flymake-diagnostic-functions' hook." + (add-hook 'flymake-diagnostic-functions #'clippy-flymake nil t)) + (provide 'flymake-clippy) ;;; flymake-clippy.el ends here |
