-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Server-side Semantic Tokens #3159
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
Conversation
crates/ra_lsp_server/src/caps.rs
Outdated
@@ -57,6 +59,49 @@ pub fn server_capabilities() -> ServerCapabilities { | |||
execute_command_provider: None, | |||
workspace: None, | |||
call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)), | |||
semantic_tokens_provider: Some(SemanticTokensServerCapabilities::SemanticTokensOptions( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking the token and modifier lists should be exposed in a semantic_tokens.rs
file in ra_ide
so they can be reused in conv.rs
. Maybe as arrays or strings that then get converted to SemanticTokenType
and SemanticTokenModifer
via into()
when we fill in the server caps?
data: Vec<SemanticToken>, | ||
} | ||
|
||
impl SemanticTokensBuilder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A straight forward port of the typescript version but without the support for edits.
editors/code/vscode.proposed.d.ts
Outdated
@@ -0,0 +1,1737 @@ | |||
/*--------------------------------------------------------------------------------------------- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the rationale behind copying it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Followed instructions for proposed extensions. It will be removed before merging.
crates/ra_lsp_server/src/conv.rs
Outdated
type Output = (SemanticTokenType, Vec<SemanticTokenModifier>); | ||
|
||
fn conv_with(self, _world: &WorldSnapshot) -> (SemanticTokenType, Vec<SemanticTokenModifier>) { | ||
match self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also put a function-local use SemanticTokenType as Stt;
here to decrease verbosity, but I am not sure that everyone likes this style...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I am not a fan of local use *
or renames.
To make this less verbose, I'd ranter
let tag = match {
// many trivial branches;
}
let mods = match {
// copule of non-trivial branches
_ => vec![]
}
It also makes sense to refactor our internal repr to use tag + mods apporach, but that should be done separately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or
let simple_token_type = match self {
tags::KEYWORD => Stt::KEYWORD,
tags::SOMETHING => return (Stt::SOMETHING, vec![MODIFIER])
}
return (simple_token_type, vec![])
crates/ra_lsp_server/src/conv.rs
Outdated
SemanticTokenType::COMMENT, | ||
SemanticTokenType::KEYWORD, | ||
SemanticTokenType::STRING, | ||
SemanticTokenType::NUMBER, | ||
SemanticTokenType::REGEXP, | ||
SemanticTokenType::OPERATOR, | ||
SemanticTokenType::NAMESPACE, | ||
SemanticTokenType::TYPE, | ||
SemanticTokenType::STRUCT, | ||
SemanticTokenType::CLASS, | ||
SemanticTokenType::INTERFACE, | ||
SemanticTokenType::ENUM, | ||
SemanticTokenType::TYPE_PARAMETER, | ||
SemanticTokenType::FUNCTION, | ||
SemanticTokenType::MEMBER, | ||
SemanticTokenType::PROPERTY, | ||
SemanticTokenType::MACRO, | ||
SemanticTokenType::VARIABLE, | ||
SemanticTokenType::PARAMETER, | ||
SemanticTokenType::LABEL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a176cec
to
f49e942
Compare
Haven't looked too closely into this, but looks 👍 on the first glance! |
It's still WIP. I haven't had a chance to do much with it this week.
…On Sat, Feb 22, 2020, 7:03 AM Aleksey Kladov ***@***.***> wrote:
Haven't looked too closely into this, but looks 👍 on the first glance!
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#3159>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABBACRGWP4CI2GMMUGOFL23REEIAVANCNFSM4KV4SRIA>
.
|
7fb8741
to
38ae123
Compare
@matklad I've refactored a few things and I think the rust side is in good shape. However it's not useful from vscode yet. In order to get it to work you have to:
So I think I would like to back out the typescript changes and leave those as an exercise to anyone who would like to mess with tokens. |
38ae123
to
9f0cfb7
Compare
I've removed the client side changes. |
This only supports whole file token support. Once accepted I can tackle edits |
bors r+
Edits are not important. They add quite a bit of complexity for questionable performance benefits. What is important to support are ranges for narrowing down the highlighted bit. |
Build succeeded |
We also should remove our custom client-side hacks. It's ok if this regresses functionality for non-insiders builds. |
Let's not rush with removing working hacks, I personally don't use code insiders... |
Aggressively not accumulating technical debt is an explicit design guideline for rust-analyzer. We should actively migrate from hacks to insiders functionality. It's OK to regress the experience of users who don't use insiders. |
I disagree with both requiring the insiders version, which 99% of the people don't use, and having to manually pass an argument to vscode every time you want to start it. In this particular case the old implementation is kind of broken anyway, so it is not a very big problem, but in the general case I would prefer that users of the latest stable vscode release can keep using features. |
Yeah, this is exactly my reasoning here: we replacing something completely ad hoc and broken with something on path to stabilization. We should migrate from hacks, but we shouldn't change something that already works just because a new shiny thing just came out. |
impl Conv for &'static str { | ||
type Output = (SemanticTokenType, Vec<SemanticTokenModifier>); | ||
|
||
fn conv(self) -> (SemanticTokenType, Vec<SemanticTokenModifier>) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could do a more direct conversion here, avoiding the Vec
allocation, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think smallvec
could be more appropriate here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is using &'static str
type in the first place. It doesn't make sense to optimize impl details while the API itself is wrong. I think we should move to a model closer to tag+modifier
of LSP.
While we are at it, this is why I think it's important to migrate to new APIs:
|
@matklad I noticed last night that edits aren't used in the extensions so will focus on ranges. Thanks. |
@kjeremy should I do anything else to test this besides |
You have to also set "enableProposedApi": "true" in your package.json and in client.ts either:
|
Note that range requests and possibly edits are not implemented yet in vscode: microsoft/vscode#86415 (comment) |
Oh, right... @kjeremy do you have client-side implemenation around by any chance? If you have, could you send a PR? |
You mean the client.ts changes I mentioned above? I can't do that because it will kill the client on stable and insiders without that command line switch... maybe we can catch and ignore the error somehow. |
It's still useful to have at least a PR |
Done! #3321 |
Also, I think there was a problem that requests are canceld with |
I have not reported that issue. I THINK I saw it yesterday but then ran into the panics in #3310 which may be the actual problem. |
Takes the output of
syntax_highlighting
and converts it to the proposed semantic tokens API (so far onlytextDocument/semanticTokens
. There's a lot of cool stuff we could do with this and the "Inspect Editor Tokens and Scopes" vscode command (pic below) is a cool way to see what has tokens and what doesn't.Incredibly hacky and could panic due to unwraps,
panic!
etc. To use: run withcode-insiders --enable-proposed-api matklad.rust-analyzer
. If you try to run this without--enable-proposed-api
it will crash.@matklad I'm mostly looking for design feedback.