diff options
-rw-r--r-- | crates/ra_ide/src/display/structure.rs | 13 | ||||
-rw-r--r-- | crates/ra_ide/src/extend_selection.rs | 10 | ||||
-rw-r--r-- | crates/ra_ide/src/goto_definition.rs | 9 | ||||
-rw-r--r-- | crates/ra_ide/src/goto_implementation.rs (renamed from crates/ra_ide/src/impls.rs) | 9 | ||||
-rw-r--r-- | crates/ra_ide/src/goto_type_definition.rs | 3 | ||||
-rw-r--r-- | crates/ra_ide/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide/src/typing.rs | 7 | ||||
-rw-r--r-- | crates/ra_ide_db/src/symbol_index.rs | 21 | ||||
-rw-r--r-- | docs/user/features.md | 52 | ||||
-rw-r--r-- | docs/user/generated_features.adoc | 98 | ||||
-rw-r--r-- | docs/user/readme.adoc | 5 | ||||
-rw-r--r-- | xtask/src/codegen.rs | 5 | ||||
-rw-r--r-- | xtask/src/codegen/gen_feature_docs.rs | 72 | ||||
-rw-r--r-- | xtask/src/main.rs | 1 | ||||
-rw-r--r-- | xtask/tests/tidy.rs | 7 |
15 files changed, 258 insertions, 58 deletions
diff --git a/crates/ra_ide/src/display/structure.rs b/crates/ra_ide/src/display/structure.rs index 967eee5d2..3f59b89bb 100644 --- a/crates/ra_ide/src/display/structure.rs +++ b/crates/ra_ide/src/display/structure.rs | |||
@@ -18,6 +18,19 @@ pub struct StructureNode { | |||
18 | pub deprecated: bool, | 18 | pub deprecated: bool, |
19 | } | 19 | } |
20 | 20 | ||
21 | // Feature: File Structure | ||
22 | // | ||
23 | // Provides a tree of the symbols defined in the file. Can be used to | ||
24 | // | ||
25 | // * fuzzy search symbol in a file (super useful) | ||
26 | // * draw breadcrumbs to describe the context around the cursor | ||
27 | // * draw outline of the file | ||
28 | // | ||
29 | // |=== | ||
30 | // | Editor | Shortcut | ||
31 | // | ||
32 | // | VS Code | kbd:[Ctrl+Shift+O] | ||
33 | // |=== | ||
21 | pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> { | 34 | pub fn file_structure(file: &SourceFile) -> Vec<StructureNode> { |
22 | let mut res = Vec::new(); | 35 | let mut res = Vec::new(); |
23 | let mut stack = Vec::new(); | 36 | let mut stack = Vec::new(); |
diff --git a/crates/ra_ide/src/extend_selection.rs b/crates/ra_ide/src/extend_selection.rs index 554594a43..cee0a19e1 100644 --- a/crates/ra_ide/src/extend_selection.rs +++ b/crates/ra_ide/src/extend_selection.rs | |||
@@ -14,6 +14,16 @@ use ra_syntax::{ | |||
14 | 14 | ||
15 | use crate::FileRange; | 15 | use crate::FileRange; |
16 | 16 | ||
17 | // Feature: Extend Selection | ||
18 | // | ||
19 | // Extends the current selection to the encompassing syntactic construct | ||
20 | // (expression, statement, item, module, etc). It works with multiple cursors. | ||
21 | // | ||
22 | // |=== | ||
23 | // | Editor | Shortcut | ||
24 | // | ||
25 | // | VS Code | kbd:[Ctrl+Shift+→] | ||
26 | // |=== | ||
17 | pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { | 27 | pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { |
18 | let sema = Semantics::new(db); | 28 | let sema = Semantics::new(db); |
19 | let src = sema.parse(frange.file_id); | 29 | let src = sema.parse(frange.file_id); |
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs index 90e85d419..83ea5092c 100644 --- a/crates/ra_ide/src/goto_definition.rs +++ b/crates/ra_ide/src/goto_definition.rs | |||
@@ -17,6 +17,15 @@ use crate::{ | |||
17 | FilePosition, NavigationTarget, RangeInfo, | 17 | FilePosition, NavigationTarget, RangeInfo, |
18 | }; | 18 | }; |
19 | 19 | ||
20 | // Feature: Go To Definition | ||
21 | // | ||
22 | // Navigates to the definition of an identifier. | ||
23 | // | ||
24 | // |=== | ||
25 | // | Editor | Shortcut | ||
26 | // | ||
27 | // | VS Code | kbd:[F12] | ||
28 | // |=== | ||
20 | pub(crate) fn goto_definition( | 29 | pub(crate) fn goto_definition( |
21 | db: &RootDatabase, | 30 | db: &RootDatabase, |
22 | position: FilePosition, | 31 | position: FilePosition, |
diff --git a/crates/ra_ide/src/impls.rs b/crates/ra_ide/src/goto_implementation.rs index ea2225f70..a5a296d22 100644 --- a/crates/ra_ide/src/impls.rs +++ b/crates/ra_ide/src/goto_implementation.rs | |||
@@ -6,6 +6,15 @@ use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; | |||
6 | 6 | ||
7 | use crate::{display::ToNav, FilePosition, NavigationTarget, RangeInfo}; | 7 | use crate::{display::ToNav, FilePosition, NavigationTarget, RangeInfo}; |
8 | 8 | ||
9 | // Feature: Go To Implementation | ||
10 | // | ||
11 | // Navigates to the impl block of structs, enums or traits. Also implemented as a code lens. | ||
12 | // | ||
13 | // |=== | ||
14 | // | Editor | Shortcut | ||
15 | // | ||
16 | // | VS Code | kbd:[Ctrl+F12] | ||
17 | // |=== | ||
9 | pub(crate) fn goto_implementation( | 18 | pub(crate) fn goto_implementation( |
10 | db: &RootDatabase, | 19 | db: &RootDatabase, |
11 | position: FilePosition, | 20 | position: FilePosition, |
diff --git a/crates/ra_ide/src/goto_type_definition.rs b/crates/ra_ide/src/goto_type_definition.rs index a84637489..eeadfa9ee 100644 --- a/crates/ra_ide/src/goto_type_definition.rs +++ b/crates/ra_ide/src/goto_type_definition.rs | |||
@@ -5,6 +5,9 @@ use ra_syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffs | |||
5 | 5 | ||
6 | use crate::{display::ToNav, FilePosition, NavigationTarget, RangeInfo}; | 6 | use crate::{display::ToNav, FilePosition, NavigationTarget, RangeInfo}; |
7 | 7 | ||
8 | // Feature: Go To Type Definition | ||
9 | // | ||
10 | // Navigates to the type of an identifier. | ||
8 | pub(crate) fn goto_type_definition( | 11 | pub(crate) fn goto_type_definition( |
9 | db: &RootDatabase, | 12 | db: &RootDatabase, |
10 | position: FilePosition, | 13 | position: FilePosition, |
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index d983cd910..12d5716e8 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs | |||
@@ -23,6 +23,7 @@ mod completion; | |||
23 | mod runnables; | 23 | mod runnables; |
24 | mod goto_definition; | 24 | mod goto_definition; |
25 | mod goto_type_definition; | 25 | mod goto_type_definition; |
26 | mod goto_implementation; | ||
26 | mod extend_selection; | 27 | mod extend_selection; |
27 | mod hover; | 28 | mod hover; |
28 | mod call_hierarchy; | 29 | mod call_hierarchy; |
@@ -30,7 +31,6 @@ mod call_info; | |||
30 | mod syntax_highlighting; | 31 | mod syntax_highlighting; |
31 | mod parent_module; | 32 | mod parent_module; |
32 | mod references; | 33 | mod references; |
33 | mod impls; | ||
34 | mod diagnostics; | 34 | mod diagnostics; |
35 | mod syntax_tree; | 35 | mod syntax_tree; |
36 | mod folding_ranges; | 36 | mod folding_ranges; |
@@ -373,7 +373,7 @@ impl Analysis { | |||
373 | &self, | 373 | &self, |
374 | position: FilePosition, | 374 | position: FilePosition, |
375 | ) -> Cancelable<Option<RangeInfo<Vec<NavigationTarget>>>> { | 375 | ) -> Cancelable<Option<RangeInfo<Vec<NavigationTarget>>>> { |
376 | self.with_db(|db| impls::goto_implementation(db, position)) | 376 | self.with_db(|db| goto_implementation::goto_implementation(db, position)) |
377 | } | 377 | } |
378 | 378 | ||
379 | /// Returns the type definitions for the symbol at `position`. | 379 | /// Returns the type definitions for the symbol at `position`. |
diff --git a/crates/ra_ide/src/typing.rs b/crates/ra_ide/src/typing.rs index 39bb3b357..67e2c33a0 100644 --- a/crates/ra_ide/src/typing.rs +++ b/crates/ra_ide/src/typing.rs | |||
@@ -32,6 +32,13 @@ pub(crate) use on_enter::on_enter; | |||
32 | 32 | ||
33 | pub(crate) const TRIGGER_CHARS: &str = ".=>"; | 33 | pub(crate) const TRIGGER_CHARS: &str = ".=>"; |
34 | 34 | ||
35 | // Feature: On Typing Assists | ||
36 | // | ||
37 | // Some features trigger on typing certain characters: | ||
38 | // | ||
39 | // - typing `let =` tries to smartly add `;` if `=` is followed by an existing expression | ||
40 | // - Enter inside comments automatically inserts `///` | ||
41 | // - typing `.` in a chain method call auto-indents | ||
35 | pub(crate) fn on_char_typed( | 42 | pub(crate) fn on_char_typed( |
36 | db: &RootDatabase, | 43 | db: &RootDatabase, |
37 | position: FilePosition, | 44 | position: FilePosition, |
diff --git a/crates/ra_ide_db/src/symbol_index.rs b/crates/ra_ide_db/src/symbol_index.rs index 95be11134..acc31fe3b 100644 --- a/crates/ra_ide_db/src/symbol_index.rs +++ b/crates/ra_ide_db/src/symbol_index.rs | |||
@@ -110,6 +110,27 @@ fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex> | |||
110 | Arc::new(SymbolIndex::new(symbols)) | 110 | Arc::new(SymbolIndex::new(symbols)) |
111 | } | 111 | } |
112 | 112 | ||
113 | // Feature: Workspace Symbol | ||
114 | // | ||
115 | // Uses fuzzy-search to find types, modules and functions by name across your | ||
116 | // project and dependencies. This is **the** most useful feature, which improves code | ||
117 | // navigation tremendously. It mostly works on top of the built-in LSP | ||
118 | // functionality, however `#` and `*` symbols can be used to narrow down the | ||
119 | // search. Specifically, | ||
120 | // | ||
121 | // - `Foo` searches for `Foo` type in the current workspace | ||
122 | // - `foo#` searches for `foo` function in the current workspace | ||
123 | // - `Foo*` searches for `Foo` type among dependencies, including `stdlib` | ||
124 | // - `foo#*` searches for `foo` function among dependencies | ||
125 | // | ||
126 | // That is, `#` switches from "types" to all symbols, `*` switches from the current | ||
127 | // workspace to dependencies. | ||
128 | // | ||
129 | // |=== | ||
130 | // | Editor | Shortcut | ||
131 | // | ||
132 | // | VS Code | kbd:[Ctrl+T] | ||
133 | // |=== | ||
113 | pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> { | 134 | pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> { |
114 | /// Need to wrap Snapshot to provide `Clone` impl for `map_with` | 135 | /// Need to wrap Snapshot to provide `Clone` impl for `map_with` |
115 | struct Snap(salsa::Snapshot<RootDatabase>); | 136 | struct Snap(salsa::Snapshot<RootDatabase>); |
diff --git a/docs/user/features.md b/docs/user/features.md index 12ecdec13..4d9402252 100644 --- a/docs/user/features.md +++ b/docs/user/features.md | |||
@@ -2,58 +2,6 @@ This document is an index of features that the rust-analyzer language server | |||
2 | provides. Shortcuts are for the default VS Code layout. If there's no shortcut, | 2 | provides. Shortcuts are for the default VS Code layout. If there's no shortcut, |
3 | you can use <kbd>Ctrl+Shift+P</kbd> to search for the corresponding action. | 3 | you can use <kbd>Ctrl+Shift+P</kbd> to search for the corresponding action. |
4 | 4 | ||
5 | ### Workspace Symbol <kbd>ctrl+t</kbd> | ||
6 | |||
7 | Uses fuzzy-search to find types, modules and functions by name across your | ||
8 | project and dependencies. This is **the** most useful feature, which improves code | ||
9 | navigation tremendously. It mostly works on top of the built-in LSP | ||
10 | functionality, however `#` and `*` symbols can be used to narrow down the | ||
11 | search. Specifically, | ||
12 | |||
13 | - `Foo` searches for `Foo` type in the current workspace | ||
14 | - `foo#` searches for `foo` function in the current workspace | ||
15 | - `Foo*` searches for `Foo` type among dependencies, including `stdlib` | ||
16 | - `foo#*` searches for `foo` function among dependencies | ||
17 | |||
18 | That is, `#` switches from "types" to all symbols, `*` switches from the current | ||
19 | workspace to dependencies. | ||
20 | |||
21 | ### Document Symbol <kbd>ctrl+shift+o</kbd> | ||
22 | |||
23 | Provides a tree of the symbols defined in the file. Can be used to | ||
24 | |||
25 | * fuzzy search symbol in a file (super useful) | ||
26 | * draw breadcrumbs to describe the context around the cursor | ||
27 | * draw outline of the file | ||
28 | |||
29 | ### On Typing Assists | ||
30 | |||
31 | Some features trigger on typing certain characters: | ||
32 | |||
33 | - typing `let =` tries to smartly add `;` if `=` is followed by an existing expression | ||
34 | - Enter inside comments automatically inserts `///` | ||
35 | - typing `.` in a chain method call auto-indents | ||
36 | |||
37 | ### Extend Selection | ||
38 | |||
39 | Extends the current selection to the encompassing syntactic construct | ||
40 | (expression, statement, item, module, etc). It works with multiple cursors. This | ||
41 | is a relatively new feature of LSP: | ||
42 | https://github.com/Microsoft/language-server-protocol/issues/613, check your | ||
43 | editor's LSP library to see if this feature is supported. | ||
44 | |||
45 | ### Go to Definition | ||
46 | |||
47 | Navigates to the definition of an identifier. | ||
48 | |||
49 | ### Go to Implementation | ||
50 | |||
51 | Navigates to the impl block of structs, enums or traits. Also implemented as a code lens. | ||
52 | |||
53 | ### Go to Type Defintion | ||
54 | |||
55 | Navigates to the type of an identifier. | ||
56 | |||
57 | ### Commands <kbd>ctrl+shift+p</kbd> | 5 | ### Commands <kbd>ctrl+shift+p</kbd> |
58 | 6 | ||
59 | #### Run | 7 | #### Run |
diff --git a/docs/user/generated_features.adoc b/docs/user/generated_features.adoc new file mode 100644 index 000000000..e1eb5d88a --- /dev/null +++ b/docs/user/generated_features.adoc | |||
@@ -0,0 +1,98 @@ | |||
1 | === Extend Selection | ||
2 | **Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/extend_selection.rs[extend_selection.rs] | ||
3 | |||
4 | |||
5 | Extends the current selection to the encompassing syntactic construct | ||
6 | (expression, statement, item, module, etc). It works with multiple cursors. | ||
7 | |||
8 | |=== | ||
9 | | Editor | Shortcut | ||
10 | |||
11 | | VS Code | kbd:[Ctrl+Shift+→] | ||
12 | |=== | ||
13 | |||
14 | |||
15 | === File Structure | ||
16 | **Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/display/structure.rs[structure.rs] | ||
17 | |||
18 | |||
19 | Provides a tree of the symbols defined in the file. Can be used to | ||
20 | |||
21 | * fuzzy search symbol in a file (super useful) | ||
22 | * draw breadcrumbs to describe the context around the cursor | ||
23 | * draw outline of the file | ||
24 | |||
25 | |=== | ||
26 | | Editor | Shortcut | ||
27 | |||
28 | | VS Code | kbd:[Ctrl+Shift+O] | ||
29 | |=== | ||
30 | |||
31 | |||
32 | === Go To Definition | ||
33 | **Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/goto_definition.rs[goto_definition.rs] | ||
34 | |||
35 | |||
36 | Navigates to the definition of an identifier. | ||
37 | |||
38 | |=== | ||
39 | | Editor | Shortcut | ||
40 | |||
41 | | VS Code | kbd:[F12] | ||
42 | |=== | ||
43 | |||
44 | |||
45 | === Go To Implementation | ||
46 | **Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/goto_implementation.rs[goto_implementation.rs] | ||
47 | |||
48 | |||
49 | Navigates to the impl block of structs, enums or traits. Also implemented as a code lens. | ||
50 | |||
51 | |=== | ||
52 | | Editor | Shortcut | ||
53 | |||
54 | | VS Code | kbd:[Ctrl+F12] | ||
55 | |=== | ||
56 | |||
57 | |||
58 | === Go To Type Definition | ||
59 | **Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/goto_type_definition.rs[goto_type_definition.rs] | ||
60 | |||
61 | |||
62 | Navigates to the type of an identifier. | ||
63 | |||
64 | |||
65 | === On Typing Assists | ||
66 | **Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide/src/typing.rs[typing.rs] | ||
67 | |||
68 | |||
69 | Some features trigger on typing certain characters: | ||
70 | |||
71 | - typing `let =` tries to smartly add `;` if `=` is followed by an existing expression | ||
72 | - Enter inside comments automatically inserts `///` | ||
73 | - typing `.` in a chain method call auto-indents | ||
74 | |||
75 | |||
76 | === Workspace Symbol | ||
77 | **Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_ide_db/src/symbol_index.rs[symbol_index.rs] | ||
78 | |||
79 | |||
80 | Uses fuzzy-search to find types, modules and functions by name across your | ||
81 | project and dependencies. This is **the** most useful feature, which improves code | ||
82 | navigation tremendously. It mostly works on top of the built-in LSP | ||
83 | functionality, however `#` and `*` symbols can be used to narrow down the | ||
84 | search. Specifically, | ||
85 | |||
86 | - `Foo` searches for `Foo` type in the current workspace | ||
87 | - `foo#` searches for `foo` function in the current workspace | ||
88 | - `Foo*` searches for `Foo` type among dependencies, including `stdlib` | ||
89 | - `foo#*` searches for `foo` function among dependencies | ||
90 | |||
91 | That is, `#` switches from "types" to all symbols, `*` switches from the current | ||
92 | workspace to dependencies. | ||
93 | |||
94 | |=== | ||
95 | | Editor | Shortcut | ||
96 | |||
97 | | VS Code | kbd:[Ctrl+T] | ||
98 | |=== | ||
diff --git a/docs/user/readme.adoc b/docs/user/readme.adoc index 64bd0feb1..7b159bfc6 100644 --- a/docs/user/readme.adoc +++ b/docs/user/readme.adoc | |||
@@ -8,6 +8,7 @@ | |||
8 | :important-caption: :heavy_exclamation_mark: | 8 | :important-caption: :heavy_exclamation_mark: |
9 | :caution-caption: :fire: | 9 | :caution-caption: :fire: |
10 | :warning-caption: :warning: | 10 | :warning-caption: :warning: |
11 | :experimental: | ||
11 | 12 | ||
12 | // Master copy of this document lives in the https://github.com/rust-analyzer/rust-analyzer repository | 13 | // Master copy of this document lives in the https://github.com/rust-analyzer/rust-analyzer repository |
13 | 14 | ||
@@ -268,6 +269,6 @@ Gnome Builder currently has support for RLS, and there's no way to configure the | |||
268 | 1. Rename, symlink or copy the `rust-analyzer` binary to `rls` and place it somewhere Builder can find (in `PATH`, or under `~/.cargo/bin`). | 269 | 1. Rename, symlink or copy the `rust-analyzer` binary to `rls` and place it somewhere Builder can find (in `PATH`, or under `~/.cargo/bin`). |
269 | 2. Enable the Rust Builder plugin. | 270 | 2. Enable the Rust Builder plugin. |
270 | 271 | ||
271 | == Usage | 272 | == Features |
272 | 273 | ||
273 | See https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/features.md[features.md]. | 274 | include::./generated_features.adoc[] |
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs index 2e8fd3494..3e2a66979 100644 --- a/xtask/src/codegen.rs +++ b/xtask/src/codegen.rs | |||
@@ -8,14 +8,15 @@ | |||
8 | mod gen_syntax; | 8 | mod gen_syntax; |
9 | mod gen_parser_tests; | 9 | mod gen_parser_tests; |
10 | mod gen_assists_docs; | 10 | mod gen_assists_docs; |
11 | mod gen_feature_docs; | ||
11 | 12 | ||
12 | use std::{mem, path::Path}; | 13 | use std::{mem, path::Path}; |
13 | 14 | ||
14 | use crate::{not_bash::fs2, Result}; | 15 | use crate::{not_bash::fs2, Result}; |
15 | 16 | ||
16 | pub use self::{ | 17 | pub use self::{ |
17 | gen_assists_docs::generate_assists_docs, gen_parser_tests::generate_parser_tests, | 18 | gen_assists_docs::generate_assists_docs, gen_feature_docs::generate_feature_docs, |
18 | gen_syntax::generate_syntax, | 19 | gen_parser_tests::generate_parser_tests, gen_syntax::generate_syntax, |
19 | }; | 20 | }; |
20 | 21 | ||
21 | const GRAMMAR_DIR: &str = "crates/ra_parser/src/grammar"; | 22 | const GRAMMAR_DIR: &str = "crates/ra_parser/src/grammar"; |
diff --git a/xtask/src/codegen/gen_feature_docs.rs b/xtask/src/codegen/gen_feature_docs.rs new file mode 100644 index 000000000..583185648 --- /dev/null +++ b/xtask/src/codegen/gen_feature_docs.rs | |||
@@ -0,0 +1,72 @@ | |||
1 | //! Generates `assists.md` documentation. | ||
2 | |||
3 | use std::{fmt, fs, path::PathBuf}; | ||
4 | |||
5 | use crate::{ | ||
6 | codegen::{self, extract_comment_blocks_with_empty_lines, Mode}, | ||
7 | project_root, rust_files, Result, | ||
8 | }; | ||
9 | |||
10 | pub fn generate_feature_docs(mode: Mode) -> Result<()> { | ||
11 | let features = Feature::collect()?; | ||
12 | let contents = features.into_iter().map(|it| it.to_string()).collect::<Vec<_>>().join("\n\n"); | ||
13 | |||
14 | let dst = project_root().join("docs/user/generated_features.adoc"); | ||
15 | codegen::update(&dst, &contents, mode)?; | ||
16 | Ok(()) | ||
17 | } | ||
18 | |||
19 | #[derive(Debug)] | ||
20 | struct Feature { | ||
21 | id: String, | ||
22 | path: PathBuf, | ||
23 | doc: String, | ||
24 | } | ||
25 | |||
26 | impl Feature { | ||
27 | fn collect() -> Result<Vec<Feature>> { | ||
28 | let mut res = Vec::new(); | ||
29 | for path in rust_files(&project_root()) { | ||
30 | collect_file(&mut res, path)?; | ||
31 | } | ||
32 | res.sort_by(|lhs, rhs| lhs.id.cmp(&rhs.id)); | ||
33 | return Ok(res); | ||
34 | |||
35 | fn collect_file(acc: &mut Vec<Feature>, path: PathBuf) -> Result<()> { | ||
36 | let text = fs::read_to_string(&path)?; | ||
37 | let comment_blocks = extract_comment_blocks_with_empty_lines("Feature", &text); | ||
38 | |||
39 | for block in comment_blocks { | ||
40 | let id = block.id; | ||
41 | assert!( | ||
42 | id.split_ascii_whitespace().all(|it| it.starts_with(char::is_uppercase)), | ||
43 | "bad feature: {}", | ||
44 | id | ||
45 | ); | ||
46 | let doc = block.contents.join("\n"); | ||
47 | acc.push(Feature { id, path: path.clone(), doc }) | ||
48 | } | ||
49 | |||
50 | Ok(()) | ||
51 | } | ||
52 | } | ||
53 | } | ||
54 | |||
55 | impl fmt::Display for Feature { | ||
56 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
57 | writeln!(f, "=== {}", self.id)?; | ||
58 | let path = self.path.strip_prefix(&project_root()).unwrap(); | ||
59 | let name = self.path.file_name().unwrap(); | ||
60 | |||
61 | //FIXME: generate line number as well | ||
62 | writeln!( | ||
63 | f, | ||
64 | "**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/{}[{}]", | ||
65 | path.display(), | ||
66 | name.to_str().unwrap(), | ||
67 | )?; | ||
68 | |||
69 | writeln!(f, "\n{}", self.doc)?; | ||
70 | Ok(()) | ||
71 | } | ||
72 | } | ||
diff --git a/xtask/src/main.rs b/xtask/src/main.rs index dff3ce4a1..9d7cdd114 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs | |||
@@ -75,6 +75,7 @@ FLAGS: | |||
75 | codegen::generate_syntax(Mode::Overwrite)?; | 75 | codegen::generate_syntax(Mode::Overwrite)?; |
76 | codegen::generate_parser_tests(Mode::Overwrite)?; | 76 | codegen::generate_parser_tests(Mode::Overwrite)?; |
77 | codegen::generate_assists_docs(Mode::Overwrite)?; | 77 | codegen::generate_assists_docs(Mode::Overwrite)?; |
78 | codegen::generate_feature_docs(Mode::Overwrite)?; | ||
78 | Ok(()) | 79 | Ok(()) |
79 | } | 80 | } |
80 | "format" => { | 81 | "format" => { |
diff --git a/xtask/tests/tidy.rs b/xtask/tests/tidy.rs index 2e9fcf07c..06ff45d99 100644 --- a/xtask/tests/tidy.rs +++ b/xtask/tests/tidy.rs | |||
@@ -31,6 +31,13 @@ fn generated_assists_are_fresh() { | |||
31 | } | 31 | } |
32 | 32 | ||
33 | #[test] | 33 | #[test] |
34 | fn generated_features_are_fresh() { | ||
35 | if let Err(error) = codegen::generate_feature_docs(Mode::Verify) { | ||
36 | panic!("{}. Please update features by running `cargo xtask codegen`", error); | ||
37 | } | ||
38 | } | ||
39 | |||
40 | #[test] | ||
34 | fn check_code_formatting() { | 41 | fn check_code_formatting() { |
35 | if let Err(error) = run_rustfmt(Mode::Verify) { | 42 | if let Err(error) = run_rustfmt(Mode::Verify) { |
36 | panic!("{}. Please format the code by running `cargo format`", error); | 43 | panic!("{}. Please format the code by running `cargo format`", error); |