Skip to content

Commit d8ef53b

Browse files
jojCopilot
andcommitted
lsp: emit VS-internal HiddenInEditor tag for unnecessary diagnostics
The LSP spec says clients are "allowed to render diagnostics [tagged Unnecessary] faded out instead of having an error squiggle." Visual Studio's LSP client, however, only renders the faded "unused" appearance when a diagnostic carries both DiagnosticTag.Unnecessary AND the VS-internal VSDiagnosticTags.HiddenInEditor tag; with just Unnecessary the diagnostic shows as a normal squiggle. When the client advertises _vs_supportsVisualStudioExtensions, also emit HiddenInEditor (int32.MaxValue - 6 = 2147483641) so unused variables and similar diagnostics render faded in Visual Studio. Non-VS clients continue to receive only the standard LSP tags. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 913fed9 commit d8ef53b

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

internal/ls/lsconv/converters.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,16 @@ func diagnosticToLSP(ctx context.Context, converters *Converters, diagnostic *as
300300

301301
var tags []lsproto.DiagnosticTag
302302
if len(opts.tagValueSet) > 0 && (diagnostic.ReportsUnnecessary() || diagnostic.ReportsDeprecated()) {
303-
tags = make([]lsproto.DiagnosticTag, 0, 2)
303+
tags = make([]lsproto.DiagnosticTag, 0, 3)
304304
if diagnostic.ReportsUnnecessary() && slices.Contains(opts.tagValueSet, lsproto.DiagnosticTagUnnecessary) {
305305
tags = append(tags, lsproto.DiagnosticTagUnnecessary)
306+
// Visual Studio's LSP client only renders Unnecessary diagnostics as
307+
// faded-out text when they also carry the VS-internal HiddenInEditor
308+
// tag; otherwise they appear as a regular squiggle. Emit it so VS
309+
// matches the LSP-spec intent of the Unnecessary tag.
310+
if opts.visualStudio {
311+
tags = append(tags, lsproto.VSDiagnosticTagHiddenInEditor)
312+
}
306313
}
307314
if diagnostic.ReportsDeprecated() && slices.Contains(opts.tagValueSet, lsproto.DiagnosticTagDeprecated) {
308315
tags = append(tags, lsproto.DiagnosticTagDeprecated)

internal/lsp/lsproto/lsp.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,4 +312,15 @@ func PreferredMarkupKind(formats []MarkupKind) MarkupKind {
312312
const (
313313
CodeActionKindSourceRemoveUnusedImports CodeActionKind = "source.removeUnusedImports"
314314
CodeActionKindSourceSortImports CodeActionKind = "source.sortImports"
315+
316+
// VSDiagnosticTagHiddenInEditor is a Visual Studio-specific DiagnosticTag
317+
// (see Microsoft.VisualStudio.LanguageServer.Protocol.Extensions.VSDiagnosticTags)
318+
// indicating the diagnostic should not be rendered with a squiggle in the
319+
// editor. When combined with DiagnosticTagUnnecessary, Visual Studio
320+
// renders the affected code as faded-out text (the typical "unused
321+
// variable" appearance). VS extension tags use sentinel values near
322+
// int32.MaxValue to avoid colliding with future standard DiagnosticTag
323+
// additions. Only emit when the client advertises
324+
// _vs_supportsVisualStudioExtensions.
325+
VSDiagnosticTagHiddenInEditor DiagnosticTag = 2147483641 // int32.MaxValue - 6
315326
)

0 commit comments

Comments
 (0)