Skip to content

feat: append LSP diagnostic codes to flymake messages#5036

Open
alberti42 wants to merge 1 commit into
emacs-lsp:masterfrom
alberti42:show-diagnostic-codes
Open

feat: append LSP diagnostic codes to flymake messages#5036
alberti42 wants to merge 1 commit into
emacs-lsp:masterfrom
alberti42:show-diagnostic-codes

Conversation

@alberti42
Copy link
Copy Markdown
Contributor

Currently, lsp-diagnostics--flymake-update-diagnostics extracts :message and :severity? from each LSP diagnostic but silently drops :code?. As a result, flymake displays messages like:

"variable_XYZ" is possibly unbound

without the diagnostic rule name that the language server also provides.

This patch binds :code? and appends it to the message text when present:

"variable_XYZ" is possibly unbound [reportPossiblyUnbound]

This is a small but valuable change. The diagnostic code is the primary handle users need to:

  • search for the error online
  • look it up in the language server's documentation
  • write a precise inline suppression comment (e.g. # pyright: ignore[reportPossiblyUnbound])

Without the code, users must guess the rule name. The fix is a two-line change: bind :code? in the existing -let* destructuring and conditionally append [code] to the message.

The code field is optional in the LSP spec, so the format falls back gracefully to the plain message when absent.

@jcs090218
Copy link
Copy Markdown
Member

Can you do this to flycheck too? Thanks! :D

@alberti42
Copy link
Copy Markdown
Contributor Author

Hi @jcs090218, thanks for the quick reply already.

I checked flycheck. The good news is that we don't need to change anything in the flycheck branch. The code is already correct and exactly displays the error code as [CODE].

You can see that code? was already deconstructed and passed to :id. Flycheck then takes care of rendering it correctly.

(-map (-lambda ((&Diagnostic :message :severity? :tags? :code? :source?
                                    :range (&Range :start (start &as &Position
                                                                 :line      start-line
                                                                 :character start-character)
                                                   :end   (end   &as &Position
                                                                 :line      end-line
                                                                 :character end-character))))
               (flycheck-error-new
                :buffer (current-buffer)
                :checker checker
                :filename buffer-file-name
                :message message
                :level (lsp-diagnostics--flycheck-calculate-level severity? tags?)
                :id code?
                :group source?
                :line (lsp-translate-line (1+ start-line))
                :column (1+ (lsp-translate-column start-character))
                :end-line (lsp-translate-line (1+ end-line))
                :end-column (unless (lsp--position-equal start end)
                              (1+ (lsp-translate-column end-character))))))

What was missing was precisely the flymake branch where the code was not displayed. If this PR makes it to upstream, then both branches display the same message and error code.

@alberti42
Copy link
Copy Markdown
Contributor Author

alberti42 commented Apr 18, 2026

Hi @jcs090218 and maintainers,

I looked into the three failing CI checks (the snapshot, true rows on ubuntu-latest, ubuntu-24.04-arm, and macos-latest). They predate this PR: the same three jobs fail on the latest master runs, and the root cause is an Emacs-snapshot / ert-runner compatibility issue (ert-compat load error, void-function defmacro*) that trips lsp-byte-compilation-test before any of the code in this PR is exercised. From what I understand, the stable matrix (Emacs 28.2 / 29.4 / 30.2 across Linux, macOS, Windows) is all green, and those jobs are marked continue-on-error anyway, so I don't think they should block the merge.

While I have your attention, would you be open to a follow-up that makes this more configurable per client? Two directions where I'd appreciate your feedback:

  1. Composable formatter: a per-client hook, e.g. :diagnostic-message-fn, that takes the LSP diagnostic and returns the flymake message string. Users/clients could then format as they like (include source, code, code-description href, severity, etc.). The current behavior would be the default.
  2. Simple toggle: a per-client boolean (e.g. :flymake-show-diagnostic-code) to suppress the [code] suffix for servers where it's noisy. Cheaper, but less flexible.

My motivation is that for some servers the codes are essential (Pyright, tsc), while for others they're just visual noise on every line. Happy to prepare a demo PR for whichever direction you prefer, either extending this one, or as a separate PR once this lands. Let me know what you think is the best.

@jcs090218
Copy link
Copy Markdown
Member

I checked flycheck. The good news is that we don't need to change anything in the flycheck branch. The code is already correct and exactly displays the error code as [CODE].

Hmm.. I think the text renders differently. These are my sideline screenshots (applied your changes):

flycheck

flycheck

flymake

flymake

@jcs090218
Copy link
Copy Markdown
Member

I looked into the three failing CI checks (the snapshot, true rows on ubuntu-latest, ubuntu-24.04-arm, and macos-latest). They predate this PR: the same three jobs fail on the latest master runs, and the root cause is an Emacs-snapshot / ert-runner compatibility issue (ert-compat load error, void-function defmacro*) that trips lsp-byte-compilation-test before any of the code in this PR is exercised. From what I understand, the stable matrix (Emacs 28.2 / 29.4 / 30.2 across Linux, macOS, Windows) is all green, and those jobs are marked continue-on-error anyway, so I don't think they should block the merge.

Yeah, there are breaking changes on the Emacs snapshot. No need to worry about those job failures (at least for now). :)

While I have your attention, would you be open to a follow-up that makes this more configurable per client? Two directions where I'd appreciate your feedback:

I prefer the Composable formatter approach because it's more flexible and gives users greater control.

Thanks for bringing this up! :D

@alberti42 alberti42 force-pushed the show-diagnostic-codes branch from b94bab6 to d468183 Compare May 3, 2026 10:25
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