mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 13:48:50 +00:00
better user docs
This commit is contained in:
parent
206bbe9c93
commit
192a5cd11d
2 changed files with 210 additions and 206 deletions
|
@ -1,3 +1,22 @@
|
|||
The main interface to rust-analyzer is the
|
||||
[LSP](https://microsoft.github.io/language-server-protocol/) implementation. To
|
||||
install lsp server, use `cargo install-lsp`, which is a shorthand for `cargo
|
||||
install --package ra_lsp_server`. The binary is named `ra_lsp_server`, you
|
||||
should be able to use it with any LSP-compatible editor. We use custom
|
||||
extensions to LSP, so special client-side support is required to take full
|
||||
advantage of rust-analyzer. This repository contains support code for VS Code
|
||||
and Emacs.
|
||||
|
||||
Rust Analyzer needs sources of rust standard library to work, so you might need
|
||||
to execute
|
||||
|
||||
```
|
||||
$ rustup component add rust-src
|
||||
```
|
||||
|
||||
See [./features.md] document for a list of features that are available.
|
||||
|
||||
## VS Code
|
||||
|
||||
Prerequisites:
|
||||
|
||||
|
@ -15,227 +34,44 @@ following commands:
|
|||
$ git clone https://github.com/rust-analyzer/rust-analyzer.git --depth 1
|
||||
$ cd rust-analyzer
|
||||
$ cargo install-code
|
||||
|
||||
# for stdlib support
|
||||
$ rustup component add rust-src
|
||||
```
|
||||
|
||||
This will run `cargo install --package ra_lsp_server` to install the server
|
||||
binary into `~/.cargo/bin`, and then will build and install plugin from
|
||||
`editors/code`. See
|
||||
[this](https://github.com/rust-analyzer/rust-analyzer/blob/0199572a3d06ff66eeae85a2d2c9762996f0d2d8/crates/tools/src/main.rs#L150)
|
||||
[this](https://github.com/rust-analyzer/rust-analyzer/blob/69ee5c9c5ef212f7911028c9ddf581559e6565c3/crates/tools/src/main.rs#L37-L56)
|
||||
for details. The installation is expected to *just work*, if it doesn't, report
|
||||
bugs!
|
||||
|
||||
It's better to remove existing Rust plugins to avoid interference.
|
||||
|
||||
## Rust Analyzer Specific Features
|
||||
Beyond basic LSP features, there are some extension commands which you can
|
||||
invoke via <kbd>Ctrl+Shift+P</kbd> or bind to a shortcut. See [./features.md]
|
||||
for details.
|
||||
|
||||
These features are implemented as extensions to the language server protocol.
|
||||
They are more experimental in nature and work only with VS Code.
|
||||
### Settings
|
||||
|
||||
### Syntax highlighting
|
||||
|
||||
It overrides built-in highlighting, and works only with a specific theme
|
||||
(zenburn). `rust-analyzer.highlightingOn` setting can be used to disable it.
|
||||
|
||||
### Go to symbol in workspace <kbd>ctrl+t</kbd>
|
||||
|
||||
It mostly works on top of the built-in LSP functionality, however `#` and `*`
|
||||
symbols can be used to narrow down the search. Specifically,
|
||||
|
||||
- `#Foo` searches for `Foo` type in the current workspace
|
||||
- `#foo#` searches for `foo` function in the current workspace
|
||||
- `#Foo*` searches for `Foo` type among dependencies, excluding `stdlib`
|
||||
- `#foo#*` searches for `foo` function among dependencies.
|
||||
|
||||
That is, `#` switches from "types" to all symbols, `*` switches from the current
|
||||
workspace to dependencies.
|
||||
|
||||
### Commands <kbd>ctrl+shift+p</kbd>
|
||||
|
||||
#### Show Rust Syntax Tree
|
||||
|
||||
Shows the parse tree of the current file. It exists mostly for debugging
|
||||
rust-analyzer itself.
|
||||
|
||||
#### Extend Selection
|
||||
|
||||
Extends the current selection to the encompassing syntactic construct
|
||||
(expression, statement, item, module, etc). It works with multiple cursors. Do
|
||||
bind this command to a key, its super-useful! Expected to be upstreamed to LSP soonish:
|
||||
https://github.com/Microsoft/language-server-protocol/issues/613
|
||||
|
||||
#### Matching Brace
|
||||
|
||||
If the cursor is on any brace (`<>(){}[]`) which is a part of a brace-pair,
|
||||
moves cursor to the matching brace. It uses the actual parser to determine
|
||||
braces, so it won't confuse generics with comparisons.
|
||||
|
||||
#### Parent Module
|
||||
|
||||
Navigates to the parent module of the current module.
|
||||
|
||||
#### Join Lines
|
||||
|
||||
Join selected lines into one, smartly fixing up whitespace and trailing commas.
|
||||
|
||||
#### Run
|
||||
|
||||
Shows popup suggesting to run a test/benchmark/binary **at the current cursor
|
||||
location**. Super useful for repeatedly running just a single test. Do bind this
|
||||
to a shortcut!
|
||||
* `rust-analyzer.highlightingOn`: enables experimental syntax highlighting
|
||||
* `rust-analyzer.showWorkspaceLoadedNotification`: to ease troubleshooting, a
|
||||
notification is shown by default when a workspace is loaded
|
||||
* `rust-analyzer.enableEnhancedTyping`: by default, rust-analyzer intercepts
|
||||
`Enter` key to make it easier to continue comments
|
||||
* `rust-analyzer.raLspServerPath`: path to `ra_lsp_server` executable
|
||||
* `rust-analyzer.enableCargoWatchOnStartup`: prompt to install & enable `cargo
|
||||
watch` for live error highlighting (note, this **does not** use rust-analyzer)
|
||||
* `rust-analyzer.trace.server`: enables internal logging
|
||||
|
||||
|
||||
### On Typing Assists
|
||||
## Emacs
|
||||
|
||||
Some features trigger on typing certain characters:
|
||||
Prerequisites:
|
||||
|
||||
- typing `let =` tries to smartly add `;` if `=` is followed by an existing expression.
|
||||
- Enter inside comments automatically inserts `///`
|
||||
- typing `.` in a chain method call auto-indents
|
||||
`emacs-lsp`, `dash` and `ht` packages.
|
||||
|
||||
Installation:
|
||||
|
||||
### Code Actions (Assists)
|
||||
|
||||
These are triggered in a particular context via light bulb. We use custom code on
|
||||
the VS Code side to be able to position cursor.
|
||||
|
||||
|
||||
- Flip `,`
|
||||
|
||||
```rust
|
||||
// before:
|
||||
fn foo(x: usize,<|> dim: (usize, usize))
|
||||
// after:
|
||||
fn foo(dim: (usize, usize), x: usize)
|
||||
```
|
||||
|
||||
- Add `#[derive]`
|
||||
|
||||
```rust
|
||||
// before:
|
||||
struct Foo {
|
||||
<|>x: i32
|
||||
}
|
||||
// after:
|
||||
#[derive(<|>)]
|
||||
struct Foo {
|
||||
x: i32
|
||||
}
|
||||
```
|
||||
|
||||
- Add `impl`
|
||||
|
||||
```rust
|
||||
// before:
|
||||
struct Foo<'a, T: Debug> {
|
||||
<|>t: T
|
||||
}
|
||||
// after:
|
||||
struct Foo<'a, T: Debug> {
|
||||
t: T
|
||||
}
|
||||
|
||||
impl<'a, T: Debug> Foo<'a, T> {
|
||||
<|>
|
||||
}
|
||||
```
|
||||
|
||||
- Change visibility
|
||||
|
||||
```rust
|
||||
// before:
|
||||
fn<|> foo() {}
|
||||
|
||||
// after
|
||||
pub(crate) fn foo() {}
|
||||
```
|
||||
|
||||
- Introduce variable:
|
||||
|
||||
```rust
|
||||
// before:
|
||||
fn foo() {
|
||||
foo(<|>1 + 1<|>);
|
||||
}
|
||||
|
||||
// after:
|
||||
fn foo() {
|
||||
let var_name = 1 + 1;
|
||||
foo(var_name);
|
||||
}
|
||||
```
|
||||
|
||||
- Replace if-let with match:
|
||||
|
||||
```rust
|
||||
// before:
|
||||
impl VariantData {
|
||||
pub fn is_struct(&self) -> bool {
|
||||
if <|>let VariantData::Struct(..) = *self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// after:
|
||||
impl VariantData {
|
||||
pub fn is_struct(&self) -> bool {
|
||||
<|>match *self {
|
||||
VariantData::Struct(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- Split import
|
||||
|
||||
```rust
|
||||
// before:
|
||||
use algo:<|>:visitor::{Visitor, visit};
|
||||
//after:
|
||||
use algo::{<|>visitor::{Visitor, visit}};
|
||||
```
|
||||
|
||||
## LSP features
|
||||
|
||||
* **Go to definition**: works correctly for local variables and some paths,
|
||||
falls back to heuristic name matching for other things for the time being.
|
||||
|
||||
* **Completion**: completes paths, including dependencies and standard library.
|
||||
Does not handle glob imports and macros. Completes fields and inherent
|
||||
methods.
|
||||
|
||||
* **Outline** <kbd>alt+shift+o</kbd>
|
||||
|
||||
* **Signature Info**
|
||||
|
||||
* **Format document**. Formats the current file with rustfmt. Rustfmt must be
|
||||
installed separately with `rustup component add rustfmt`.
|
||||
|
||||
* **Hover** shows types of expressions and docstings
|
||||
|
||||
* **Rename** works for local variables
|
||||
|
||||
* **Code Lens** for running tests
|
||||
|
||||
* **Folding**
|
||||
|
||||
* **Diagnostics**
|
||||
- missing module for `mod foo;` with a fix to create `foo.rs`.
|
||||
- struct field shorthand
|
||||
- unnecessary braces in use item
|
||||
|
||||
|
||||
## Performance
|
||||
|
||||
Rust Analyzer is expected to be pretty fast. Specifically, the initial analysis
|
||||
of the project (i.e, when you first invoke completion or symbols) typically
|
||||
takes dozen of seconds at most. After that, everything is supposed to be more or
|
||||
less instant. However currently all analysis results are kept in memory, so
|
||||
memory usage is pretty high. Working with `rust-lang/rust` repo, for example,
|
||||
needs about 5 gigabytes of ram.
|
||||
* add
|
||||
[ra-emacs-lsp.el](https://github.com/rust-analyzer/rust-analyzer/blob/69ee5c9c5ef212f7911028c9ddf581559e6565c3/editors/emacs/ra-emacs-lsp.el)
|
||||
to load path and require it in `init.el`
|
||||
* run `lsp` in a rust buffer
|
||||
* (Optionally) bind commands like `join-lines` or `extend-selection` to keys
|
||||
|
|
168
docs/user/features.md
Normal file
168
docs/user/features.md
Normal file
|
@ -0,0 +1,168 @@
|
|||
This documents is an index of features that rust-analyzer language server provides.
|
||||
|
||||
### Go to symbol in workspace <kbd>ctrl+t</kbd>
|
||||
|
||||
It mostly works on top of the built-in LSP functionality, however `#` and `*`
|
||||
symbols can be used to narrow down the search. Specifically,
|
||||
|
||||
- `#Foo` searches for `Foo` type in the current workspace
|
||||
- `#foo#` searches for `foo` function in the current workspace
|
||||
- `#Foo*` searches for `Foo` type among dependencies, excluding `stdlib`
|
||||
- `#foo#*` searches for `foo` function among dependencies.
|
||||
|
||||
That is, `#` switches from "types" to all symbols, `*` switches from the current
|
||||
workspace to dependencies.
|
||||
|
||||
### Commands <kbd>ctrl+shift+p</kbd>
|
||||
|
||||
#### Show Rust Syntax Tree
|
||||
|
||||
Shows the parse tree of the current file. It exists mostly for debugging
|
||||
rust-analyzer itself.
|
||||
|
||||
#### Extend Selection
|
||||
|
||||
Extends the current selection to the encompassing syntactic construct
|
||||
(expression, statement, item, module, etc). It works with multiple cursors. Do
|
||||
bind this command to a key, its super-useful! Expected to be upstreamed to LSP soonish:
|
||||
https://github.com/Microsoft/language-server-protocol/issues/613
|
||||
|
||||
#### Matching Brace
|
||||
|
||||
If the cursor is on any brace (`<>(){}[]`) which is a part of a brace-pair,
|
||||
moves cursor to the matching brace. It uses the actual parser to determine
|
||||
braces, so it won't confuse generics with comparisons.
|
||||
|
||||
#### Parent Module
|
||||
|
||||
Navigates to the parent module of the current module.
|
||||
|
||||
#### Join Lines
|
||||
|
||||
Join selected lines into one, smartly fixing up whitespace and trailing commas.
|
||||
|
||||
#### Run
|
||||
|
||||
Shows popup suggesting to run a test/benchmark/binary **at the current cursor
|
||||
location**. Super useful for repeatedly running just a single test. Do bind this
|
||||
to a shortcut!
|
||||
|
||||
|
||||
### On Typing Assists
|
||||
|
||||
Some features trigger on typing certain characters:
|
||||
|
||||
- typing `let =` tries to smartly add `;` if `=` is followed by an existing expression.
|
||||
- Enter inside comments automatically inserts `///`
|
||||
- typing `.` in a chain method call auto-indents
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Code Actions (Assists)
|
||||
|
||||
These are triggered in a particular context via light bulb. We use custom code on
|
||||
the VS Code side to be able to position cursor.
|
||||
|
||||
|
||||
- Flip `,`
|
||||
|
||||
```rust
|
||||
// before:
|
||||
fn foo(x: usize,<|> dim: (usize, usize))
|
||||
// after:
|
||||
fn foo(dim: (usize, usize), x: usize)
|
||||
```
|
||||
|
||||
- Add `#[derive]`
|
||||
|
||||
```rust
|
||||
// before:
|
||||
struct Foo {
|
||||
<|>x: i32
|
||||
}
|
||||
// after:
|
||||
#[derive(<|>)]
|
||||
struct Foo {
|
||||
x: i32
|
||||
}
|
||||
```
|
||||
|
||||
- Add `impl`
|
||||
|
||||
```rust
|
||||
// before:
|
||||
struct Foo<'a, T: Debug> {
|
||||
<|>t: T
|
||||
}
|
||||
// after:
|
||||
struct Foo<'a, T: Debug> {
|
||||
t: T
|
||||
}
|
||||
|
||||
impl<'a, T: Debug> Foo<'a, T> {
|
||||
<|>
|
||||
}
|
||||
```
|
||||
|
||||
- Change visibility
|
||||
|
||||
```rust
|
||||
// before:
|
||||
fn<|> foo() {}
|
||||
|
||||
// after
|
||||
pub(crate) fn foo() {}
|
||||
```
|
||||
|
||||
- Introduce variable:
|
||||
|
||||
```rust
|
||||
// before:
|
||||
fn foo() {
|
||||
foo(<|>1 + 1<|>);
|
||||
}
|
||||
|
||||
// after:
|
||||
fn foo() {
|
||||
let var_name = 1 + 1;
|
||||
foo(var_name);
|
||||
}
|
||||
```
|
||||
|
||||
- Replace if-let with match:
|
||||
|
||||
```rust
|
||||
// before:
|
||||
impl VariantData {
|
||||
pub fn is_struct(&self) -> bool {
|
||||
if <|>let VariantData::Struct(..) = *self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// after:
|
||||
impl VariantData {
|
||||
pub fn is_struct(&self) -> bool {
|
||||
<|>match *self {
|
||||
VariantData::Struct(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- Split import
|
||||
|
||||
```rust
|
||||
// before:
|
||||
use algo:<|>:visitor::{Visitor, visit};
|
||||
//after:
|
||||
use algo::{<|>visitor::{Visitor, visit}};
|
||||
```
|
||||
|
||||
|
Loading…
Reference in a new issue