To accommodate breaking API changes in Flymake in newer versions of Emacs 28. Fix: #5644 Ref: emacs-mirror/emacs@4633e02726
76 lines
2.8 KiB
EmacsLisp
76 lines
2.8 KiB
EmacsLisp
;;; flycheck-eglot --- Hacky eglot support in flycheck -*- lexical-binding: t; -*-
|
|
;;; Commentary:
|
|
;; This file sets up flycheck so that, when eglot receives a publishDiagnostics method
|
|
;; from the server, flycheck updates the reports.
|
|
;;
|
|
;; Thanks to:
|
|
;; - joaotavora for adding a handle to plug flycheck, and
|
|
;; - purcell for finding out the initial stub and the current implementation
|
|
;;
|
|
;; It works by creating a bridge function which can be used as the argument of
|
|
;; `eglot-flymake-backend', which both consumes diagnostics and queue a call to
|
|
;; 'flycheck-buffer'
|
|
;;
|
|
;;; Code:
|
|
|
|
(defvar-local +lsp--flycheck-eglot--current-errors nil)
|
|
|
|
(defun +lsp--flycheck-eglot-init (checker callback)
|
|
"CHECKER is the checker (eglot).
|
|
CALLBACK is the function that we need to call when we are done, on all the errors."
|
|
(eglot-flymake-backend #'+lsp--flycheck-eglot--on-diagnostics)
|
|
(funcall callback 'finished +lsp--flycheck-eglot--current-errors))
|
|
|
|
(defun +lsp--flycheck-eglot--on-diagnostics (diags &rest _)
|
|
(cl-labels
|
|
((flymake-diag->flycheck-err
|
|
(diag)
|
|
(with-current-buffer (flymake--diag-buffer diag)
|
|
(flycheck-error-new-at-pos
|
|
(flymake--diag-beg diag)
|
|
(pcase (flymake--diag-type diag)
|
|
('eglot-note 'info)
|
|
('eglot-warning 'warning)
|
|
('eglot-error 'error)
|
|
(_ (error "Unknown diagnostic type, %S" diag)))
|
|
(flymake--diag-text diag)
|
|
:end-pos (flymake--diag-end diag)
|
|
:checker 'eglot
|
|
:buffer (current-buffer)
|
|
:filename (buffer-file-name)))))
|
|
(setq +lsp--flycheck-eglot--current-errors
|
|
(mapcar #'flymake-diag->flycheck-err diags))
|
|
;; Call Flycheck to update the diagnostics annotations
|
|
(flycheck-buffer-deferred)))
|
|
|
|
(defun +lsp--flycheck-eglot-available-p ()
|
|
(bound-and-true-p eglot--managed-mode))
|
|
|
|
(flycheck-define-generic-checker 'eglot
|
|
"Report `eglot' diagnostics using `flycheck'."
|
|
:start #'+lsp--flycheck-eglot-init
|
|
:predicate #'+lsp--flycheck-eglot-available-p
|
|
:modes '(prog-mode text-mode))
|
|
|
|
(push 'eglot flycheck-checkers)
|
|
|
|
(add-hook! 'eglot-managed-mode-hook
|
|
(defun +lsp-eglot-prefer-flycheck-h ()
|
|
(when eglot--managed-mode
|
|
(flymake-mode -1)
|
|
(when-let ((current-checker (flycheck-get-checker-for-buffer)))
|
|
(unless (equal current-checker 'eglot)
|
|
(flycheck-add-next-checker 'eglot current-checker)))
|
|
(flycheck-add-mode 'eglot major-mode)
|
|
(flycheck-mode 1)
|
|
;; Call flycheck on initilization to make sure to display initial
|
|
;; errors
|
|
(flycheck-buffer-deferred))))
|
|
|
|
(after! flymake
|
|
(when (and
|
|
(not (fboundp 'flymake--diag-buffer))
|
|
(fboundp 'flymake--diag-locus))
|
|
(defalias 'flymake--diag-buffer 'flymake--diag-locus)))
|
|
|
|
;;; flycheck-eglot.el ends here
|