:source-highlighter: rouge
:experimental:
-// Master copy of this document lives in the https://github.com/rust-analyzer/rust-analyzer repository
-
At its core, rust-analyzer is a *library* for semantic analysis of Rust code as it changes over time.
This manual focuses on a specific usage of the library -- running it as part of a server that implements the
https://microsoft.github.io/language-server-protocol/[Language Server Protocol] (LSP).
https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/manual.adoc[https://github.com/rust-analyzer/.../manual.adoc]
The manual is written in https://asciidoc.org[AsciiDoc] and includes some extra files which are generated from the source code. Run `cargo test` and `cargo test -p xtask` to create these and then `asciidoctor manual.adoc` to create an HTML copy.
-
====
If you have questions about using rust-analyzer, please ask them in the https://users.rust-lang.org/c/ide/14["`IDEs and Editors`"] topic of Rust users forum.
$ cargo xtask install --server
----
-==== Troubleshooting
-
-Here are some useful self-diagnostic commands:
-
-* **Rust Analyzer: Show RA Version** shows the version of `rust-analyzer` binary.
-* **Rust Analyzer: Status** prints some statistics about the server, and dependency information for the current file.
-* To enable server-side logging, run with `env RA_LOG=info` and see `Output > Rust Analyzer Language Server` in VS Code's panel.
-* To log project loading (sysroot & `cargo metadata`), set `RA_LOG=project_model=debug`.
-* To log all LSP requests, add `"rust-analyzer.trace.server": "verbose"` to the settings and look for `Rust Analyzer Language Server Trace` in the panel.
-* To enable client-side logging, add `"rust-analyzer.trace.extension": true` to the settings and open `Output > Rust Analyzer Client` in the panel.
-
=== rust-analyzer Language Server Binary
Other editors generally require the `rust-analyzer` binary to be in `$PATH`.
==== YouCompleteMe
-1. Install YouCompleteMe by following the instructions
- https://github.com/ycm-core/lsp-examples#rust-rust-analyzer[here]
+Install YouCompleteMe by following the instructions
+ https://github.com/ycm-core/YouCompleteMe#installation[here].
-2. Configure by adding this to your vim/neovim config file (replacing the existing Rust-specific line if it exists):
-+
-[source,vim]
-----
-let g:ycm_language_server =
-\ [
-\ {
-\ 'name': 'rust',
-\ 'cmdline': ['rust-analyzer'],
-\ 'filetypes': ['rust'],
-\ 'project_root_files': ['Cargo.toml']
-\ }
-\ ]
-----
+rust-analyzer is the default in ycm, it should work out of the box.
==== ALE
settings = {
["rust-analyzer"] = {
assist = {
- importMergeBehavior = "last",
+ importGranularity = "module",
importPrefix = "by_self",
},
cargo = {
If `rust-analyzer` is not detected, Corrosion will prompt you for configuration of your Rust toolchain and language server with a link to the __Window > Preferences > Rust__ preference page; from here a button allows to download and configure `rust-analyzer`, but you can also reference another installation.
You'll need to close and reopen all .rs and Cargo files, or to restart the IDE, for this change to take effect.
+=== Kate Text Editor
+
+Support for the language server protocol is built into Kate through the LSP plugin, which is included by default.
+It is preconfigured to use Rls for rust sources, but allows you to use rust-analyzer through a simple settings change.
+In the LSP Client settings of Kate, copy the content of the third tab "default parameters" to the second tab "server configuration".
+Then in the configuration replace:
+[source,json]
+----
+ "rust": {
+ "command": ["rls"],
+ "rootIndicationFileNames": ["Cargo.lock", "Cargo.toml"],
+ "url": "https://github.com/rust-lang/rls",
+ "highlightingModeRegex": "^Rust$"
+ },
+----
+With
+[source,json]
+----
+ "rust": {
+ "command": ["rust-analyzer"],
+ "rootIndicationFileNames": ["Cargo.lock", "Cargo.toml"],
+ "url": "https://github.com/rust-analyzer/rust-analyzer",
+ "highlightingModeRegex": "^Rust$"
+ },
+----
+Then click on apply, and restart the LSP server for your rust project.
+
+== Troubleshooting
+
+Start with looking at the rust-analyzer version.
+Try **Rust Analyzer: Show RA Version** in VS Code and `rust-analyzer --version` in the command line.
+If the date is more than a week ago, it's better to update rust-analyzer version.
+
+The next thing to check would be panic messages in rust-analyzer's log.
+Log messages are printed to stderr, in VS Code you can see then in the `Output > Rust Analyzer Language Server` tab of the panel.
+To see more logs, set `RA_LOG=info` environmental variable.
+
+To fully capture LSP messages between the editor and the server, set `"rust-analyzer.trace.server": "verbose"` config and check
+`Output > Rust Analyzer Language Server Trace`.
+
+The root cause for many "`nothing works`" problems is that rust-analyzer fails to understand the project structure.
+To debug that, first note the `rust-analyzer` section in the status bar.
+If it has an error icon and red, that's the problem (hover will have somewhat helpful error message).
+**Rust Analyzer: Status** prints dependency information for the current file.
+Finally, `RA_LOG=project_model=debug` enables verbose logs during project loading.
+
+If rust-analyzer outright crashes, try running `rust-analyzer analysis-stats /path/to/project/directory/` on the command line.
+This command type checks the whole project in batch mode bypassing LSP machinery.
+
+When filing issues, it is useful (but not necessary) to try to minimize examples.
+An ideal bug reproduction looks like this:
+
+```bash
+$ git clone https://github.com/username/repo.git && cd repo && git switch --detach commit-hash
+$ rust-analyzer --version
+rust-analyzer dd12184e4 2021-05-08 dev
+$ rust-analyzer analysis-stats .
+💀 💀 💀
+```
+
+It is especially useful when the `repo` doesn't use external crates or the standard library.
+
== Configuration
**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/rust-analyzer/src/config.rs[config.rs]
[source,TypeScript]
----
interface JsonProject {
- /// Path to the directory with *source code* of sysroot crates.
+ /// Path to the directory with *source code* of
+ /// sysroot crates.
+ ///
+ /// It should point to the directory where std,
+ /// core, and friends can be found:
///
- /// It should point to the directory where std, core, and friends can be found:
/// https://github.com/rust-lang/rust/tree/master/library.
///
- /// If provided, rust-analyzer automatically adds dependencies on sysroot
- /// crates. Conversely, if you omit this path, you can specify sysroot
- /// dependencies yourself and, for example, have several different "sysroots" in
- /// one graph of crates.
+ /// If provided, rust-analyzer automatically adds
+ /// dependencies on sysroot crates. Conversely,
+ /// if you omit this path, you can specify sysroot
+ /// dependencies yourself and, for example, have
+ /// several different "sysroots" in one graph of
+ /// crates.
sysroot_src?: string;
- /// The set of crates comprising the current project.
- /// Must include all transitive dependencies as well as sysroot crate (libstd, libcore and such).
+ /// The set of crates comprising the current
+ /// project. Must include all transitive
+ /// dependencies as well as sysroot crate (libstd,
+ /// libcore and such).
crates: Crate[];
}
interface Crate {
- /// Optional crate name used for display purposes, without affecting semantics.
- /// See the `deps` key for semantically-significant crate names.
+ /// Optional crate name used for display purposes,
+ /// without affecting semantics. See the `deps`
+ /// key for semantically-significant crate names.
display_name?: string;
/// Path to the root module of the crate.
root_module: string;
edition: "2015" | "2018" | "2021";
/// Dependencies
deps: Dep[];
- /// Should this crate be treated as a member of current "workspace".
+ /// Should this crate be treated as a member of
+ /// current "workspace".
///
- /// By default, inferred from the `root_module` (members are the crates which reside
- /// inside the directory opened in the editor).
+ /// By default, inferred from the `root_module`
+ /// (members are the crates which reside inside
+ /// the directory opened in the editor).
///
- /// Set this to `false` for things like standard library and 3rd party crates to
- /// enable performance optimizations (rust-analyzer assumes that non-member crates
- /// don't change).
+ /// Set this to `false` for things like standard
+ /// library and 3rd party crates to enable
+ /// performance optimizations (rust-analyzer
+ /// assumes that non-member crates don't change).
is_workspace_member?: boolean;
- /// Optionally specify the (super)set of `.rs` files comprising this crate.
+ /// Optionally specify the (super)set of `.rs`
+ /// files comprising this crate.
///
- /// By default, rust-analyzer assumes that only files under `root_module.parent` can belong to a crate.
- /// `include_dirs` are included recursively, unless a subdirectory is in `exclude_dirs`.
+ /// By default, rust-analyzer assumes that only
+ /// files under `root_module.parent` can belong
+ /// to a crate. `include_dirs` are included
+ /// recursively, unless a subdirectory is in
+ /// `exclude_dirs`.
///
/// Different crates can share the same `source`.
///
- /// If two crates share an `.rs` file in common, they *must* have the same `source`.
- /// rust-analyzer assumes that files from one source can't refer to files in another source.
+ /// If two crates share an `.rs` file in common,
+ /// they *must* have the same `source`.
+ /// rust-analyzer assumes that files from one
+ /// source can't refer to files in another source.
source?: {
include_dirs: string[],
exclude_dirs: string[],
},
- /// The set of cfgs activated for a given crate, like `["unix", "feature=\"foo\"", "feature=\"bar\""]`.
+ /// The set of cfgs activated for a given crate, like
+ /// `["unix", "feature=\"foo\"", "feature=\"bar\""]`.
cfg: string[];
/// Target triple for this Crate.
///
- /// Used when running `rustc --print cfg` to get target-specific cfgs.
+ /// Used when running `rustc --print cfg`
+ /// to get target-specific cfgs.
target?: string;
- /// Environment variables, used for the `env!` macro
+ /// Environment variables, used for
+ /// the `env!` macro
env: : { [key: string]: string; },
- /// For proc-macro crates, path to compiles proc-macro (.so file).
+ /// For proc-macro crates, path to compiled
+ /// proc-macro (.so file).
proc_macro_dylib_path?: string;
}
interface Dep {
/// Index of a crate in the `crates` array.
crate: number,
- /// Name as should appear in the (implicit) `extern crate name` declaration.
+ /// Name as should appear in the (implicit)
+ /// `extern crate name` declaration.
name: string,
}
----
* proc macros and build scripts are executed by default
* `.cargo/config` can override `rustc` with an arbitrary executable
+* `rust-toolchain.toml` can override `rustc` with an arbitrary executable
* VS Code plugin reads configuration from project directory, and that can be used to override paths to various executables, like `rustfmt` or `rust-analyzer` itself.
* rust-analyzer's syntax trees library uses a lot of `unsafe` and hasn't been properly audited for memory safety.
== Diagnostics
While most errors and warnings provided by rust-analyzer come from the `cargo check` integration, there's a growing number of diagnostics implemented using rust-analyzer's own analysis.
-These diagnostics don't respect `#[allow]` or `#[deny]` attributes yet, but can be turned off using the `rust-analyzer.diagnostics.enable`, `rust-analyzer.diagnostics.enableExperimental` or `rust-analyzer.diagnostics.disabled` settings.
+Some of these diagnostics don't respect `\#[allow]` or `\#[deny]` attributes yet, but can be turned off using the `rust-analyzer.diagnostics.enable`, `rust-analyzer.diagnostics.enableExperimental` or `rust-analyzer.diagnostics.disabled` settings.
include::./generated_diagnostic.adoc[]
}
----
+Most themes doesn't support styling unsafe operations differently yet. You can fix this by adding overrides for the rules `operator.unsafe`, `function.unsafe`, and `method.unsafe`:
+
+[source,jsonc]
+----
+{
+ "editor.semanticTokenColorCustomizations": {
+ "rules": {
+ "operator.unsafe": "#ff6600",
+ "function.unsafe": "#ff6600"
+ "method.unsafe": "#ff6600"
+ }
+ },
+}
+----
+
+In addition to the top-level rules you can specify overrides for specific themes. For example, if you wanted to use a darker text color on a specific light theme, you might write:
+
+[source,jsonc]
+----
+{
+ "editor.semanticTokenColorCustomizations": {
+ "rules": {
+ "operator.unsafe": "#ff6600"
+ },
+ "[Ayu Light]": {
+ "rules": {
+ "operator.unsafe": "#572300"
+ }
+ }
+ },
+}
+----
+
+Make sure you include the brackets around the theme name. For example, use `"[Ayu Light]"` to customize the theme Ayu Light.
+
==== Special `when` clause context for keybindings.
You may use `inRustProject` context to configure keybindings for rust projects only.
For example: