flycheck / flycheck-eglot

Flycheck support for eglot
GNU General Public License v3.0
32 stars 3 forks source link

+TITLE: flycheck-eglot

+AUTHOR: Sergey Firsov intramurz@gmail.com

[[https://melpa.org/#/flycheck-eglot][file:https://melpa.org/packages/flycheck-eglot-badge.svg]]

A simple "glue" minor mode that allows [[https://www.flycheck.org/][Flycheck]] and [[https://github.com/joaotavora/eglot][Eglot]] to work together. Thus, the Flycheck frontend can display the results of syntactic checks performed by the LSP server.

** Manually

You can simply copy =flycheck-eglot.el= to your local filesystem, and add the path to the file to the ~load-path~ variable so that Emacs can find it.

** Quelpa

A more advanced way is with a package management tool that can install directly from Github repositories, such as [[https://github.com/quelpa/quelpa][quelpa]]. Evaluate this or add to your init file:

+begin_src elisp

  (quelpa '(flycheck-eglot :repo "flycheck/flycheck-eglot"
                           :fetcher github
                           :upgrade t))

+end_src

** MELPA (recommended)

You can install this package from [[https://melpa.org][MELPA]] manually using the standard package manager ~M-x package-install RET flycheck-eglot RET~ or install and configure it [[https://github.com/intramurz/flycheck-eglot#using-use-package][using use-package]].

** Manual Toggle

You can toggle the Flycheck-Eglot mode for the current buffer: ~M-x flycheck-eglot-mode~; if the buffer is not Eglot-enabled, this will have no effect. You can also toggle Flycheck-Eglot mode system-wide - for all applicable buffers: ~M-x global-flycheck-eglot-mode~.

** With an init file

*** Minimal

You just need to put the following in the init file:

+begin_src elisp

(require 'flycheck-eglot) (global-flycheck-eglot-mode 1)

+end_src

*** Using use-package

Most recommended setup with [[https://github.com/jwiegley/use-package][use-package]]:

+begin_src elisp

(use-package flycheck-eglot :ensure t :after (flycheck eglot) :config (global-flycheck-eglot-mode 1))

+end_src

You can also enable Flycheck-Eglot mode only for certain major modes. For example:

+begin_src elisp

(use-package python-mode :hook (python-mode . (lambda () (eglot-ensure) (flycheck-eglot-mode 1))))

+end_src

*** Cooperation with other checkers

By default, the Flycheck-Eglot considers the Eglot to be the only provider of syntax checks. The LSP-mode with Flycheck and the Eglot with Flymake behave in a similar way. It is assumed that all suitable checkers are plugged in the LSP server. In most cases, this is what you need. However, in case you need to use an Eglot checker in parallel with regular Flycheck checkers, there is a variable ~flycheck-eglot-exclusive~ that controls this. You can override it system wide:

+begin_src elisp

(use-package flycheck-eglot :ensure t :after (flycheck eglot) :custom (flycheck-eglot-exclusive nil) :config (global-flycheck-eglot-mode 1))

+end_src

or in a major mode hook:

+begin_src elisp

(use-package python-mode :hook (python-mode . (lambda () (setq flycheck-eglot-exclusive nil) (eglot-ensure))))

+end_src

** With Customize interface

You can enable ~global-flycheck-eglot-mode~ by default, or change the ~flycheck-eglot-exclusive~ default value using Customize (if you like that way).

Diagnostic tags are supported (according to the LSP protocol [[https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18/specification/#diagnosticTag][specification]]). Tagged diagnostics are decorated in a special way when displaying the source code. You can toggle this feature with the ~flycheck-eglot-enable-diagnostic-tags~ custom variable.

Some technical notes on the feature. The implementation creates auxiliary "tagged" error levels ([[https://github.com/emacs-lsp/lsp-mode][lsp-mode]] uses the same approach). By default, these extra levels are named like ~level:tags~, where ~level~ is the name of the /base level/ (~error~, ~warning~, or ~info~), and ~tags~ are the /tag labels/: ~?~ for ~unnessesary~, ~*~ for ~deprecated~, or both. You can try tweaking the ~flycheck-eglot-tag-labels~, ~flycheck-eglot-level-tag-separator~ and ~flycheck-eglot-tag-separator~ variables and get something like ~error-unnessesary-deprecated~ (is that even possible?)

The feature is not critical (and not even extremely useful): if it causes problems or you don't like it, you can turn it off.

Flycheck-Eglot mode automatically enables Flycheck and disables Flymake.

When I decided to try another LSP client for Emacs, I discovered that the Eglot out of the box supports only Flymake, but not Flycheck (which I did not intend to change - I consider it more convenient and rich in features). There was a need to somehow connect the Eglot and Flycheck. Searching for a ready-made solution in [[https://melpa.org][MELPA]] and [[https://elpa.gnu.org/][ELPA]] did not give any results, however, I found out that the popular [[https://github.com/doomemacs/doomemacs][Doom Emacs]] has a similar feature. Not being a Doom Emacs user, I trivially adapted the code from there (as some other users have already done in this case). Testing this solution revealed a nasty bug in it: when editing, the display of errors was one step behind the current changes, catching up with them only when a new line was entered or the buffer was saved. In addition, it behaved incorrectly when reverting the buffer. After some experimentation and reading the Eglot code, these bugs were fixed. Along the way, I've added a few changes to make it easier to use, and slightly refactored the code to my liking. As a result, I came to rewrite the feature in a more standard form for Emacs, so that a regular user can install and configure it in the most simple way, that is, a minor mode in the package.

This package has its origin in [[https://github.com/doomemacs/doomemacs/blob/aa54383b5d30d9e1a275b27244335a5aa6114318/modules/tools/lsp/autoload/flycheck-eglot.el][this module]] of Doom Emacs code with a similar purpose. Many thanks to its authors for their efforts. Today Doom Emacs uses our package instead.

Thanks to [[https://github.com/p00f][p00f]] for suggesting the implementation of diagnostic tags and for the early prototype.

Flycheck-Elgot is distributed under the GNU General Public License, version 3.

This package has its origin in a piece of Doom Emacs code, which was distributed under the MIT License (MIT).