-
Notifications
You must be signed in to change notification settings - Fork 837
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
Expand semantic highlighting support for CompletionItem.Documentation and Hover.Contents #1056
Comments
I understand the screenshot you've posted is for VisualStudio, could you provide an example of a similar method using a modern LSP client. This would make it easier understand the change you're proposing without having a lot of knowledge of LSPs and the way they're used. I'd love to see LSPs/LSIF used to generate static docs, and something like this seems like an absolute requirement for that, however commenting on your use of markdown is tricky without examples of current markdown capabilities. |
We discussed this internally as well and one idea was to have a special language in markup instead of sending the raw tokens. Something like
And then the client can turn it into semantic tokens. Would avoid having yet another MarkupKind and can be combined with other text since it is markup. |
@dbaeumer would that include being able to specify the token types for non-blocks? Putting the token type in the markdown block itself is a bit concerning to me given that it means you have to start reasoning about escaping rules with "unescaped" text, but it is certainly a workable approach with some amount effort. |
@333fred I am not sure I understand
Can you give me an example. What we should avoid is a format where positions are computed upfront. That makes it very hard to use if people want to type the text and still want to get semantic classification. |
In my original post, I showed a screenshot from VS that included classified text inline with normal text. Basically, being able to specify tokens in a single-backtick codeblock, not just a triple-backtick codeblock. |
I have 3 potential ideas. Not sure of any of the 3 are good.
|
Now that VS Code supports rendering a subset of HTML tags in MarkdownStrings (microsoft/vscode#40607) and there is a related capability for LSP (#1344) just waiting for a PR, this seems a lot more feasible. I really like this idea because it's still valid Markdown. Clients could announce support for these semantic tokens by announcing support for The only downside I see is that it's not as space-efficient of a format as the encoded uint-array, but I don't think these kinds of code blocks are nearly as large as whole source files, so maybe that's not an issue? Another idea if we do want to save space is to borrow the ## Highligting of a code block
<pre><code data-semantic-tokens="0">
void foo(Bar bar, String s, int i) {d
baz(bar, s, i + 3);
}
</code></pre>
## Highlighting of inline code
<code data-semantic-tokens="1">Foo bar(Baz baz)</code>
---
Some _normal_ markdown without semantic tokens.
---
## Highlighting of another code block
<pre><code data-semantic-tokens="2">
void bar(Foo foo, Float f) {
return false;
}
</code></pre> where the ranges of the encoded semantic tokens you get from Having said this, I also think it would be really useful to be able to provide commands (as links) on spans in the code block, in order to be able to provide something like "go to symbol" on the tokens. But that's probably outside the scope of this issue, unless we add that data to these semantic tokens and consider them different from the ones provided via Although now that I think about it, this would already be possible in my <pre><code data-semantic-tokens="3">
void bar(<a href="file:/path/to/Foo">Foo</a> foo, Float f) {
return false;
}
</code></pre> assuming that the client announces support for But that again raises the question of how semantic token ranges should handle the fact that the contents of the code block are not the same as what's rendered to the user. Again, a simple solution would be to encode the semantic tokens as Another idea is to add Considering this, maybe the attribute on the |
I think the simplest proposal would be to just add |
Version 3.16 will add semantic highlighting to the protocol, which is a great addition that Omnisharp has already used to great effect. However, adding this to the text editor has then made all the places that use markdown for formatting today stick out, as they're not using real semantic classification and can often mess up highlighting, particularly because they're just snippets. A bare word might refer to a parameter or field or method name, for example, but as the markdown content of the documentation or hover has no extra info, it'll be highlighted as a local variable. I recently implemented some improvements for Omnisharp in the hover provider to use Roslyn's QuickInfo service, but the lack of expressiveness in markdown quickly became apparent. I think the issue is best demonstrated through a picture. Given this simple sample with some documentation comments:
Here's what the hover looks like in VS over

M
:There's several pieces of this popup that are simply unachievable through unaltered markdown:
$(symbol-method)
would be interpreted as that literal text and not substituted with a codicon.Class2
and it will go to definition on that member. This is also not possible for the same reason as # 1: the[]()
link syntax inside a code block would be interpreted literally.Class2
in the summary and returns section are semantically colored and clickable. There are some markdown extensions that support inline colorization of single-line code blocks, but this is a) not semantic, and b) not guaranteed to be supported by the editor. You can get links working for these locations as they're single-line blocks, but you can't get both today.To solve these, I'd like to propose an extension to
MarkupContent
. This is a very, very, very rough proposal: I spend most of my time in compiler land and am certain to get parts of this wrong, so criticism and ideas are welcome. This extension has, to my mind, a few specific goals:My initial proposal is to add a new kind to
MarkupKind
to indicate that the content is semantic markdown and provide a SemanticTokens stream that should be used for colorization. In the definition below, I've elided the existing parts ofMarkupContent
for brevity, but assume they're unchanged except where noted.For the previous example of hovering over
M
, this is a rough idea of what you'd provide. I'm going to just use type or identifier names in the url locations, but presumably they'd be actual URIs that link to commands.The accompanying token stream would look something like this. I'm going to make the stream uncompressed for the sake of everyone reading this, and I'm sure I'll get some offset wrong, but it conveys the general idea:
As I said, this is a very rough first draft, and there are a few open questions I have:
a. If yes, backticks should still be specified, should the semantic classification span include the backticks?
The text was updated successfully, but these errors were encountered: