rust-lang/rust-analyzer

Announcements: Client Changes

matklad opened this issue · 68 comments

This issue exists to announce changes which might affect rust-analyzer plugins for different editors.
If you maintain such a plugin, consider subscribing to this issue.

All our protocol extensions are documented at lsp-extensions.md. I'll try to remember to leave a comment on this issue if I modify that file.

After #4632, all our current extensions are documented. There were a bunch of minor changes here and there. Most notably some requests were moved from rust-analyzer/foo to experimental/foo, in hope that this might be useful for other servers, and to mark the extensions we intend to upstream to the protocol itself.

Notably, inlay hints and runnables are are still unchanged: i want to upstream these two as well, but I am not too happy with their current state, and I don't have time to polish them right now. So i opted for documenting them as is, and cleaning up later.

#4688 documents our initilizationOptions.

#4710 changes API for runnables. The idea is that it's the client who is reponsible for running stuff, to make it possible to, eg, inject debugger support or other custom tools. So, rust-analzyer provides a more abstract representation of a cargo command, to make it easier for the client to make sense of it.

#4717 adds API for lazily computing code action edits.

#5188 adds status notification.

adds "memory usage" command: #5244

#4972 will switch to gzipping release artifacts.

rust-analyzer is available via rustup.

15:04:42|~/projects/rust-analyzer/editors/code|master✓
λ rustup component add --toolchain nightly rust-analyzer-preview
info: component 'rust-analyzer-preview' for target 'x86_64-unknown-linux-gnu' is up to date

15:04:46|~/projects/rust-analyzer/editors/code|master✓
λ rustup run nightly rust-analyzer --version
rust-analyzer f5a4a4b

The "officially recommended" binary at the moment is still the one from releases in this repo, but rustup one should be fine as well.

#5930 adapts the latest changes of the semantic tokens

Flexible runnables configuration:

I am adding a rust-analyzer action for #6462, and will be changing the hash.

#6521 removes our custom support for code action resolving in favor of one provided by LSP 1.16.

#6761 adds a rust-analyzer --print-config-schema command which prints JSON-schema for the configuration for rust-analyzer, in the style of package.json. This should allow non-VS Code clients to show better auto-complete & docs for user config, and should also help to ensure that the defaults are the same between vscode and other editors.

In #6996 we want to stop releasing uncompressed binaries. Clients that can automatically install the LSP server binary should download the .gz file instead.

We've also changed the naming convention to include the platform tuple:

  • instead of rust-analyzer-windows.exe, use rust-analyzer-x86_64-pc-windows-msvc.gz
  • instead of rust-analyzer-linux, use rust-analyzer-x86_64-unknown-linux-gnu.gz
  • instead of rust-analyzer-mac, use rust-analyzer-x86_64-apple-darwin.gz

This allows us to support new platforms more easily, speeds up downloads and avoids wasting disk space.

#7068 adds a command to show our HIR representation of a function.

#7412 adds a new readyPartial in status notification :

export type Status = "loading" | "ready" | "readyPartial" | "invalid" | "needsReload";

#7625 adds a "copy runnable command line" command.

It is now possible to use ut8 coordinate space for positions and ranges: #7657

#8054 adds a new request to move functions, statements, etc up and down.

Side note: There's a missing n in the title, it should be "Announcements".

#8355 replaces rust-analyzer specific rust-analyzer/status with a more general experimental/serverStatus. close upstream issue: microsoft/language-server-protocol#511

For the record, here the new status is documented as requiring serverStatus capability, when in rust-analyzer only reacted to serverStatusNotification.

Is that a typo in the docs or a bug in #8355?

@matklad ping re bstaletic's question. Would like a clarification on what was the intention there, please.

Bug in the spec!

Pushed the fix and clarified the docs in #8580. @bstaletic I see that you are using the status to check is this a good occasion to bother the server with requests. I guess you can do that, but its not really necessary. In VS Code client, we just always send the requests, without checking if the server is ready.

The status notification is used solely to draw an entry in the modline for the user: https://github.com/rust-analyzer/rust-analyzer/blob/master/editors/code/src/ctx.ts#L69-L91

#7698 and #8877 extend workspace/symbol to allow for filtering, such as "give me all types in my project" or "give me all types and functions in my project and its dependencies". I feel that we might want to iterate a bit on what exactly the filtering parameter looks like, but, if we do that we'll add new capability.

#8926 drops the uncompressed release artifacts and those that don't contain the target name:

  • rust-analyzer-linux
  • rust-analyzer-linux.gz
  • rust-analyzer-mac
  • rust-analyzer-mac.gz
  • rust-analyzer-windows.exe
  • rust-analyzer-windows.gz

With #9693, it's now possible to pass a Range in the Hover request, and not just a position.

#9732 add client capabilities for curstom client-side rust-analyzre commands. So, heads up, action required: if your client implements any of

                "rust-analyzer.runSingle",
                "rust-analyzer.debugSingle",
                "rust-analyzer.showReferences",
                "rust-analyzer.gotoLocation",
                "editor.action.triggerParameterHints",

Then add

"experimental": {
  "commands": {
    "commands": [ "rust-analyzer.runSingle", "rust-analyzer.debugSingle", "rust-analyzer.showReferences", "rust-analyzer.gotoLocation", "editor.action.triggerParameterHints"]
  }
}

to the capabilities. Note the nested commands/commands. This feels stupid, but is intentional -- it mirrors the capability for server commands, and allows us to add more fields to the cap in a backwrad compatible way

After #9828, the crate graph is returned in the dot (GraphViz) syntax instead of a SVG. The Code extension runs a built-in GraphViz to render it.

#11830 allows OnTypeFormatting request to return SnippetTextEdit

#11935 fully switches to LSP inlay hints, experimental/inlayHints is now gone.

#12010 will change a lot of the config keys we currently have, to make them more consistent as well as giving us the ability to extend configurations without breakage more easily. The PR description contains all the key changes as well as the few config keys that have been merged/split.

We are planning on merging the PR next week on monday on May 9th after our stable release to let it sit with nightly for a full week until the next stable release.

If you have points to raise regarding this please do so on zulip https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frust-analyzer/topic/r-a.20config.20format or on the linked PR.

Follow up to my previous comment, since most clients don't have the luxury of matching up server with client like the VSCode extension does we'll add a compatibility layer for some time that will keep accepting the old values (though we do want to remove this in the future at some point, so it would be great if the clients could nudge their users to updating their configs/if the clients could transition over to the new one)

It's not a matter of matching versions, it's a matter of breaking existing users' configuration, right?

@puremourning kind of, yeah. The VSCode extension will update configurations to the new format if I understand correctly, but that's not an option for most clients. But e.g. the Emacs plugin has its own customizations for most RA options, which can (will need to) be translated to the new config format.

exactly, so "delaying" isn't really solving.

It's solving the problem for clients like VSCode and Emacs; clients that just let users directly pass RA config JSON will need a different solution. Maybe we will have to take on the "nudging users to update their configs" somehow.

For the transition period - ra could just send a showMessage notification to user notifying them about upcoming config changes, wouldn't that work better when paired with "delaying" ?

It might yeah, for clients that implement that message, which, err, ahem, mine doesn't (!). But I think that's a fair compromise.

#13792 and 2 earlier PRs now allow controlling the flycheck (checkOnSave) features a bit via notifications. They have been described in the lsp-ext docs in #13792.

#13699 uses location links in inlay hints. It is not a lsp extension and it exists in standard lsp, but since no language server which I'm aware of is currently using this feature, it is very likely that some clients have not implemented this feature. See inlay hint label part in lsp spec.

If merged, #13876 will add a ZIP release artifact on Windows containing the language binary corresponding PDB. This should make life easier for Windows users since they no longer have to install anything. Ideally, we'd only keep producing one format, so we might drop the .gz version in the future.

There's also the alternative to produce .tar.gz everywhere (Windows can extract those, at least from the command line), but IMHO that's the worse format, perpetuated only because of historical reasons.

If you're maintaining a client that can automatically download rust-analyzer, consider leaving a comment on #13876 regarding your preferred format.

#13848 adds a client capability colorDiagnosticOutput to declare that a client is capable of rendering the "full compiler diagnostic" with ANSI color and style codes. VSCode is probably the only client using this for now. The docs have been updated as part of that PR as well.

#14141 adds support for positionEncoding = "utf-32", in addition to utf-8 and utf-16 which we support since forever.

#11557 adds a viewTree which allows to navigate through project dependencies

#14662 adds support for locally built documentation

#15081 adds support for a memory layout viewer.

#15876 allows a single TextDocumentEdit to have multiple SnippetTextEdits.

#15979 adds commands for running selected tests

There's a recent change introducing the "Unindexed Project" notification. I think @davidbarsky forgot to mention it here. However, it is not clear to me what are the linkedProjects and how should the client determine the owner. Can you, David, explain this feature in more details? Thank you.

#16662 adds a set of lsp extension for supporting the vscode test explorer. If your client has a similar feature for exploring tests, you may find it useful. There are probably some problems around the lsp extension, or it may be too overfitted to the vscode, please raise an issue in those cases.

#16773 puts the test explorer behind a testExplorer capability, note that the lsp extension is likely to still change

#16840 by @Wilfred is a pending PR that allows rust-project.json to include arbitrary shell commands for runnables

Although lsp-extensions.md hasn't been updated, commit 18ca22a extended ServerStatusParams with a new field called workspaceInfo.

Although lsp-extensions.md hasn't been updated, commit 18ca22a extended ServerStatusParams with a new field called workspaceInfo.

#17287 removes this again as it feels out of place for the status notification. (I didn't post about it here when adding it because I was mainly experimenting, should've made that clear from the start)

Commit ef59b49 by @roife extended the args of Runnable with an optional cwd field for the cargo kind. It seems cwd sould be used instead of workspaceRoot when it is present.

On the other hand, the log of commit a55e8bf has this sentence: "When the kind of runnable is bin", but according to the docs, kind can only be cargo.

roife commented

On the other hand, the log of commit a55e8bf has this sentence: "When the kind of runnable is bin", but according to the docs, kind can only be cargo.

There was some ambiguity regarding the term kind due to my previous lack of clarity. In this context, kind refers to ide::Runnable.kind, which is of type RunnableKind (can be Test, Bin, Bench, etc.), is used internally within r-a.

The kind you mentioned refers to rust_analyzer::lsp_ext::Runnable.kind, which is of type rust_analyzer::lsp_ext::RunnableKind (and can only be cargo), is used for responses sent to the client.

#16840 added runnable support to rust-project.json. I'll create a PR to update the manual, but the newly added rustdocs on project_json.rs will are a reasonable starting point for the new behavior.

#17547 changes the runnable payload, notably it now has an environment field for env vars to be set, always sents a cwd working directory that a client should honor, gets rid of cargoExtraArgs and bakes that into cargoArgs (as there is no need for the client to do this) and drops the expectTest field in favor of the env var field.

joshka commented

#17587 adds a rust-analyzer.rename command that triggers the editor.action.rename. This allows extract symbols assists to cause the editor to prompt the user to rename the newly extracted symbol in place.

Heads up, #17647 changes two command names. This is unfortunately a breaking change but the previous names were accidentally plainly copied from VSCode whereas they should've been more rust-analyzer specific

joshka commented

Heads up, #17647 changes two command names. This is unfortunately a breaking change but the previous names were accidentally plainly copied from VSCode whereas they should've been more rust-analyzer specific

To save the extra click (and make this thread searchable for changes in the future):

The commands editor.action.triggerParameterHints and
editor.action.rename are now renamed to
rust-analyzer.triggerParameterHints and rust-analyzer.rename

#18412 disabled the generation of .gz binary artifacts for Windows. If your client downloads rust-analyzer from GitHub, you should switch to the .zip ones.

We might make a similar change to the Linux ones in the future.

#18813 by @Giga-Bowser added rust-analyzer/viewSyntaxTree and removed rust-analyzer/syntaxTree.