Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A couple minor fixes for Flymake diagnostics #4435

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

brownts
Copy link
Contributor

@brownts brownts commented Apr 20, 2024

No description provided.

@@ -298,7 +307,7 @@ See https://github.com/emacs-lsp/lsp-mode."
(when (= start end)
(if-let ((region (flymake-diag-region (current-buffer)
(1+ start-line)
character)))
(1+ character))))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate why +1? 🤔 Thanks!

Copy link
Contributor Author

@brownts brownts Apr 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flymake-diag-region expects the line and column values to start at 1, not start at 0 like LSP specifies. Thus, both the line and column need incrementing when calling flymake-diag-region. The line number was already incremented but the column was not.

Note that this logic is only executed when the LSP server doesn't support an end position (i.e., the start and end position are the same), so flymake-diag-region is used to compute it.

flymake-diag-region is typically used to turn a normal compiler diagnostic position (1-based) into a region. Since LSP specifies position as 0-based, we need to adjust the line and column numbers before using the function.

Previously, there was a Flycheck specific defcustom, which was used to
select a default error level for Flycheck.  However, there was nothing
for Flymake.  Additionally, there were numerous other places in
lsp-mode which query the severity attribute of the diagnostic, such as
for statistics, modeline, headerline, etc.  All of these were being
handled inconsistently, either not at all (causing an error when the
attribute was not sent by the server), ignoring it when it was
missing (causing statistics to be inaccurate) or assuming a default of
error, which might have been different than the Flycheck specific
configuration, therefore causing an inconsistency in the modeline
statistics vs what Flycheck would report.

This change creates a common defcustom which is then used anywhere the
diagnostic severity is needed, but was not provided by the server.
This should create consistent statistics between the modeline and the
back-end checkers.  Additionally, the mapping between this defcustom
and the checker specific values happens in the diagnostic package.

Since this defcustom is used outside of the lsp-diagnostic package, it
resides in the lsp-mode package and renamed more generally.
Additionally, the Flycheck specific defcustom has been obsoleted.
@brownts brownts force-pushed the bugfix/flymake-diagnostic branch from 71a9a69 to a686a77 Compare April 23, 2024 02:57
@brownts
Copy link
Contributor Author

brownts commented Apr 23, 2024

I decided to take a different approach with respect to the default severity level. Instead of adding an additional defcustom for Flymake (which seemed clunky to have two separate configurations for the same thing), I decided to make it more general and elevate it out of lsp-diagnostics to lsp-mode. The reason for this is because there were multiple places that really need this value. The lsp-modeline, lsp-headerline, lsp-mode and lsp-diagnostics all need this information. I also noticed that in those places the absence of the severity provided by the server manifested differently. Some didn't handle it at all (which caused an error to be raised), some ignored it completely, and some hard-coded it as an "error", which might have been inconsistent to the existing Flymake defcustom. Due to the needs outside of the lsp-diagnostics package, I made this more general. Now, any place that needs the severity and it isn't provided, will utilize this defcustom.

On a side note, I have also seen lsp-treemacs cause an error as well, since it's not checking whether the server provided a severity before attempting to use it, but that's another fix in another repo, lol.

(level (cond ((= severity lsp/diagnostic-severity-error) 'error)
((= severity lsp/diagnostic-severity-warning) 'warning)
((= severity lsp/diagnostic-severity-information) 'info)
((= severity lsp/diagnostic-severity-hint) 'info)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using pcase is probably cleaner.

And the one below, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that at first, but was having trouble with pcase not evaluating the lsp/diagnostic variables. If you have an example of how to transform this, I'd appreciate it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this isn't any cleaner. 🤔

(pcase severity
        ((pred (= lsp/diagnostic-severity-error))       'error)
        ((pred (= lsp/diagnostic-severity-warning))     'warning)
        ((pred (= lsp/diagnostic-severity-information)) 'info)
        ((pred (= lsp/diagnostic-severity-hint))        'info)
        (_ 'info))

It's okay to leave it as it is.

(const :tag "Information" info)
(const :tag "Hint" hint))
:group 'lsp-mode
:package-version '(lsp-mode . "9.0.1"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we keep this in lsp-diagnostics.el? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jcs090218, the reason I put it in lsp-mode.el is because there are multiple users, not just lsp-diagnostics.el. lsp-modeline, lsp-headerline, lsp-mode and lsp-diagnostics all need this information, so it seemed more general and likely belongs in lsp-mode.el. It answers the general question of what the user wants to do in the absence of LSP severity information. lsp-diagnostics.el is just one such user of this information.

I placed it in lsp-mode.el near a couple other diagnostic-related user options (i.e., lsp-after-diagnostics-hook and lsp-diagnostics-updated-hook) to be consistent there. It appears that lsp-diagnostics.el is strictly the diagnostics provider (i.e., Flymake/Flycheck) interfacing, but other LSP diagnostics related information is kept in lsp-mode.el.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants