diff options
-rw-r--r-- | README.md | 76 | ||||
-rw-r--r-- | editors/README.md | 221 |
2 files changed, 199 insertions, 98 deletions
@@ -2,15 +2,13 @@ | |||
2 | 2 | ||
3 | [![Build Status](https://travis-ci.org/rust-analyzer/rust-analyzer.svg?branch=master)](https://travis-ci.org/rust-analyzer/rust-analyzer) | 3 | [![Build Status](https://travis-ci.org/rust-analyzer/rust-analyzer.svg?branch=master)](https://travis-ci.org/rust-analyzer/rust-analyzer) |
4 | 4 | ||
5 | Rust Analyzer is an **experimental** modular compiler frontend for the | 5 | Rust Analyzer is an **experimental** modular compiler frontend for the Rust |
6 | Rust language, which aims to lay a foundation for excellent IDE | 6 | language, which aims to lay a foundation for excellent IDE support. |
7 | support. | ||
8 | 7 | ||
9 | It doesn't implement much of compiler functionality yet, but the | 8 | It doesn't implement much of compiler functionality yet, but the white-space |
10 | white-space preserving Rust parser works, and there are significant | 9 | preserving Rust parser works, and there are significant chunks of overall |
11 | chunks of overall architecture (indexing, on-demand & lazy | 10 | architecture (indexing, on-demand & lazy computation, snapshotable world view) |
12 | computation, snapshotable world view) in place. Some basic IDE | 11 | in place. Some basic IDE functionality is provided via a language server. |
13 | functionality is provided via a language server. | ||
14 | 12 | ||
15 | Work on the Rust Analyzer is sponsored by | 13 | Work on the Rust Analyzer is sponsored by |
16 | 14 | ||
@@ -30,53 +28,45 @@ $ cargo run --package ra_cli parse < crates/ra_syntax/src/lib.rs | |||
30 | 28 | ||
31 | # show symbols of a Rust file | 29 | # show symbols of a Rust file |
32 | $ cargo run --package ra_cli symbols < crates/ra_syntax/src/lib.rs | 30 | $ cargo run --package ra_cli symbols < crates/ra_syntax/src/lib.rs |
33 | ``` | ||
34 | 31 | ||
35 | To try out the language server, see [these | 32 | # install the language server |
36 | instructions](./editors/README.md). Please note that the server is not | 33 | $ cargo install --path crates/ra_lsp_server |
37 | ready for general use yet. If you are looking for a Rust IDE that | 34 | ``` |
38 | works, use [IntelliJ | ||
39 | Rust](https://github.com/intellij-rust/intellij-rust) or | ||
40 | [RLS](https://github.com/rust-lang-nursery/rls). That being said, the | ||
41 | basic stuff works, and rust analyzer is developed in the rust analyzer | ||
42 | powered editor. | ||
43 | 35 | ||
36 | See [these instructions](./editors/README.md) for VS Code setup and the list of | ||
37 | features (some of which are VS Code specific). | ||
44 | 38 | ||
45 | ## Current Status and Plans | 39 | ## Current Status and Plans |
46 | 40 | ||
47 | Rust analyzer aims to fill the same niche as the official [Rust | 41 | Rust analyzer aims to fill the same niche as the official [Rust Language |
48 | Language Server](https://github.com/rust-lang-nursery/rls), but uses a | 42 | Server](https://github.com/rust-lang-nursery/rls), but uses a significantly |
49 | significantly different architecture. More details can be found [in | 43 | different architecture. More details can be found [in this |
50 | this | ||
51 | thread](https://internals.rust-lang.org/t/2019-strategy-for-rustc-and-the-rls/8361), | 44 | thread](https://internals.rust-lang.org/t/2019-strategy-for-rustc-and-the-rls/8361), |
52 | but the core issue is that RLS works in the "wait until user stops | 45 | but the core issue is that RLS works in the "wait until user stops typing, run |
53 | typing, run the build process, save the results of the analysis" mode, | 46 | the build process, save the results of the analysis" mode, which arguably is the |
54 | which arguably is the wrong foundation for IDE. | 47 | wrong foundation for IDE. |
55 | 48 | ||
56 | Rust Analyzer is a hobby project at the moment, there's exactly zero | 49 | Rust Analyzer is an experimental project at the moment, there's exactly zero |
57 | guarantees that it becomes production-ready one day. | 50 | guarantees that it becomes production-ready one day. |
58 | 51 | ||
59 | The near/mid term plan is to work independently of the main rustc | 52 | The near/mid term plan is to work independently of the main rustc compiler and |
60 | compiler and implement at least simplistic versions of name | 53 | implement at least simplistic versions of name resolution, macro expansion and |
61 | resolution, macro expansion and type inference. The purpose is two | 54 | type inference. The purpose is two fold: |
62 | fold: | ||
63 | 55 | ||
64 | * to quickly bootstrap usable and useful language server: solution | 56 | * to quickly bootstrap usable and useful language server: solution that covers |
65 | that covers 80% of Rust code will be useful for IDEs, and will be | 57 | 80% of Rust code will be useful for IDEs, and will be vastly simpler than 100% |
66 | vastly simpler than 100% solution. | 58 | solution. |
67 | 59 | ||
68 | * to understand how the consumer-side of compiler API should look like | 60 | * to understand how the consumer-side of compiler API should look like |
69 | (especially it's on-demand aspects). If you have | 61 | (especially it's on-demand aspects). If you have `get_expression_type` |
70 | `get_expression_type` function, you can write a ton of purely-IDE | 62 | function, you can write a ton of purely-IDE features on top of it, even if the |
71 | features on top of it, even if the function is only partially | 63 | function is only partially correct. Pluging in the precise function afterwards |
72 | correct. Plugin in the precise function afterwards should just make | 64 | should just make IDE features more reliable. |
73 | IDE features more reliable. | 65 | |
74 | 66 | The long term plan is to merge with the mainline rustc compiler, probably around | |
75 | The long term plan is to merge with the mainline rustc compiler, | 67 | the HIR boundary? That is, use rust analyzer for parsing, macro expansion and |
76 | probably around the HIR boundary? That is, use rust analyzer for | 68 | related bits of name resolution, but leave the rest (including type inference |
77 | parsing, macro expansion and related bits of name resolution, but | 69 | and trait selection) to the existing rustc. |
78 | leave the rest (including type inference and trait selection) to the | ||
79 | existing rustc. | ||
80 | 70 | ||
81 | ## Getting in touch | 71 | ## Getting in touch |
82 | 72 | ||
diff --git a/editors/README.md b/editors/README.md index 5b09750e6..9ed65e631 100644 --- a/editors/README.md +++ b/editors/README.md | |||
@@ -4,72 +4,96 @@ To install experimental VS Code plugin: | |||
4 | $ git clone https://github.com/rust-analyzer/rust-analyzer.git --depth 1 | 4 | $ git clone https://github.com/rust-analyzer/rust-analyzer.git --depth 1 |
5 | $ cd rust-analyzer | 5 | $ cd rust-analyzer |
6 | $ cargo install-code | 6 | $ cargo install-code |
7 | |||
8 | # for stdlib support | ||
9 | $ rustup component add rust-src | ||
7 | ``` | 10 | ``` |
8 | 11 | ||
9 | This will run `cargo install --packge ra_lsp_server` to install the | 12 | This will run `cargo install --packge ra_lsp_server` to install the server |
10 | server binary into `~/.cargo/bin`, and then will build and install | 13 | binary into `~/.cargo/bin`, and then will build and install plugin from |
11 | plugin from `editors/code`. See | 14 | `editors/code`. See |
12 | [this](https://github.com/matklad/rust-analyzer/blob/cc76b0d31d8ba013c499dd3a4ca69b37004795e6/crates/tools/src/main.rs#L192) | 15 | [this](https://github.com/rust-analyzer/rust-analyzer/blob/0199572a3d06ff66eeae85a2d2c9762996f0d2d8/crates/tools/src/main.rs#L150) |
13 | for details | 16 | for details. The installation is expected to *just work*, if it doesn't, report |
17 | bugs! | ||
14 | 18 | ||
15 | It's better to remove existing Rust plugins to avoid interference. | 19 | It's better to remove existing Rust plugins to avoid interference. |
16 | 20 | ||
17 | ### Features: | 21 | ## Rust Analyzer Specifc Features |
18 | |||
19 | * syntax highlighting (LSP does not have API for it, so impl is hacky | ||
20 | and sometimes fall-backs to the horrible built-in highlighting) | ||
21 | |||
22 | * **Go to symbol in workspace** (`ctrl+t`) | ||
23 | - `#Foo` searches for `Foo` type in the current workspace | ||
24 | - `#foo#` searches for `foo` function in the current workspace | ||
25 | - `#Foo*` searches for `Foo` type among dependencies, excluding `stdlib` | ||
26 | - Sorry for a weired UI, neither LSP, not VSCode have any sane API for filtering! :) | ||
27 | |||
28 | * **Go to symbol in file** (`alt+shift+o`) | ||
29 | |||
30 | * **Go to definition** ("correct" for `mod foo;` decls, approximate for other things). | ||
31 | |||
32 | * commands (`ctrl+shift+p` or keybindings) | ||
33 | - **Show Rust Syntax Tree** (use it to verify that plugin works) | ||
34 | - **Rust Extend Selection**. Extends the current selection to the | ||
35 | encompassing syntactic construct (expression, statement, item, | ||
36 | module, etc). It works with multiple cursors. Do bind this command | ||
37 | to a key, its super-useful! | ||
38 | - **Rust Matching Brace**. If the cursor is on any brace | ||
39 | (`<>(){}[]`) which is a part of a brace-pair, moves cursor to the | ||
40 | matching brace. | ||
41 | - **Rust Parent Module**. Navigate to the parent module of the current module | ||
42 | - **Rust Join Lines**. Join selected lines into one, smartly fixing | ||
43 | up whitespace and trailing commas. | ||
44 | - **Run test at caret**. When cursor is inside a function marked | ||
45 | `#[test]`, this action runs this specific test. If the cursor is | ||
46 | outside of the test function, this re-runs the last test. Do bind | ||
47 | this to a shortcut! | ||
48 | - **Format document**. Formats the current file with rustfmt. | ||
49 | Rustfmt must be installed separately with `rustup component add rustfmt`. | ||
50 | |||
51 | * Typing assists | ||
52 | - typing `let =` tries to smartly add `;` if `=` is followed by an existing expression. | ||
53 | - Enter inside comments continues comment (`<|>` signifies cursor position): | ||
54 | 22 | ||
55 | ``` | 23 | These features are implemented as extensions to the langauge server protocol. |
56 | /// Docs<|> | 24 | They are more experimental in nature and work only with VS Code. |
57 | fn foo() {} | ||
58 | ``` | ||
59 | 25 | ||
60 | ``` | 26 | ### Syntax highlighting |
61 | /// Docs | 27 | |
62 | /// <|> | 28 | It overrides built-in highlighting, and works only with a specific theme |
63 | fn foo() {} | 29 | (zenburn). `ra-lsp.highlightingOn` setting can be used to disable it. |
64 | ``` | 30 | |
31 | ### Go to symbol in workspace <kbd>ctrl+t</kbd> | ||
32 | |||
33 | It mostly works on top of the built-in LSP functionality, however `#` and `*` | ||
34 | symbols can be used to narrow down the search. Specifically, | ||
35 | |||
36 | - `#Foo` searches for `Foo` type in the current workspace | ||
37 | - `#foo#` searches for `foo` function in the current workspace | ||
38 | - `#Foo*` searches for `Foo` type among dependencies, excluding `stdlib` | ||
39 | - `#foo#*` seaches for `foo` function among dependencies. | ||
40 | |||
41 | That is, `#` switches from "types" to all symbols, `*` switches from the current | ||
42 | workspace to dependencies. | ||
43 | |||
44 | ### Commands <kbd>ctrl+shift+p</kbd> | ||
45 | |||
46 | #### Show Rust Syntax Tree | ||
47 | |||
48 | Shows the parse tree of the current file. It exists mostly for debugging | ||
49 | rust-analyzer itself. | ||
50 | |||
51 | #### Extend Selection | ||
52 | |||
53 | Extends the current selection to the encompassing syntactic construct | ||
54 | (expression, statement, item, module, etc). It works with multiple cursors. Do | ||
55 | bind this command to a key, its super-useful! Expected to be upstreamed to LSP soonish: | ||
56 | https://github.com/Microsoft/language-server-protocol/issues/613 | ||
57 | |||
58 | #### Matching Brace | ||
59 | |||
60 | If the cursor is on any brace (`<>(){}[]`) which is a part of a brace-pair, | ||
61 | moves cursor to the matching brace. It uses the actual parser to determine | ||
62 | braces, so it won't confuse generics with comparisons. | ||
65 | 63 | ||
66 | * code actions (use `ctrl+.` to activate). | 64 | #### Parent Module |
67 | 65 | ||
66 | Navigates to the parent module of the current module. | ||
67 | |||
68 | #### Join Lines | ||
69 | |||
70 | Join selected lines into one, smartly fixing up whitespace and trailing commas. | ||
71 | |||
72 | #### Run | ||
73 | |||
74 | Shows popup suggesting to run a test/benchmark/binary **at the current cursor | ||
75 | location**. Super useful for repeatedly running just a single test. Do bind this | ||
76 | to a shortcut! | ||
77 | |||
78 | |||
79 | ### On Typing Assists | ||
80 | |||
81 | Some features trigger on typing certain characters: | ||
82 | |||
83 | - typing `let =` tries to smartly add `;` if `=` is followed by an existing expression. | ||
84 | - Enter inside comments automatically inserts `///` | ||
85 | - typing `.` in a chain method call auto-indents | ||
86 | |||
87 | |||
88 | ### Code Actions (Assists) | ||
89 | |||
90 | These are triggered in a particular context via lightbulb. We use custom code on | ||
91 | the VS Code side to be able to position cursor. | ||
68 | 92 | ||
69 | 93 | ||
70 | - Flip `,` | 94 | - Flip `,` |
71 | 95 | ||
72 | ``` | 96 | ```rust |
73 | // before: | 97 | // before: |
74 | fn foo(x: usize,<|> dim: (usize, usize)) | 98 | fn foo(x: usize,<|> dim: (usize, usize)) |
75 | // after: | 99 | // after: |
@@ -78,7 +102,7 @@ fn foo(dim: (usize, usize), x: usize) | |||
78 | 102 | ||
79 | - Add `#[derive]` | 103 | - Add `#[derive]` |
80 | 104 | ||
81 | ``` | 105 | ```rust |
82 | // before: | 106 | // before: |
83 | struct Foo { | 107 | struct Foo { |
84 | <|>x: i32 | 108 | <|>x: i32 |
@@ -92,7 +116,7 @@ struct Foo { | |||
92 | 116 | ||
93 | - Add `impl` | 117 | - Add `impl` |
94 | 118 | ||
95 | ``` | 119 | ```rust |
96 | // before: | 120 | // before: |
97 | struct Foo<'a, T: Debug> { | 121 | struct Foo<'a, T: Debug> { |
98 | <|>t: T | 122 | <|>t: T |
@@ -106,3 +130,90 @@ impl<'a, T: Debug> Foo<'a, T> { | |||
106 | <|> | 130 | <|> |
107 | } | 131 | } |
108 | ``` | 132 | ``` |
133 | |||
134 | - Change visibility | ||
135 | |||
136 | ```rust | ||
137 | // before: | ||
138 | fn<|> foo() {} | ||
139 | |||
140 | // after | ||
141 | pub(crate) fn foo() {} | ||
142 | ``` | ||
143 | |||
144 | - Introduce variable: | ||
145 | |||
146 | ```rust | ||
147 | // before: | ||
148 | fn foo() { | ||
149 | foo(<|>1 + 1<|>); | ||
150 | } | ||
151 | |||
152 | // after: | ||
153 | fn foo() { | ||
154 | let var_name = 1 + 1; | ||
155 | foo(var_name); | ||
156 | } | ||
157 | ``` | ||
158 | |||
159 | - Replace if-let with match: | ||
160 | |||
161 | ```rust | ||
162 | // before: | ||
163 | impl VariantData { | ||
164 | pub fn is_struct(&self) -> bool { | ||
165 | if <|>let VariantData::Struct(..) = *self { | ||
166 | true | ||
167 | } else { | ||
168 | false | ||
169 | } | ||
170 | } | ||
171 | } | ||
172 | |||
173 | // after: | ||
174 | impl VariantData { | ||
175 | pub fn is_struct(&self) -> bool { | ||
176 | <|>match *self { | ||
177 | VariantData::Struct(..) => true, | ||
178 | _ => false, | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | ``` | ||
183 | |||
184 | - Split import | ||
185 | |||
186 | ```rust | ||
187 | // before: | ||
188 | use algo:<|>:visitor::{Visitor, visit}; | ||
189 | //after: | ||
190 | use algo::{<|>visitor::{Visitor, visit}}; | ||
191 | ``` | ||
192 | |||
193 | ## LSP features | ||
194 | |||
195 | * **Go to definition**: works correctly for local variables and some paths, | ||
196 | falls back to heuristic name matching for other things for the time being. | ||
197 | |||
198 | * **Completion**: completes paths, including dependencies and standard library. | ||
199 | Does not handle glob imports and macros. Completes fields and inherent methods | ||
200 | |||
201 | * **Outline** <kbd>alt+shift+o</kbd> | ||
202 | |||
203 | * **Signature Info** | ||
204 | |||
205 | * **Format document**. Formats the current file with rustfmt. Rustfmt must be | ||
206 | installed separately with `rustup component add rustfmt`. | ||
207 | |||
208 | * **Hover** shows types of expressions and docstings | ||
209 | |||
210 | * **Rename** works for local variables | ||
211 | |||
212 | * **Code Lens** for running tests | ||
213 | |||
214 | * **Folding** | ||
215 | |||
216 | * **Diagnostics** | ||
217 | - missing module for `mod foo;` with a fix to create `foo.rs`. | ||
218 | - struct field shorthand | ||
219 | - unnessary braces in use item | ||