diff options
-rw-r--r-- | crates/assists/src/assist_context.rs | 13 | ||||
-rw-r--r-- | crates/assists/src/handlers/extract_module_to_file.rs | 170 | ||||
-rw-r--r-- | crates/assists/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/assists/src/tests.rs | 28 | ||||
-rw-r--r-- | crates/assists/src/tests/generated.rs | 15 | ||||
-rw-r--r-- | crates/ide/src/diagnostics.rs | 1 | ||||
-rw-r--r-- | crates/ide/src/diagnostics/fixes.rs | 1 | ||||
-rw-r--r-- | crates/ide_db/src/source_change.rs | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/to_proto.rs | 37 | ||||
-rw-r--r-- | editors/code/.vscodeignore | 1 | ||||
-rw-r--r-- | editors/code/package.json | 5 | ||||
-rw-r--r-- | editors/code/rust.tmGrammar.json | 1140 | ||||
-rw-r--r-- | editors/code/src/commands.ts | 2 | ||||
-rw-r--r-- | editors/code/src/main.ts | 7 |
14 files changed, 256 insertions, 1168 deletions
diff --git a/crates/assists/src/assist_context.rs b/crates/assists/src/assist_context.rs index 69499ea32..80cf9aba1 100644 --- a/crates/assists/src/assist_context.rs +++ b/crates/assists/src/assist_context.rs | |||
@@ -4,10 +4,10 @@ use std::mem; | |||
4 | 4 | ||
5 | use algo::find_covering_element; | 5 | use algo::find_covering_element; |
6 | use hir::Semantics; | 6 | use hir::Semantics; |
7 | use ide_db::base_db::{FileId, FileRange}; | 7 | use ide_db::base_db::{AnchoredPathBuf, FileId, FileRange}; |
8 | use ide_db::{ | 8 | use ide_db::{ |
9 | label::Label, | 9 | label::Label, |
10 | source_change::{SourceChange, SourceFileEdit}, | 10 | source_change::{FileSystemEdit, SourceChange, SourceFileEdit}, |
11 | RootDatabase, | 11 | RootDatabase, |
12 | }; | 12 | }; |
13 | use syntax::{ | 13 | use syntax::{ |
@@ -209,6 +209,7 @@ pub(crate) struct AssistBuilder { | |||
209 | file_id: FileId, | 209 | file_id: FileId, |
210 | is_snippet: bool, | 210 | is_snippet: bool, |
211 | source_file_edits: Vec<SourceFileEdit>, | 211 | source_file_edits: Vec<SourceFileEdit>, |
212 | file_system_edits: Vec<FileSystemEdit>, | ||
212 | } | 213 | } |
213 | 214 | ||
214 | impl AssistBuilder { | 215 | impl AssistBuilder { |
@@ -218,6 +219,7 @@ impl AssistBuilder { | |||
218 | file_id, | 219 | file_id, |
219 | is_snippet: false, | 220 | is_snippet: false, |
220 | source_file_edits: Vec::default(), | 221 | source_file_edits: Vec::default(), |
222 | file_system_edits: Vec::default(), | ||
221 | } | 223 | } |
222 | } | 224 | } |
223 | 225 | ||
@@ -282,12 +284,17 @@ impl AssistBuilder { | |||
282 | algo::diff(&node, &new).into_text_edit(&mut self.edit); | 284 | algo::diff(&node, &new).into_text_edit(&mut self.edit); |
283 | } | 285 | } |
284 | } | 286 | } |
287 | pub(crate) fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) { | ||
288 | let file_system_edit = | ||
289 | FileSystemEdit::CreateFile { dst: dst.clone(), initial_contents: content.into() }; | ||
290 | self.file_system_edits.push(file_system_edit); | ||
291 | } | ||
285 | 292 | ||
286 | fn finish(mut self) -> SourceChange { | 293 | fn finish(mut self) -> SourceChange { |
287 | self.commit(); | 294 | self.commit(); |
288 | SourceChange { | 295 | SourceChange { |
289 | source_file_edits: mem::take(&mut self.source_file_edits), | 296 | source_file_edits: mem::take(&mut self.source_file_edits), |
290 | file_system_edits: Default::default(), | 297 | file_system_edits: mem::take(&mut self.file_system_edits), |
291 | is_snippet: self.is_snippet, | 298 | is_snippet: self.is_snippet, |
292 | } | 299 | } |
293 | } | 300 | } |
diff --git a/crates/assists/src/handlers/extract_module_to_file.rs b/crates/assists/src/handlers/extract_module_to_file.rs new file mode 100644 index 000000000..5fc190fa6 --- /dev/null +++ b/crates/assists/src/handlers/extract_module_to_file.rs | |||
@@ -0,0 +1,170 @@ | |||
1 | use ast::edit::IndentLevel; | ||
2 | use ide_db::base_db::{AnchoredPathBuf, SourceDatabaseExt}; | ||
3 | use syntax::{ | ||
4 | ast::{self, edit::AstNodeEdit, NameOwner}, | ||
5 | AstNode, | ||
6 | }; | ||
7 | |||
8 | use crate::{AssistContext, AssistId, AssistKind, Assists}; | ||
9 | |||
10 | // Assist: extract_module_to_file | ||
11 | // | ||
12 | // This assist extract module to file. | ||
13 | // | ||
14 | // ``` | ||
15 | // mod foo {<|> | ||
16 | // fn t() {} | ||
17 | // } | ||
18 | // ``` | ||
19 | // -> | ||
20 | // ``` | ||
21 | // mod foo; | ||
22 | // ``` | ||
23 | pub(crate) fn extract_module_to_file(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | ||
24 | let assist_id = AssistId("extract_module_to_file", AssistKind::RefactorExtract); | ||
25 | let assist_label = "Extract module to file"; | ||
26 | let db = ctx.db(); | ||
27 | let module_ast = ctx.find_node_at_offset::<ast::Module>()?; | ||
28 | let module_items = module_ast.item_list()?; | ||
29 | let dedent_module_items_text = module_items.dedent(IndentLevel(1)).to_string(); | ||
30 | let module_name = module_ast.name()?; | ||
31 | let target = module_ast.syntax().text_range(); | ||
32 | let anchor_file_id = ctx.frange.file_id; | ||
33 | let sr = db.file_source_root(anchor_file_id); | ||
34 | let sr = db.source_root(sr); | ||
35 | let file_path = sr.path_for_file(&anchor_file_id)?; | ||
36 | let (file_name, file_ext) = file_path.name_and_extension()?; | ||
37 | acc.add(assist_id, assist_label, target, |builder| { | ||
38 | builder.replace(target, format!("mod {};", module_name)); | ||
39 | let path = if is_main_or_lib(file_name) { | ||
40 | format!("./{}.{}", module_name, file_ext.unwrap()) | ||
41 | } else { | ||
42 | format!("./{}/{}.{}", file_name, module_name, file_ext.unwrap()) | ||
43 | }; | ||
44 | let dst = AnchoredPathBuf { anchor: anchor_file_id, path }; | ||
45 | let contents = update_module_items_string(dedent_module_items_text); | ||
46 | builder.create_file(dst, contents); | ||
47 | }) | ||
48 | } | ||
49 | fn is_main_or_lib(file_name: &str) -> bool { | ||
50 | file_name == "main".to_string() || file_name == "lib".to_string() | ||
51 | } | ||
52 | fn update_module_items_string(items_str: String) -> String { | ||
53 | let mut items_string_lines: Vec<&str> = items_str.lines().collect(); | ||
54 | items_string_lines.pop(); // Delete last line | ||
55 | items_string_lines.reverse(); | ||
56 | items_string_lines.pop(); // Delete first line | ||
57 | items_string_lines.reverse(); | ||
58 | |||
59 | let string = items_string_lines.join("\n"); | ||
60 | format!("{}", string) | ||
61 | } | ||
62 | |||
63 | #[cfg(test)] | ||
64 | mod tests { | ||
65 | use crate::tests::check_assist; | ||
66 | |||
67 | use super::*; | ||
68 | |||
69 | #[test] | ||
70 | fn extract_module_to_file_with_basic_module() { | ||
71 | check_assist( | ||
72 | extract_module_to_file, | ||
73 | r#" | ||
74 | //- /foo.rs crate:foo | ||
75 | mod tests {<|> | ||
76 | #[test] fn t() {} | ||
77 | } | ||
78 | "#, | ||
79 | r#" | ||
80 | //- /foo.rs | ||
81 | mod tests; | ||
82 | //- /foo/tests.rs | ||
83 | #[test] fn t() {}"#, | ||
84 | ) | ||
85 | } | ||
86 | |||
87 | #[test] | ||
88 | fn extract_module_to_file_with_file_path() { | ||
89 | check_assist( | ||
90 | extract_module_to_file, | ||
91 | r#" | ||
92 | //- /src/foo.rs crate:foo | ||
93 | mod bar {<|> | ||
94 | fn f() { | ||
95 | |||
96 | } | ||
97 | } | ||
98 | fn main() { | ||
99 | println!("Hello, world!"); | ||
100 | } | ||
101 | "#, | ||
102 | r#" | ||
103 | //- /src/foo.rs | ||
104 | mod bar; | ||
105 | fn main() { | ||
106 | println!("Hello, world!"); | ||
107 | } | ||
108 | //- /src/foo/bar.rs | ||
109 | fn f() { | ||
110 | |||
111 | }"#, | ||
112 | ) | ||
113 | } | ||
114 | |||
115 | #[test] | ||
116 | fn extract_module_to_file_with_main_filw() { | ||
117 | check_assist( | ||
118 | extract_module_to_file, | ||
119 | r#" | ||
120 | //- /main.rs | ||
121 | mod foo {<|> | ||
122 | fn f() { | ||
123 | |||
124 | } | ||
125 | } | ||
126 | fn main() { | ||
127 | println!("Hello, world!"); | ||
128 | } | ||
129 | "#, | ||
130 | r#" | ||
131 | //- /main.rs | ||
132 | mod foo; | ||
133 | fn main() { | ||
134 | println!("Hello, world!"); | ||
135 | } | ||
136 | //- /foo.rs | ||
137 | fn f() { | ||
138 | |||
139 | }"#, | ||
140 | ) | ||
141 | } | ||
142 | |||
143 | #[test] | ||
144 | fn extract_module_to_file_with_lib_file() { | ||
145 | check_assist( | ||
146 | extract_module_to_file, | ||
147 | r#" | ||
148 | //- /lib.rs | ||
149 | mod foo {<|> | ||
150 | fn f() { | ||
151 | |||
152 | } | ||
153 | } | ||
154 | fn main() { | ||
155 | println!("Hello, world!"); | ||
156 | } | ||
157 | "#, | ||
158 | r#" | ||
159 | //- /lib.rs | ||
160 | mod foo; | ||
161 | fn main() { | ||
162 | println!("Hello, world!"); | ||
163 | } | ||
164 | //- /foo.rs | ||
165 | fn f() { | ||
166 | |||
167 | }"#, | ||
168 | ) | ||
169 | } | ||
170 | } | ||
diff --git a/crates/assists/src/lib.rs b/crates/assists/src/lib.rs index 6e736ccb3..6b89b2d04 100644 --- a/crates/assists/src/lib.rs +++ b/crates/assists/src/lib.rs | |||
@@ -129,6 +129,7 @@ mod handlers { | |||
129 | mod convert_integer_literal; | 129 | mod convert_integer_literal; |
130 | mod early_return; | 130 | mod early_return; |
131 | mod expand_glob_import; | 131 | mod expand_glob_import; |
132 | mod extract_module_to_file; | ||
132 | mod extract_struct_from_enum_variant; | 133 | mod extract_struct_from_enum_variant; |
133 | mod extract_variable; | 134 | mod extract_variable; |
134 | mod fill_match_arms; | 135 | mod fill_match_arms; |
@@ -179,6 +180,7 @@ mod handlers { | |||
179 | convert_integer_literal::convert_integer_literal, | 180 | convert_integer_literal::convert_integer_literal, |
180 | early_return::convert_to_guarded_return, | 181 | early_return::convert_to_guarded_return, |
181 | expand_glob_import::expand_glob_import, | 182 | expand_glob_import::expand_glob_import, |
183 | extract_module_to_file::extract_module_to_file, | ||
182 | extract_struct_from_enum_variant::extract_struct_from_enum_variant, | 184 | extract_struct_from_enum_variant::extract_struct_from_enum_variant, |
183 | extract_variable::extract_variable, | 185 | extract_variable::extract_variable, |
184 | fill_match_arms::fill_match_arms, | 186 | fill_match_arms::fill_match_arms, |
diff --git a/crates/assists/src/tests.rs b/crates/assists/src/tests.rs index 709a34d03..b41f4874a 100644 --- a/crates/assists/src/tests.rs +++ b/crates/assists/src/tests.rs | |||
@@ -2,6 +2,7 @@ mod generated; | |||
2 | 2 | ||
3 | use hir::Semantics; | 3 | use hir::Semantics; |
4 | use ide_db::base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt}; | 4 | use ide_db::base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt}; |
5 | use ide_db::source_change::FileSystemEdit; | ||
5 | use ide_db::RootDatabase; | 6 | use ide_db::RootDatabase; |
6 | use syntax::TextRange; | 7 | use syntax::TextRange; |
7 | use test_utils::{assert_eq_text, extract_offset, extract_range}; | 8 | use test_utils::{assert_eq_text, extract_offset, extract_range}; |
@@ -47,7 +48,7 @@ fn check_doc_test(assist_id: &str, before: &str, after: &str) { | |||
47 | let before = db.file_text(file_id).to_string(); | 48 | let before = db.file_text(file_id).to_string(); |
48 | let frange = FileRange { file_id, range: selection.into() }; | 49 | let frange = FileRange { file_id, range: selection.into() }; |
49 | 50 | ||
50 | let mut assist = Assist::resolved(&db, &AssistConfig::default(), frange) | 51 | let assist = Assist::resolved(&db, &AssistConfig::default(), frange) |
51 | .into_iter() | 52 | .into_iter() |
52 | .find(|assist| assist.assist.id.0 == assist_id) | 53 | .find(|assist| assist.assist.id.0 == assist_id) |
53 | .unwrap_or_else(|| { | 54 | .unwrap_or_else(|| { |
@@ -63,9 +64,12 @@ fn check_doc_test(assist_id: &str, before: &str, after: &str) { | |||
63 | }); | 64 | }); |
64 | 65 | ||
65 | let actual = { | 66 | let actual = { |
66 | let change = assist.source_change.source_file_edits.pop().unwrap(); | ||
67 | let mut actual = before; | 67 | let mut actual = before; |
68 | change.edit.apply(&mut actual); | 68 | for source_file_edit in assist.source_change.source_file_edits { |
69 | if source_file_edit.file_id == file_id { | ||
70 | source_file_edit.edit.apply(&mut actual) | ||
71 | } | ||
72 | } | ||
69 | actual | 73 | actual |
70 | }; | 74 | }; |
71 | assert_eq_text!(&after, &actual); | 75 | assert_eq_text!(&after, &actual); |
@@ -99,7 +103,8 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label: | |||
99 | (Some(assist), ExpectedResult::After(after)) => { | 103 | (Some(assist), ExpectedResult::After(after)) => { |
100 | let mut source_change = assist.source_change; | 104 | let mut source_change = assist.source_change; |
101 | assert!(!source_change.source_file_edits.is_empty()); | 105 | assert!(!source_change.source_file_edits.is_empty()); |
102 | let skip_header = source_change.source_file_edits.len() == 1; | 106 | let skip_header = source_change.source_file_edits.len() == 1 |
107 | && source_change.file_system_edits.len() == 0; | ||
103 | source_change.source_file_edits.sort_by_key(|it| it.file_id); | 108 | source_change.source_file_edits.sort_by_key(|it| it.file_id); |
104 | 109 | ||
105 | let mut buf = String::new(); | 110 | let mut buf = String::new(); |
@@ -115,6 +120,21 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label: | |||
115 | buf.push_str(&text); | 120 | buf.push_str(&text); |
116 | } | 121 | } |
117 | 122 | ||
123 | for file_system_edit in source_change.file_system_edits.clone() { | ||
124 | match file_system_edit { | ||
125 | FileSystemEdit::CreateFile { dst, initial_contents } => { | ||
126 | let sr = db.file_source_root(dst.anchor); | ||
127 | let sr = db.source_root(sr); | ||
128 | let mut base = sr.path_for_file(&dst.anchor).unwrap().clone(); | ||
129 | base.pop(); | ||
130 | let created_file_path = format!("{}{}", base.to_string(), &dst.path[1..]); | ||
131 | format_to!(buf, "//- {}\n", created_file_path); | ||
132 | buf.push_str(&initial_contents); | ||
133 | } | ||
134 | _ => (), | ||
135 | } | ||
136 | } | ||
137 | |||
118 | assert_eq_text!(after, &buf); | 138 | assert_eq_text!(after, &buf); |
119 | } | 139 | } |
120 | (Some(assist), ExpectedResult::Target(target)) => { | 140 | (Some(assist), ExpectedResult::Target(target)) => { |
diff --git a/crates/assists/src/tests/generated.rs b/crates/assists/src/tests/generated.rs index cc7c4a343..e9093ec53 100644 --- a/crates/assists/src/tests/generated.rs +++ b/crates/assists/src/tests/generated.rs | |||
@@ -236,6 +236,21 @@ fn qux(bar: Bar, baz: Baz) {} | |||
236 | } | 236 | } |
237 | 237 | ||
238 | #[test] | 238 | #[test] |
239 | fn doctest_extract_module_to_file() { | ||
240 | check_doc_test( | ||
241 | "extract_module_to_file", | ||
242 | r#####" | ||
243 | mod foo {<|> | ||
244 | fn t() {} | ||
245 | } | ||
246 | "#####, | ||
247 | r#####" | ||
248 | mod foo; | ||
249 | "#####, | ||
250 | ) | ||
251 | } | ||
252 | |||
253 | #[test] | ||
239 | fn doctest_extract_struct_from_enum_variant() { | 254 | fn doctest_extract_struct_from_enum_variant() { |
240 | check_doc_test( | 255 | check_doc_test( |
241 | "extract_struct_from_enum_variant", | 256 | "extract_struct_from_enum_variant", |
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index 049f808dc..3ad30f0c9 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -619,6 +619,7 @@ fn test_fn() { | |||
619 | ), | 619 | ), |
620 | path: "foo.rs", | 620 | path: "foo.rs", |
621 | }, | 621 | }, |
622 | initial_contents: "", | ||
622 | }, | 623 | }, |
623 | ], | 624 | ], |
624 | is_snippet: false, | 625 | is_snippet: false, |
diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs index e8b896623..d79f5c170 100644 --- a/crates/ide/src/diagnostics/fixes.rs +++ b/crates/ide/src/diagnostics/fixes.rs | |||
@@ -40,6 +40,7 @@ impl DiagnosticWithFix for UnresolvedModule { | |||
40 | anchor: self.file.original_file(sema.db), | 40 | anchor: self.file.original_file(sema.db), |
41 | path: self.candidate.clone(), | 41 | path: self.candidate.clone(), |
42 | }, | 42 | }, |
43 | initial_contents: "".to_string(), | ||
43 | } | 44 | } |
44 | .into(), | 45 | .into(), |
45 | unresolved_module.syntax().text_range(), | 46 | unresolved_module.syntax().text_range(), |
diff --git a/crates/ide_db/src/source_change.rs b/crates/ide_db/src/source_change.rs index e87d98dad..10c0abdac 100644 --- a/crates/ide_db/src/source_change.rs +++ b/crates/ide_db/src/source_change.rs | |||
@@ -44,7 +44,7 @@ impl From<Vec<SourceFileEdit>> for SourceChange { | |||
44 | 44 | ||
45 | #[derive(Debug, Clone)] | 45 | #[derive(Debug, Clone)] |
46 | pub enum FileSystemEdit { | 46 | pub enum FileSystemEdit { |
47 | CreateFile { dst: AnchoredPathBuf }, | 47 | CreateFile { dst: AnchoredPathBuf, initial_contents: String }, |
48 | MoveFile { src: FileId, dst: AnchoredPathBuf }, | 48 | MoveFile { src: FileId, dst: AnchoredPathBuf }, |
49 | } | 49 | } |
50 | 50 | ||
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index e0561b5a7..5a1ae96aa 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -634,30 +634,47 @@ pub(crate) fn snippet_text_document_edit( | |||
634 | Ok(lsp_ext::SnippetTextDocumentEdit { text_document, edits }) | 634 | Ok(lsp_ext::SnippetTextDocumentEdit { text_document, edits }) |
635 | } | 635 | } |
636 | 636 | ||
637 | pub(crate) fn resource_op( | 637 | pub(crate) fn snippet_text_document_ops( |
638 | snap: &GlobalStateSnapshot, | 638 | snap: &GlobalStateSnapshot, |
639 | file_system_edit: FileSystemEdit, | 639 | file_system_edit: FileSystemEdit, |
640 | ) -> lsp_types::ResourceOp { | 640 | ) -> Vec<lsp_ext::SnippetDocumentChangeOperation> { |
641 | let mut ops = Vec::new(); | ||
641 | match file_system_edit { | 642 | match file_system_edit { |
642 | FileSystemEdit::CreateFile { dst } => { | 643 | FileSystemEdit::CreateFile { dst, initial_contents } => { |
643 | let uri = snap.anchored_path(&dst); | 644 | let uri = snap.anchored_path(&dst); |
644 | lsp_types::ResourceOp::Create(lsp_types::CreateFile { | 645 | let create_file = lsp_types::ResourceOp::Create(lsp_types::CreateFile { |
645 | uri, | 646 | uri: uri.clone(), |
646 | options: None, | 647 | options: None, |
647 | annotation_id: None, | 648 | annotation_id: None, |
648 | }) | 649 | }); |
650 | ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(create_file)); | ||
651 | if !initial_contents.is_empty() { | ||
652 | let text_document = | ||
653 | lsp_types::OptionalVersionedTextDocumentIdentifier { uri, version: None }; | ||
654 | let range = range(&LineIndex::new(""), TextRange::empty(TextSize::from(0))); | ||
655 | let text_edit = lsp_ext::SnippetTextEdit { | ||
656 | range, | ||
657 | new_text: initial_contents, | ||
658 | insert_text_format: Some(lsp_types::InsertTextFormat::PlainText), | ||
659 | }; | ||
660 | let edit_file = | ||
661 | lsp_ext::SnippetTextDocumentEdit { text_document, edits: vec![text_edit] }; | ||
662 | ops.push(lsp_ext::SnippetDocumentChangeOperation::Edit(edit_file)); | ||
663 | } | ||
649 | } | 664 | } |
650 | FileSystemEdit::MoveFile { src, dst } => { | 665 | FileSystemEdit::MoveFile { src, dst } => { |
651 | let old_uri = snap.file_id_to_url(src); | 666 | let old_uri = snap.file_id_to_url(src); |
652 | let new_uri = snap.anchored_path(&dst); | 667 | let new_uri = snap.anchored_path(&dst); |
653 | lsp_types::ResourceOp::Rename(lsp_types::RenameFile { | 668 | let rename_file = lsp_types::ResourceOp::Rename(lsp_types::RenameFile { |
654 | old_uri, | 669 | old_uri, |
655 | new_uri, | 670 | new_uri, |
656 | options: None, | 671 | options: None, |
657 | annotation_id: None, | 672 | annotation_id: None, |
658 | }) | 673 | }); |
674 | ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(rename_file)) | ||
659 | } | 675 | } |
660 | } | 676 | } |
677 | ops | ||
661 | } | 678 | } |
662 | 679 | ||
663 | pub(crate) fn snippet_workspace_edit( | 680 | pub(crate) fn snippet_workspace_edit( |
@@ -666,8 +683,8 @@ pub(crate) fn snippet_workspace_edit( | |||
666 | ) -> Result<lsp_ext::SnippetWorkspaceEdit> { | 683 | ) -> Result<lsp_ext::SnippetWorkspaceEdit> { |
667 | let mut document_changes: Vec<lsp_ext::SnippetDocumentChangeOperation> = Vec::new(); | 684 | let mut document_changes: Vec<lsp_ext::SnippetDocumentChangeOperation> = Vec::new(); |
668 | for op in source_change.file_system_edits { | 685 | for op in source_change.file_system_edits { |
669 | let op = resource_op(&snap, op); | 686 | let ops = snippet_text_document_ops(snap, op); |
670 | document_changes.push(lsp_ext::SnippetDocumentChangeOperation::Op(op)); | 687 | document_changes.extend_from_slice(&ops); |
671 | } | 688 | } |
672 | for edit in source_change.source_file_edits { | 689 | for edit in source_change.source_file_edits { |
673 | let edit = snippet_text_document_edit(&snap, source_change.is_snippet, edit)?; | 690 | let edit = snippet_text_document_edit(&snap, source_change.is_snippet, edit)?; |
diff --git a/editors/code/.vscodeignore b/editors/code/.vscodeignore index 5096ce4da..c1cf00fa0 100644 --- a/editors/code/.vscodeignore +++ b/editors/code/.vscodeignore | |||
@@ -4,6 +4,5 @@ | |||
4 | !package.json | 4 | !package.json |
5 | !package-lock.json | 5 | !package-lock.json |
6 | !ra_syntax_tree.tmGrammar.json | 6 | !ra_syntax_tree.tmGrammar.json |
7 | !rust.tmGrammar.json | ||
8 | !icon.png | 7 | !icon.png |
9 | !README.md | 8 | !README.md |
diff --git a/editors/code/package.json b/editors/code/package.json index ad01fea7b..abcc84eda 100644 --- a/editors/code/package.json +++ b/editors/code/package.json | |||
@@ -749,11 +749,6 @@ | |||
749 | ], | 749 | ], |
750 | "grammars": [ | 750 | "grammars": [ |
751 | { | 751 | { |
752 | "language": "rust", | ||
753 | "scopeName": "source.rust", | ||
754 | "path": "rust.tmGrammar.json" | ||
755 | }, | ||
756 | { | ||
757 | "language": "ra_syntax_tree", | 752 | "language": "ra_syntax_tree", |
758 | "scopeName": "source.ra_syntax_tree", | 753 | "scopeName": "source.ra_syntax_tree", |
759 | "path": "ra_syntax_tree.tmGrammar.json" | 754 | "path": "ra_syntax_tree.tmGrammar.json" |
diff --git a/editors/code/rust.tmGrammar.json b/editors/code/rust.tmGrammar.json deleted file mode 100644 index 4759bb116..000000000 --- a/editors/code/rust.tmGrammar.json +++ /dev/null | |||
@@ -1,1140 +0,0 @@ | |||
1 | { | ||
2 | "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", | ||
3 | "name": "Rust", | ||
4 | "fileTypes": [ | ||
5 | "rs" | ||
6 | ], | ||
7 | "scopeName": "source.rust", | ||
8 | "patterns": [ | ||
9 | { | ||
10 | "comment": "boxed slice literal", | ||
11 | "begin": "(<)(\\[)", | ||
12 | "beginCaptures": { | ||
13 | "1": { | ||
14 | "name": "punctuation.brackets.angle.rust" | ||
15 | }, | ||
16 | "2": { | ||
17 | "name": "punctuation.brackets.square.rust" | ||
18 | } | ||
19 | }, | ||
20 | "end": ">", | ||
21 | "endCaptures": { | ||
22 | "0": { | ||
23 | "name": "punctuation.brackets.angle.rust" | ||
24 | } | ||
25 | }, | ||
26 | "patterns": [ | ||
27 | { | ||
28 | "include": "#block-comments" | ||
29 | }, | ||
30 | { | ||
31 | "include": "#comments" | ||
32 | }, | ||
33 | { | ||
34 | "include": "#gtypes" | ||
35 | }, | ||
36 | { | ||
37 | "include": "#lvariables" | ||
38 | }, | ||
39 | { | ||
40 | "include": "#lifetimes" | ||
41 | }, | ||
42 | { | ||
43 | "include": "#punctuation" | ||
44 | }, | ||
45 | { | ||
46 | "include": "#types" | ||
47 | } | ||
48 | ] | ||
49 | }, | ||
50 | { | ||
51 | "comment": "macro type metavariables", | ||
52 | "name": "meta.macro.metavariable.type.rust", | ||
53 | "match": "(\\$)((crate)|([A-Z][A-Za-z0-9_]*))((:)(block|expr|ident|item|lifetime|literal|meta|path?|stmt|tt|ty|vis))?", | ||
54 | "captures": { | ||
55 | "1": { | ||
56 | "name": "keyword.operator.macro.dollar.rust" | ||
57 | }, | ||
58 | "3": { | ||
59 | "name": "keyword.other.crate.rust" | ||
60 | }, | ||
61 | "4": { | ||
62 | "name": "entity.name.type.metavariable.rust" | ||
63 | }, | ||
64 | "6": { | ||
65 | "name": "keyword.operator.key-value.rust" | ||
66 | }, | ||
67 | "7": { | ||
68 | "name": "variable.other.metavariable.specifier.rust" | ||
69 | } | ||
70 | }, | ||
71 | "patterns": [ | ||
72 | { | ||
73 | "include": "#keywords" | ||
74 | } | ||
75 | ] | ||
76 | }, | ||
77 | { | ||
78 | "comment": "macro metavariables", | ||
79 | "name": "meta.macro.metavariable.rust", | ||
80 | "match": "(\\$)([a-z][A-Za-z0-9_]*)((:)(block|expr|ident|item|lifetime|literal|meta|path?|stmt|tt|ty|vis))?", | ||
81 | "captures": { | ||
82 | "1": { | ||
83 | "name": "keyword.operator.macro.dollar.rust" | ||
84 | }, | ||
85 | "2": { | ||
86 | "name": "variable.other.metavariable.name.rust" | ||
87 | }, | ||
88 | "4": { | ||
89 | "name": "keyword.operator.key-value.rust" | ||
90 | }, | ||
91 | "5": { | ||
92 | "name": "variable.other.metavariable.specifier.rust" | ||
93 | } | ||
94 | }, | ||
95 | "patterns": [ | ||
96 | { | ||
97 | "include": "#keywords" | ||
98 | } | ||
99 | ] | ||
100 | }, | ||
101 | { | ||
102 | "comment": "macro rules", | ||
103 | "name": "meta.macro.rules.rust", | ||
104 | "match": "\\b(macro_rules!)\\s+(([a-z0-9_]+)|([A-Z][a-z0-9_]*))\\s+(\\{)", | ||
105 | "captures": { | ||
106 | "1": { | ||
107 | "name": "entity.name.function.macro.rules.rust" | ||
108 | }, | ||
109 | "3": { | ||
110 | "name": "entity.name.function.macro.rust" | ||
111 | }, | ||
112 | "4": { | ||
113 | "name": "entity.name.type.macro.rust" | ||
114 | }, | ||
115 | "5": { | ||
116 | "name": "punctuation.brackets.curly.rust" | ||
117 | } | ||
118 | } | ||
119 | }, | ||
120 | { | ||
121 | "comment": "attributes", | ||
122 | "name": "meta.attribute.rust", | ||
123 | "begin": "(#)(\\!?)(\\[)", | ||
124 | "beginCaptures": { | ||
125 | "1": { | ||
126 | "name": "punctuation.definition.attribute.rust" | ||
127 | }, | ||
128 | "2": { | ||
129 | "name": "keyword.operator.attribute.inner.rust" | ||
130 | }, | ||
131 | "3": { | ||
132 | "name": "punctuation.brackets.attribute.rust" | ||
133 | } | ||
134 | }, | ||
135 | "end": "\\]", | ||
136 | "endCaptures": { | ||
137 | "0": { | ||
138 | "name": "punctuation.brackets.attribute.rust" | ||
139 | } | ||
140 | }, | ||
141 | "patterns": [ | ||
142 | { | ||
143 | "include": "#block-comments" | ||
144 | }, | ||
145 | { | ||
146 | "include": "#comments" | ||
147 | }, | ||
148 | { | ||
149 | "include": "#keywords" | ||
150 | }, | ||
151 | { | ||
152 | "include": "#punctuation" | ||
153 | }, | ||
154 | { | ||
155 | "include": "#strings" | ||
156 | }, | ||
157 | { | ||
158 | "include": "#gtypes" | ||
159 | }, | ||
160 | { | ||
161 | "include": "#types" | ||
162 | } | ||
163 | ] | ||
164 | }, | ||
165 | { | ||
166 | "comment": "modules", | ||
167 | "match": "(mod)\\s+((?:r#(?!crate|[Ss]elf|super))?[a-z][A-Za-z0-9_]*)", | ||
168 | "captures": { | ||
169 | "1": { | ||
170 | "name": "storage.type.rust" | ||
171 | }, | ||
172 | "2": { | ||
173 | "name": "entity.name.module.rust" | ||
174 | } | ||
175 | } | ||
176 | }, | ||
177 | { | ||
178 | "comment": "external crate imports", | ||
179 | "name": "meta.import.rust", | ||
180 | "begin": "\\b(extern)\\s+(crate)", | ||
181 | "beginCaptures": { | ||
182 | "1": { | ||
183 | "name": "storage.type.rust" | ||
184 | }, | ||
185 | "2": { | ||
186 | "name": "keyword.other.crate.rust" | ||
187 | } | ||
188 | }, | ||
189 | "end": ";", | ||
190 | "endCaptures": { | ||
191 | "0": { | ||
192 | "name": "punctuation.semi.rust" | ||
193 | } | ||
194 | }, | ||
195 | "patterns": [ | ||
196 | { | ||
197 | "include": "#block-comments" | ||
198 | }, | ||
199 | { | ||
200 | "include": "#comments" | ||
201 | }, | ||
202 | { | ||
203 | "include": "#keywords" | ||
204 | }, | ||
205 | { | ||
206 | "include": "#punctuation" | ||
207 | } | ||
208 | ] | ||
209 | }, | ||
210 | { | ||
211 | "comment": "use statements", | ||
212 | "name": "meta.use.rust", | ||
213 | "begin": "\\b(use)\\s", | ||
214 | "beginCaptures": { | ||
215 | "1": { | ||
216 | "name": "keyword.other.rust" | ||
217 | } | ||
218 | }, | ||
219 | "end": ";", | ||
220 | "endCaptures": { | ||
221 | "0": { | ||
222 | "name": "punctuation.semi.rust" | ||
223 | } | ||
224 | }, | ||
225 | "patterns": [ | ||
226 | { | ||
227 | "include": "#block-comments" | ||
228 | }, | ||
229 | { | ||
230 | "include": "#comments" | ||
231 | }, | ||
232 | { | ||
233 | "include": "#keywords" | ||
234 | }, | ||
235 | { | ||
236 | "include": "#namespaces" | ||
237 | }, | ||
238 | { | ||
239 | "include": "#punctuation" | ||
240 | }, | ||
241 | { | ||
242 | "include": "#types" | ||
243 | }, | ||
244 | { | ||
245 | "include": "#lvariables" | ||
246 | } | ||
247 | ] | ||
248 | }, | ||
249 | { | ||
250 | "include": "#block-comments" | ||
251 | }, | ||
252 | { | ||
253 | "include": "#comments" | ||
254 | }, | ||
255 | { | ||
256 | "include": "#lvariables" | ||
257 | }, | ||
258 | { | ||
259 | "include": "#constants" | ||
260 | }, | ||
261 | { | ||
262 | "include": "#gtypes" | ||
263 | }, | ||
264 | { | ||
265 | "include": "#functions" | ||
266 | }, | ||
267 | { | ||
268 | "include": "#types" | ||
269 | }, | ||
270 | { | ||
271 | "include": "#keywords" | ||
272 | }, | ||
273 | { | ||
274 | "include": "#lifetimes" | ||
275 | }, | ||
276 | { | ||
277 | "include": "#macros" | ||
278 | }, | ||
279 | { | ||
280 | "include": "#namespaces" | ||
281 | }, | ||
282 | { | ||
283 | "include": "#punctuation" | ||
284 | }, | ||
285 | { | ||
286 | "include": "#strings" | ||
287 | }, | ||
288 | { | ||
289 | "include": "#variables" | ||
290 | } | ||
291 | ], | ||
292 | "repository": { | ||
293 | "comments": { | ||
294 | "patterns": [ | ||
295 | { | ||
296 | "comment": "documentation comments", | ||
297 | "name": "comment.line.documentation.rust", | ||
298 | "match": "^\\s*///.*" | ||
299 | }, | ||
300 | { | ||
301 | "comment": "line comments", | ||
302 | "name": "comment.line.double-slash.rust", | ||
303 | "match": "\\s*//.*" | ||
304 | } | ||
305 | ] | ||
306 | }, | ||
307 | "block-comments": { | ||
308 | "patterns": [ | ||
309 | { | ||
310 | "comment": "empty block comments", | ||
311 | "name": "comment.block.rust", | ||
312 | "match": "/\\*\\*/" | ||
313 | }, | ||
314 | { | ||
315 | "comment": "block documentation comments", | ||
316 | "name": "comment.block.documentation.rust", | ||
317 | "begin": "/\\*\\*", | ||
318 | "end": "\\*/", | ||
319 | "patterns": [ | ||
320 | { | ||
321 | "include": "#block-comments" | ||
322 | } | ||
323 | ] | ||
324 | }, | ||
325 | { | ||
326 | "comment": "block comments", | ||
327 | "name": "comment.block.rust", | ||
328 | "begin": "/\\*(?!\\*)", | ||
329 | "end": "\\*/", | ||
330 | "patterns": [ | ||
331 | { | ||
332 | "include": "#block-comments" | ||
333 | } | ||
334 | ] | ||
335 | } | ||
336 | ] | ||
337 | }, | ||
338 | "constants": { | ||
339 | "patterns": [ | ||
340 | { | ||
341 | "comment": "ALL CAPS constants", | ||
342 | "name": "constant.other.caps.rust", | ||
343 | "match": "\\b[A-Z]{2}[A-Z0-9_]*\\b" | ||
344 | }, | ||
345 | { | ||
346 | "comment": "constant declarations", | ||
347 | "match": "\\b(const)\\s+([A-Z][A-Za-z0-9_]*)\\b", | ||
348 | "captures": { | ||
349 | "1": { | ||
350 | "name": "storage.type.rust" | ||
351 | }, | ||
352 | "2": { | ||
353 | "name": "constant.other.caps.rust" | ||
354 | } | ||
355 | } | ||
356 | }, | ||
357 | { | ||
358 | "comment": "decimal integers and floats", | ||
359 | "name": "constant.numeric.decimal.rust", | ||
360 | "match": "\\b\\d[\\d_]*(\\.?)[\\d_]*(?:(E)([+-])([\\d_]+))?(f32|f64|i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)?\\b", | ||
361 | "captures": { | ||
362 | "1": { | ||
363 | "name": "punctuation.separator.dot.decimal.rust" | ||
364 | }, | ||
365 | "2": { | ||
366 | "name": "keyword.operator.exponent.rust" | ||
367 | }, | ||
368 | "3": { | ||
369 | "name": "keyword.operator.exponent.sign.rust" | ||
370 | }, | ||
371 | "4": { | ||
372 | "name": "constant.numeric.decimal.exponent.mantissa.rust" | ||
373 | }, | ||
374 | "5": { | ||
375 | "name": "entity.name.type.numeric.rust" | ||
376 | } | ||
377 | } | ||
378 | }, | ||
379 | { | ||
380 | "comment": "hexadecimal integers", | ||
381 | "name": "constant.numeric.hex.rust", | ||
382 | "match": "\\b0x[\\da-fA-F_]+(i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)?\\b", | ||
383 | "captures": { | ||
384 | "1": { | ||
385 | "name": "entity.name.type.numeric.rust" | ||
386 | } | ||
387 | } | ||
388 | }, | ||
389 | { | ||
390 | "comment": "octal integers", | ||
391 | "name": "constant.numeric.oct.rust", | ||
392 | "match": "\\b0o[0-7_]+(i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)?\\b", | ||
393 | "captures": { | ||
394 | "1": { | ||
395 | "name": "entity.name.type.numeric.rust" | ||
396 | } | ||
397 | } | ||
398 | }, | ||
399 | { | ||
400 | "comment": "binary integers", | ||
401 | "name": "constant.numeric.bin.rust", | ||
402 | "match": "\\b0b[01_]+(i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)?\\b", | ||
403 | "captures": { | ||
404 | "1": { | ||
405 | "name": "entity.name.type.numeric.rust" | ||
406 | } | ||
407 | } | ||
408 | }, | ||
409 | { | ||
410 | "comment": "booleans", | ||
411 | "name": "constant.language.bool.rust", | ||
412 | "match": "\\b(true|false)\\b" | ||
413 | } | ||
414 | ] | ||
415 | }, | ||
416 | "escapes": { | ||
417 | "comment": "escapes: ASCII, byte, Unicode, quote, regex", | ||
418 | "name": "constant.character.escape.rust", | ||
419 | "match": "(\\\\)(?:(?:(x[0-7][0-7a-fA-F])|(u(\\{)[\\da-fA-F]{4,6}(\\}))|.))", | ||
420 | "captures": { | ||
421 | "1": { | ||
422 | "name": "constant.character.escape.backslash.rust" | ||
423 | }, | ||
424 | "2": { | ||
425 | "name": "constant.character.escape.bit.rust" | ||
426 | }, | ||
427 | "3": { | ||
428 | "name": "constant.character.escape.unicode.rust" | ||
429 | }, | ||
430 | "4": { | ||
431 | "name": "constant.character.escape.unicode.punctuation.rust" | ||
432 | }, | ||
433 | "5": { | ||
434 | "name": "constant.character.escape.unicode.punctuation.rust" | ||
435 | } | ||
436 | } | ||
437 | }, | ||
438 | "functions": { | ||
439 | "patterns": [ | ||
440 | { | ||
441 | "comment": "pub as a function", | ||
442 | "match": "\\b(pub)(\\()", | ||
443 | "captures": { | ||
444 | "1": { | ||
445 | "name": "keyword.other.rust" | ||
446 | }, | ||
447 | "2": { | ||
448 | "name": "punctuation.brackets.round.rust" | ||
449 | } | ||
450 | } | ||
451 | }, | ||
452 | { | ||
453 | "comment": "function definition", | ||
454 | "name": "meta.function.definition.rust", | ||
455 | "begin": "\\b(fn)\\s+((?:r#(?!crate|[Ss]elf|super))?[A-Za-z0-9_]+)((\\()|(<))", | ||
456 | "beginCaptures": { | ||
457 | "1": { | ||
458 | "name": "keyword.other.fn.rust" | ||
459 | }, | ||
460 | "2": { | ||
461 | "name": "entity.name.function.rust" | ||
462 | }, | ||
463 | "4": { | ||
464 | "name": "punctuation.brackets.round.rust" | ||
465 | }, | ||
466 | "5": { | ||
467 | "name": "punctuation.brackets.angle.rust" | ||
468 | } | ||
469 | }, | ||
470 | "end": "\\{|;", | ||
471 | "endCaptures": { | ||
472 | "0": { | ||
473 | "name": "punctuation.brackets.curly.rust" | ||
474 | } | ||
475 | }, | ||
476 | "patterns": [ | ||
477 | { | ||
478 | "include": "#block-comments" | ||
479 | }, | ||
480 | { | ||
481 | "include": "#comments" | ||
482 | }, | ||
483 | { | ||
484 | "include": "#keywords" | ||
485 | }, | ||
486 | { | ||
487 | "include": "#lvariables" | ||
488 | }, | ||
489 | { | ||
490 | "include": "#constants" | ||
491 | }, | ||
492 | { | ||
493 | "include": "#gtypes" | ||
494 | }, | ||
495 | { | ||
496 | "include": "#functions" | ||
497 | }, | ||
498 | { | ||
499 | "include": "#lifetimes" | ||
500 | }, | ||
501 | { | ||
502 | "include": "#macros" | ||
503 | }, | ||
504 | { | ||
505 | "include": "#namespaces" | ||
506 | }, | ||
507 | { | ||
508 | "include": "#punctuation" | ||
509 | }, | ||
510 | { | ||
511 | "include": "#strings" | ||
512 | }, | ||
513 | { | ||
514 | "include": "#types" | ||
515 | }, | ||
516 | { | ||
517 | "include": "#variables" | ||
518 | } | ||
519 | ] | ||
520 | }, | ||
521 | { | ||
522 | "comment": "function/method calls, chaining", | ||
523 | "name": "meta.function.call.rust", | ||
524 | "begin": "((?:r#(?!crate|[Ss]elf|super))?[A-Za-z0-9_]+)(\\()", | ||
525 | "beginCaptures": { | ||
526 | "1": { | ||
527 | "name": "entity.name.function.rust" | ||
528 | }, | ||
529 | "2": { | ||
530 | "name": "punctuation.brackets.round.rust" | ||
531 | } | ||
532 | }, | ||
533 | "end": "\\)", | ||
534 | "endCaptures": { | ||
535 | "0": { | ||
536 | "name": "punctuation.brackets.round.rust" | ||
537 | } | ||
538 | }, | ||
539 | "patterns": [ | ||
540 | { | ||
541 | "include": "#block-comments" | ||
542 | }, | ||
543 | { | ||
544 | "include": "#comments" | ||
545 | }, | ||
546 | { | ||
547 | "include": "#keywords" | ||
548 | }, | ||
549 | { | ||
550 | "include": "#lvariables" | ||
551 | }, | ||
552 | { | ||
553 | "include": "#constants" | ||
554 | }, | ||
555 | { | ||
556 | "include": "#gtypes" | ||
557 | }, | ||
558 | { | ||
559 | "include": "#functions" | ||
560 | }, | ||
561 | { | ||
562 | "include": "#lifetimes" | ||
563 | }, | ||
564 | { | ||
565 | "include": "#macros" | ||
566 | }, | ||
567 | { | ||
568 | "include": "#namespaces" | ||
569 | }, | ||
570 | { | ||
571 | "include": "#punctuation" | ||
572 | }, | ||
573 | { | ||
574 | "include": "#strings" | ||
575 | }, | ||
576 | { | ||
577 | "include": "#types" | ||
578 | }, | ||
579 | { | ||
580 | "include": "#variables" | ||
581 | } | ||
582 | ] | ||
583 | }, | ||
584 | { | ||
585 | "comment": "function/method calls with turbofish", | ||
586 | "name": "meta.function.call.rust", | ||
587 | "begin": "((?:r#(?!crate|[Ss]elf|super))?[A-Za-z0-9_]+)(?=::<.*>\\()", | ||
588 | "beginCaptures": { | ||
589 | "1": { | ||
590 | "name": "entity.name.function.rust" | ||
591 | } | ||
592 | }, | ||
593 | "end": "\\)", | ||
594 | "endCaptures": { | ||
595 | "0": { | ||
596 | "name": "punctuation.brackets.round.rust" | ||
597 | } | ||
598 | }, | ||
599 | "patterns": [ | ||
600 | { | ||
601 | "include": "#block-comments" | ||
602 | }, | ||
603 | { | ||
604 | "include": "#comments" | ||
605 | }, | ||
606 | { | ||
607 | "include": "#keywords" | ||
608 | }, | ||
609 | { | ||
610 | "include": "#lvariables" | ||
611 | }, | ||
612 | { | ||
613 | "include": "#constants" | ||
614 | }, | ||
615 | { | ||
616 | "include": "#gtypes" | ||
617 | }, | ||
618 | { | ||
619 | "include": "#functions" | ||
620 | }, | ||
621 | { | ||
622 | "include": "#lifetimes" | ||
623 | }, | ||
624 | { | ||
625 | "include": "#macros" | ||
626 | }, | ||
627 | { | ||
628 | "include": "#namespaces" | ||
629 | }, | ||
630 | { | ||
631 | "include": "#punctuation" | ||
632 | }, | ||
633 | { | ||
634 | "include": "#strings" | ||
635 | }, | ||
636 | { | ||
637 | "include": "#types" | ||
638 | }, | ||
639 | { | ||
640 | "include": "#variables" | ||
641 | } | ||
642 | ] | ||
643 | } | ||
644 | ] | ||
645 | }, | ||
646 | "keywords": { | ||
647 | "patterns": [ | ||
648 | { | ||
649 | "comment": "control flow keywords", | ||
650 | "name": "keyword.control.rust", | ||
651 | "match": "\\b(await|break|continue|do|else|for|if|loop|match|return|try|while|yield)\\b" | ||
652 | }, | ||
653 | { | ||
654 | "comment": "storage keywords", | ||
655 | "name": "storage.type.rust", | ||
656 | "match": "\\b(const|enum|extern|let|macro|mod|struct|trait|type)\\b" | ||
657 | }, | ||
658 | { | ||
659 | "comment": "storage modifiers", | ||
660 | "name": "storage.modifier.rust", | ||
661 | "match": "\\b(abstract|static)\\b" | ||
662 | }, | ||
663 | { | ||
664 | "comment": "other keywords", | ||
665 | "name": "keyword.other.rust", | ||
666 | "match": "\\b(as|async|become|box|dyn|move|final|impl|in|override|priv|pub|ref|typeof|union|unsafe|unsized|use|virtual|where)\\b" | ||
667 | }, | ||
668 | { | ||
669 | "comment": "fn", | ||
670 | "name": "keyword.other.fn.rust", | ||
671 | "match": "\\bfn\\b" | ||
672 | }, | ||
673 | { | ||
674 | "comment": "crate", | ||
675 | "name": "keyword.other.crate.rust", | ||
676 | "match": "\\bcrate\\b" | ||
677 | }, | ||
678 | { | ||
679 | "comment": "mut", | ||
680 | "name": "storage.modifier.mut.rust", | ||
681 | "match": "\\bmut\\b" | ||
682 | }, | ||
683 | { | ||
684 | "comment": "logical operators", | ||
685 | "name": "keyword.operator.logical.rust", | ||
686 | "match": "(\\^|\\||\\|\\||&&|<<|>>|!)(?!=)" | ||
687 | }, | ||
688 | { | ||
689 | "comment": "logical AND, borrow references", | ||
690 | "name": "keyword.operator.borrow.and.rust", | ||
691 | "match": "&(?![&=])" | ||
692 | }, | ||
693 | { | ||
694 | "comment": "assignment operators", | ||
695 | "name": "keyword.operator.assignment.rust", | ||
696 | "match": "(\\+=|-=|\\*=|/=|%=|\\^=|&=|\\|=|<<=|>>=)" | ||
697 | }, | ||
698 | { | ||
699 | "comment": "single equal", | ||
700 | "name": "keyword.operator.assignment.equal.rust", | ||
701 | "match": "(?<![<>])=(?!=|>)" | ||
702 | }, | ||
703 | { | ||
704 | "comment": "comparison operators", | ||
705 | "name": "keyword.operator.comparison.rust", | ||
706 | "match": "(=(=)?(?!>)|!=|<=|(?<!=)>=)" | ||
707 | }, | ||
708 | { | ||
709 | "comment": "math operators", | ||
710 | "name": "keyword.operator.math.rust", | ||
711 | "match": "(([+%]|(\\*(?!\\w)))(?!=))|(-(?!>))|(/(?!/))" | ||
712 | }, | ||
713 | { | ||
714 | "comment": "less than, greater than (special case)", | ||
715 | "match": "(?:\\b|(?:(\\))|(\\])|(\\})))[ \\t]+([<>])[ \\t]+(?:\\b|(?:(\\()|(\\[)|(\\{)))", | ||
716 | "captures": { | ||
717 | "1": { | ||
718 | "name": "punctuation.brackets.round.rust" | ||
719 | }, | ||
720 | "2": { | ||
721 | "name": "punctuation.brackets.square.rust" | ||
722 | }, | ||
723 | "3": { | ||
724 | "name": "punctuation.brackets.curly.rust" | ||
725 | }, | ||
726 | "4": { | ||
727 | "name": "keyword.operator.comparison.rust" | ||
728 | }, | ||
729 | "5": { | ||
730 | "name": "punctuation.brackets.round.rust" | ||
731 | }, | ||
732 | "6": { | ||
733 | "name": "punctuation.brackets.square.rust" | ||
734 | }, | ||
735 | "7": { | ||
736 | "name": "punctuation.brackets.curly.rust" | ||
737 | } | ||
738 | } | ||
739 | }, | ||
740 | { | ||
741 | "comment": "namespace operator", | ||
742 | "name": "keyword.operator.namespace.rust", | ||
743 | "match": "::" | ||
744 | }, | ||
745 | { | ||
746 | "comment": "dereference asterisk", | ||
747 | "match": "(\\*)(?=\\w+)", | ||
748 | "captures": { | ||
749 | "1": { | ||
750 | "name": "keyword.operator.dereference.rust" | ||
751 | } | ||
752 | } | ||
753 | }, | ||
754 | { | ||
755 | "comment": "subpattern binding", | ||
756 | "name": "keyword.operator.subpattern.rust", | ||
757 | "match": "@" | ||
758 | }, | ||
759 | { | ||
760 | "comment": "dot access", | ||
761 | "name": "keyword.operator.access.dot.rust", | ||
762 | "match": "\\.(?!\\.)" | ||
763 | }, | ||
764 | { | ||
765 | "comment": "ranges, range patterns", | ||
766 | "name": "keyword.operator.range.rust", | ||
767 | "match": "\\.{2}(=|\\.)?" | ||
768 | }, | ||
769 | { | ||
770 | "comment": "colon", | ||
771 | "name": "keyword.operator.key-value.rust", | ||
772 | "match": ":(?!:)" | ||
773 | }, | ||
774 | { | ||
775 | "comment": "dashrocket, skinny arrow", | ||
776 | "name": "keyword.operator.arrow.skinny.rust", | ||
777 | "match": "->" | ||
778 | }, | ||
779 | { | ||
780 | "comment": "hashrocket, fat arrow", | ||
781 | "name": "keyword.operator.arrow.fat.rust", | ||
782 | "match": "=>" | ||
783 | }, | ||
784 | { | ||
785 | "comment": "dollar macros", | ||
786 | "name": "keyword.operator.macro.dollar.rust", | ||
787 | "match": "\\$" | ||
788 | }, | ||
789 | { | ||
790 | "comment": "question mark operator, questionably sized, macro kleene matcher", | ||
791 | "name": "keyword.operator.question.rust", | ||
792 | "match": "\\?" | ||
793 | } | ||
794 | ] | ||
795 | }, | ||
796 | "interpolations": { | ||
797 | "comment": "curly brace interpolations", | ||
798 | "name": "meta.interpolation.rust", | ||
799 | "match": "({)[^\"{}]*(})", | ||
800 | "captures": { | ||
801 | "1": { | ||
802 | "name": "punctuation.definition.interpolation.rust" | ||
803 | }, | ||
804 | "2": { | ||
805 | "name": "punctuation.definition.interpolation.rust" | ||
806 | } | ||
807 | } | ||
808 | }, | ||
809 | "lifetimes": { | ||
810 | "patterns": [ | ||
811 | { | ||
812 | "comment": "named lifetime parameters", | ||
813 | "match": "(['])([a-zA-Z_][0-9a-zA-Z_]*)(?!['])\\b", | ||
814 | "captures": { | ||
815 | "1": { | ||
816 | "name": "punctuation.definition.lifetime.rust" | ||
817 | }, | ||
818 | "2": { | ||
819 | "name": "entity.name.type.lifetime.rust" | ||
820 | } | ||
821 | } | ||
822 | }, | ||
823 | { | ||
824 | "comment": "borrowing references to named lifetimes", | ||
825 | "match": "(\\&)(['])([a-zA-Z_][0-9a-zA-Z_]*)(?!['])\\b", | ||
826 | "captures": { | ||
827 | "1": { | ||
828 | "name": "keyword.operator.borrow.rust" | ||
829 | }, | ||
830 | "2": { | ||
831 | "name": "punctuation.definition.lifetime.rust" | ||
832 | }, | ||
833 | "3": { | ||
834 | "name": "entity.name.type.lifetime.rust" | ||
835 | } | ||
836 | } | ||
837 | } | ||
838 | ] | ||
839 | }, | ||
840 | "macros": { | ||
841 | "patterns": [ | ||
842 | { | ||
843 | "comment": "macros", | ||
844 | "name": "meta.macro.rust", | ||
845 | "match": "(([a-z_][A-Za-z0-9_]*!)|([A-Z_][A-Za-z0-9_]*!))", | ||
846 | "captures": { | ||
847 | "2": { | ||
848 | "name": "entity.name.function.macro.rust" | ||
849 | }, | ||
850 | "3": { | ||
851 | "name": "entity.name.type.macro.rust" | ||
852 | } | ||
853 | } | ||
854 | } | ||
855 | ] | ||
856 | }, | ||
857 | "namespaces": { | ||
858 | "patterns": [ | ||
859 | { | ||
860 | "comment": "namespace (non-type, non-function path segment)", | ||
861 | "match": "(?<![A-Za-z0-9_])([a-z0-9_]+)((?<!super|self)::)", | ||
862 | "captures": { | ||
863 | "1": { | ||
864 | "name": "entity.name.namespace.rust" | ||
865 | }, | ||
866 | "2": { | ||
867 | "name": "keyword.operator.namespace.rust" | ||
868 | } | ||
869 | } | ||
870 | } | ||
871 | ] | ||
872 | }, | ||
873 | "types": { | ||
874 | "patterns": [ | ||
875 | { | ||
876 | "comment": "numeric types", | ||
877 | "match": "(?<![A-Za-z])(f32|f64|i128|i16|i32|i64|i8|isize|u128|u16|u32|u64|u8|usize)\\b", | ||
878 | "captures": { | ||
879 | "1": { | ||
880 | "name": "entity.name.type.numeric.rust" | ||
881 | } | ||
882 | } | ||
883 | }, | ||
884 | { | ||
885 | "comment": "parameterized types", | ||
886 | "begin": "\\b([A-Z][A-Za-z0-9]*)(<)", | ||
887 | "beginCaptures": { | ||
888 | "1": { | ||
889 | "name": "entity.name.type.rust" | ||
890 | }, | ||
891 | "2": { | ||
892 | "name": "punctuation.brackets.angle.rust" | ||
893 | } | ||
894 | }, | ||
895 | "end": ">", | ||
896 | "endCaptures": { | ||
897 | "0": { | ||
898 | "name": "punctuation.brackets.angle.rust" | ||
899 | } | ||
900 | }, | ||
901 | "patterns": [ | ||
902 | { | ||
903 | "include": "#block-comments" | ||
904 | }, | ||
905 | { | ||
906 | "include": "#comments" | ||
907 | }, | ||
908 | { | ||
909 | "include": "#keywords" | ||
910 | }, | ||
911 | { | ||
912 | "include": "#lvariables" | ||
913 | }, | ||
914 | { | ||
915 | "include": "#lifetimes" | ||
916 | }, | ||
917 | { | ||
918 | "include": "#punctuation" | ||
919 | }, | ||
920 | { | ||
921 | "include": "#types" | ||
922 | }, | ||
923 | { | ||
924 | "include": "#variables" | ||
925 | } | ||
926 | ] | ||
927 | }, | ||
928 | { | ||
929 | "comment": "primitive types", | ||
930 | "name": "entity.name.type.primitive.rust", | ||
931 | "match": "\\b(bool|char|str)\\b" | ||
932 | }, | ||
933 | { | ||
934 | "comment": "trait declarations", | ||
935 | "match": "\\b(trait)\\s+([A-Z][A-Za-z0-9]*)\\b", | ||
936 | "captures": { | ||
937 | "1": { | ||
938 | "name": "storage.type.rust" | ||
939 | }, | ||
940 | "2": { | ||
941 | "name": "entity.name.type.trait.rust" | ||
942 | } | ||
943 | } | ||
944 | }, | ||
945 | { | ||
946 | "comment": "struct declarations", | ||
947 | "match": "\\b(struct)\\s+([A-Z][A-Za-z0-9]*)\\b", | ||
948 | "captures": { | ||
949 | "1": { | ||
950 | "name": "storage.type.rust" | ||
951 | }, | ||
952 | "2": { | ||
953 | "name": "entity.name.type.struct.rust" | ||
954 | } | ||
955 | } | ||
956 | }, | ||
957 | { | ||
958 | "comment": "enum declarations", | ||
959 | "match": "\\b(enum)\\s+([A-Z][A-Za-z0-9_]*)\\b", | ||
960 | "captures": { | ||
961 | "1": { | ||
962 | "name": "storage.type.rust" | ||
963 | }, | ||
964 | "2": { | ||
965 | "name": "entity.name.type.enum.rust" | ||
966 | } | ||
967 | } | ||
968 | }, | ||
969 | { | ||
970 | "comment": "type declarations", | ||
971 | "match": "\\b(type)\\s+([A-Z][A-Za-z0-9_]*)\\b", | ||
972 | "captures": { | ||
973 | "1": { | ||
974 | "name": "storage.type.rust" | ||
975 | }, | ||
976 | "2": { | ||
977 | "name": "entity.name.type.declaration.rust" | ||
978 | } | ||
979 | } | ||
980 | }, | ||
981 | { | ||
982 | "comment": "types", | ||
983 | "name": "entity.name.type.rust", | ||
984 | "match": "\\b[A-Z][A-Za-z0-9]*\\b(?!!)" | ||
985 | } | ||
986 | ] | ||
987 | }, | ||
988 | "gtypes": { | ||
989 | "patterns": [ | ||
990 | { | ||
991 | "comment": "option types", | ||
992 | "name": "entity.name.type.option.rust", | ||
993 | "match": "\\b(Some|None)\\b" | ||
994 | }, | ||
995 | { | ||
996 | "comment": "result types", | ||
997 | "name": "entity.name.type.result.rust", | ||
998 | "match": "\\b(Ok|Err)\\b" | ||
999 | } | ||
1000 | ] | ||
1001 | }, | ||
1002 | "punctuation": { | ||
1003 | "patterns": [ | ||
1004 | { | ||
1005 | "comment": "comma", | ||
1006 | "name": "punctuation.comma.rust", | ||
1007 | "match": "," | ||
1008 | }, | ||
1009 | { | ||
1010 | "comment": "curly braces", | ||
1011 | "name": "punctuation.brackets.curly.rust", | ||
1012 | "match": "[{}]" | ||
1013 | }, | ||
1014 | { | ||
1015 | "comment": "parentheses, round brackets", | ||
1016 | "name": "punctuation.brackets.round.rust", | ||
1017 | "match": "[()]" | ||
1018 | }, | ||
1019 | { | ||
1020 | "comment": "semicolon", | ||
1021 | "name": "punctuation.semi.rust", | ||
1022 | "match": ";" | ||
1023 | }, | ||
1024 | { | ||
1025 | "comment": "square brackets", | ||
1026 | "name": "punctuation.brackets.square.rust", | ||
1027 | "match": "[\\[\\]]" | ||
1028 | }, | ||
1029 | { | ||
1030 | "comment": "angle brackets", | ||
1031 | "name": "punctuation.brackets.angle.rust", | ||
1032 | "match": "(?<!=)[<>]" | ||
1033 | } | ||
1034 | ] | ||
1035 | }, | ||
1036 | "strings": { | ||
1037 | "patterns": [ | ||
1038 | { | ||
1039 | "comment": "double-quoted strings and byte strings", | ||
1040 | "name": "string.quoted.double.rust", | ||
1041 | "begin": "(b?)(\")", | ||
1042 | "beginCaptures": { | ||
1043 | "1": { | ||
1044 | "name": "string.quoted.byte.raw.rust" | ||
1045 | }, | ||
1046 | "2": { | ||
1047 | "name": "punctuation.definition.string.rust" | ||
1048 | } | ||
1049 | }, | ||
1050 | "end": "\"", | ||
1051 | "endCaptures": { | ||
1052 | "0": { | ||
1053 | "name": "punctuation.definition.string.rust" | ||
1054 | } | ||
1055 | }, | ||
1056 | "patterns": [ | ||
1057 | { | ||
1058 | "include": "#escapes" | ||
1059 | }, | ||
1060 | { | ||
1061 | "include": "#interpolations" | ||
1062 | } | ||
1063 | ] | ||
1064 | }, | ||
1065 | { | ||
1066 | "comment": "double-quoted raw strings and raw byte strings", | ||
1067 | "name": "string.quoted.double.rust", | ||
1068 | "begin": "(b?r)(#*)(\")", | ||
1069 | "beginCaptures": { | ||
1070 | "1": { | ||
1071 | "name": "string.quoted.byte.raw.rust" | ||
1072 | }, | ||
1073 | "2": { | ||
1074 | "name": "punctuation.definition.string.raw.rust" | ||
1075 | }, | ||
1076 | "3": { | ||
1077 | "name": "punctuation.definition.string.rust" | ||
1078 | } | ||
1079 | }, | ||
1080 | "end": "(\")(\\2)", | ||
1081 | "endCaptures": { | ||
1082 | "1": { | ||
1083 | "name": "punctuation.definition.string.rust" | ||
1084 | }, | ||
1085 | "2": { | ||
1086 | "name": "punctuation.definition.string.raw.rust" | ||
1087 | } | ||
1088 | } | ||
1089 | }, | ||
1090 | { | ||
1091 | "comment": "characters and bytes", | ||
1092 | "name": "string.quoted.single.char.rust", | ||
1093 | "begin": "(b)?(')", | ||
1094 | "beginCaptures": { | ||
1095 | "1": { | ||
1096 | "name": "string.quoted.byte.raw.rust" | ||
1097 | }, | ||
1098 | "2": { | ||
1099 | "name": "punctuation.definition.char.rust" | ||
1100 | } | ||
1101 | }, | ||
1102 | "end": "'", | ||
1103 | "endCaptures": { | ||
1104 | "0": { | ||
1105 | "name": "punctuation.definition.char.rust" | ||
1106 | } | ||
1107 | }, | ||
1108 | "patterns": [ | ||
1109 | { | ||
1110 | "include": "#escapes" | ||
1111 | } | ||
1112 | ] | ||
1113 | } | ||
1114 | ] | ||
1115 | }, | ||
1116 | "lvariables": { | ||
1117 | "patterns": [ | ||
1118 | { | ||
1119 | "comment": "self", | ||
1120 | "name": "variable.language.self.rust", | ||
1121 | "match": "\\b[Ss]elf\\b" | ||
1122 | }, | ||
1123 | { | ||
1124 | "comment": "super", | ||
1125 | "name": "variable.language.super.rust", | ||
1126 | "match": "\\bsuper\\b" | ||
1127 | } | ||
1128 | ] | ||
1129 | }, | ||
1130 | "variables": { | ||
1131 | "patterns": [ | ||
1132 | { | ||
1133 | "comment": "variables", | ||
1134 | "name": "variable.other.rust", | ||
1135 | "match": "\\b(?<!(?<!\\.)\\.)(?:r#(?!(crate|[Ss]elf|super)))?[a-z0-9_]+\\b" | ||
1136 | } | ||
1137 | ] | ||
1138 | } | ||
1139 | } | ||
1140 | } | ||
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index 92bc4d7f7..9d4823a34 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts | |||
@@ -470,7 +470,7 @@ export function resolveCodeAction(ctx: Ctx): Cmd { | |||
470 | return; | 470 | return; |
471 | } | 471 | } |
472 | const edit = client.protocol2CodeConverter.asWorkspaceEdit(item.edit); | 472 | const edit = client.protocol2CodeConverter.asWorkspaceEdit(item.edit); |
473 | await applySnippetWorkspaceEdit(edit); | 473 | await vscode.workspace.applyEdit(edit); |
474 | }; | 474 | }; |
475 | } | 475 | } |
476 | 476 | ||
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 4eaaed62b..4b2d3c8a5 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts | |||
@@ -19,9 +19,8 @@ let ctx: Ctx | undefined; | |||
19 | const RUST_PROJECT_CONTEXT_NAME = "inRustProject"; | 19 | const RUST_PROJECT_CONTEXT_NAME = "inRustProject"; |
20 | 20 | ||
21 | export async function activate(context: vscode.ExtensionContext) { | 21 | export async function activate(context: vscode.ExtensionContext) { |
22 | // For some reason vscode not always shows pop-up error notifications | 22 | // VS Code doesn't show a notification when an extension fails to activate |
23 | // when an extension fails to activate, so we do it explicitly by ourselves. | 23 | // so we do it ourselves. |
24 | // FIXME: remove this bit of code once vscode fixes this issue: https://github.com/microsoft/vscode/issues/101242 | ||
25 | await tryActivate(context).catch(err => { | 24 | await tryActivate(context).catch(err => { |
26 | void vscode.window.showErrorMessage(`Cannot activate rust-analyzer: ${err.message}`); | 25 | void vscode.window.showErrorMessage(`Cannot activate rust-analyzer: ${err.message}`); |
27 | throw err; | 26 | throw err; |
@@ -292,6 +291,8 @@ async function getServer(config: Config, state: PersistentState): Promise<string | |||
292 | if (process.platform === "linux") platform = "linux"; | 291 | if (process.platform === "linux") platform = "linux"; |
293 | if (process.platform === "darwin") platform = "mac"; | 292 | if (process.platform === "darwin") platform = "mac"; |
294 | if (process.platform === "win32") platform = "windows"; | 293 | if (process.platform === "win32") platform = "windows"; |
294 | } else if (process.arch === "arm64" && process.platform === "darwin") { | ||
295 | platform = "mac"; | ||
295 | } | 296 | } |
296 | if (platform === undefined) { | 297 | if (platform === undefined) { |
297 | vscode.window.showErrorMessage( | 298 | vscode.window.showErrorMessage( |