I'm building a language server in C# (with VS2022) that implements the Language Server Protocol (LSP) 17.2.8 (https://www.nuget.org/packages/Microsoft.VisualStudio.LanguageServer.Protocol.Extensions)
I'm new to the Language server protocol, and there might be a simple solution to my problem. I created markdown content for a Hover popup, but the content is displayed as plain text.
This is the OnHover,
[JsonRpcMethod(Methods.TextDocumentHoverName)]
public Hover OnHover(JToken arg)
{
LogInfo($"OnHover: Received: {arg}");
var parameter = arg.ToObject<TextDocumentPositionParams>();
[SNIP details]
var hoverContent = new SumType<string, MarkedString>[]{
new SumType<string, MarkedString>(new MarkedString
{
Language = MarkupKind.PlainText.ToString(),
Value = full_Descr + "\n",
}),
new SumType<string, MarkedString>(new MarkedString
{
Language = MarkupKind.Markdown.ToString(),
Value = "```text\n" + performanceStr + "\n```",
})
};
var result = new Hover()
{
Contents = hoverContent
};
LogInfo($"OnHover: Sent: {JToken.FromObject(result)}");
return result;
}
The language server sends the following message to my VisualStudio extension (vsix):
{
"contents": [
{
"language": "PlainText",
"value": "VPCONFLICTQ : [NONE,AVX512_CD] Detect Conflicts Within a Vector of Packed Dword/Qword Values into Dense Memory/ Register\n"
},
{
"language": "Markdown",
"value": "```text\n µOps µOps µOps \nArchitecture Instruction Fused Unfused Port Latency Throughput \nSkylakeX VPCONFLICTQ x,x 3 3 p01 p5 4 2 \nSkylakeX VPCONFLICTQ y,y 15 15 p01 p5 13 7 \nSkylakeX VPCONFLICTQ z,z 22 22 p0 p5 17 12 \n```"
}
]
}
When the language server is initialized, it sends (to my VS-extension) a JSON with capabilities (removed all other capabilities).
{
"capabilities": {
"hoverProvider": {}
}
}
Question: Is there something else that I need to configure to get a popup with Markdown layout? Is Markdown not supported from the Visual studio side? Do I need HoverClientCapabilities to configure stuff?
The de facto reference implementation can be found in the VSSDK-Extensibility-Samples (https://github.com/microsoft/VSSDK-Extensibility-Samples/tree/master/LanguageServerProtocol), but it does not have a markdown popup. Even a link to working C# code would be appreciated.
Edit: see here for what I've tried.
From what I understand searching around, markdown doesn't work yet in VS 2022 (current version 17.7.4). Or at least Roslyn and other Microsoft products apparently use an undocumented
Microsoft.VisualStudio.LanguageServer.Protocol.VSInternalHover, which has an additionalRawContentfield that tells Visual Studio about the classifications etc. See examples below.Examples:
Roslyn
Razor
Also notice that there is a
Microsoft.VisualStudio.LanguageServer.Protocol.VSInternalClientCapabilitiesreferenced in Roslyn.According to this comment, there is an open issue to support markdown in their internal issue tracker.
EDIT: Digging through a decompilation of the Microsoft.VisualStudio.LanguageServer.Client.Implementation.dll, specifically
Microsoft.VisualStudio.LanguageServer.Client.HoverSource.GetQuickInfoItemAsync(), Visual Studio checks the hover response for the internal typeIHoverContent, then forVSInternalHover. If one of them is given, theirRawContentis directly forwarded to theQuickInfoItem. AMarkedStringor an array thereof are also forwarded. Astringand theValueofMarkupContentapparently are not forwarded directly, but only content within markdown triple ticks ``` (for whatever reason).In any case, according to the documentation of
QuickInfoItem, the object it contains is forwarded toIToolTipPresenterwhich should end up usingIViewElementFactoryService, which says:So, Roslyn etc. give a
ClassifiedTextElementsdirectly, which can be displayed byQuickInfoItemin Visual Studio directly. As far as I can see, nothing in VS implementsIViewElementFactoryforMarkedStringyet. So it ends up using itsToString()method.Conclusion: Markdown is not yet supported. The only workaround to get formatted hovers is to use the undocumented
VSInternalHover.RawContentand set it to aClassifiedTextElement(like Roslyn is doing).Since it is undocumented, this will most likely break in a future VS version. But hopefully markdown exists by then.