diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/libeditor/src/code_actions.rs | 32 | ||||
-rw-r--r-- | crates/libeditor/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/libeditor/tests/test.rs | 16 | ||||
-rw-r--r-- | crates/libsyntax2/src/ast/generated.rs | 3 | ||||
-rw-r--r-- | crates/libsyntax2/src/grammar.ron | 6 |
5 files changed, 54 insertions, 5 deletions
diff --git a/crates/libeditor/src/code_actions.rs b/crates/libeditor/src/code_actions.rs index 500d52c2a..1e20c0f48 100644 --- a/crates/libeditor/src/code_actions.rs +++ b/crates/libeditor/src/code_actions.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use {TextUnit, EditBuilder, Edit}; | 1 | use {TextUnit, EditBuilder, Edit}; |
2 | use libsyntax2::{ | 2 | use libsyntax2::{ |
3 | ast::{self, AstNode, AttrsOwner, ParsedFile}, | 3 | ast::{self, AstNode, AttrsOwner, TypeParamsOwner, NameOwner, ParsedFile}, |
4 | SyntaxKind::COMMA, | 4 | SyntaxKind::COMMA, |
5 | SyntaxNodeRef, | 5 | SyntaxNodeRef, |
6 | algo::{ | 6 | algo::{ |
@@ -58,6 +58,36 @@ pub fn add_derive<'a>(file: &'a ParsedFile, offset: TextUnit) -> Option<impl FnO | |||
58 | }) | 58 | }) |
59 | } | 59 | } |
60 | 60 | ||
61 | pub fn add_impl<'a>(file: &'a ParsedFile, offset: TextUnit) -> Option<impl FnOnce() -> ActionResult + 'a> { | ||
62 | let nominal = find_node::<ast::NominalDef>(file.syntax(), offset)?; | ||
63 | let name = nominal.name()?; | ||
64 | |||
65 | Some(move || { | ||
66 | // let type_params = nominal.type_param_list(); | ||
67 | // let type_args = match type_params { | ||
68 | // None => String::new(), | ||
69 | // Some(params) => { | ||
70 | // let mut buf = String::new(); | ||
71 | // } | ||
72 | // }; | ||
73 | let mut edit = EditBuilder::new(); | ||
74 | let start_offset = nominal.syntax().range().end(); | ||
75 | edit.insert( | ||
76 | start_offset, | ||
77 | format!( | ||
78 | "\n\nimpl {} {{\n\n}}", | ||
79 | name.text(), | ||
80 | ) | ||
81 | ); | ||
82 | ActionResult { | ||
83 | edit: edit.finish(), | ||
84 | cursor_position: Some( | ||
85 | start_offset + TextUnit::of_str("\n\nimpl {\n") + name.syntax().range().len() | ||
86 | ), | ||
87 | } | ||
88 | }) | ||
89 | } | ||
90 | |||
61 | fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> { | 91 | fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> { |
62 | siblings(node, direction) | 92 | siblings(node, direction) |
63 | .skip(1) | 93 | .skip(1) |
diff --git a/crates/libeditor/src/lib.rs b/crates/libeditor/src/lib.rs index 12d0a30dd..6bae7a3fa 100644 --- a/crates/libeditor/src/lib.rs +++ b/crates/libeditor/src/lib.rs | |||
@@ -22,7 +22,7 @@ pub use self::{ | |||
22 | edit::{EditBuilder, Edit, AtomEdit}, | 22 | edit::{EditBuilder, Edit, AtomEdit}, |
23 | code_actions::{ | 23 | code_actions::{ |
24 | ActionResult, find_node, | 24 | ActionResult, find_node, |
25 | flip_comma, add_derive, | 25 | flip_comma, add_derive, add_impl, |
26 | }, | 26 | }, |
27 | }; | 27 | }; |
28 | 28 | ||
diff --git a/crates/libeditor/tests/test.rs b/crates/libeditor/tests/test.rs index 4f4b4b773..3b0ec78eb 100644 --- a/crates/libeditor/tests/test.rs +++ b/crates/libeditor/tests/test.rs | |||
@@ -7,7 +7,7 @@ use assert_eq_text::{assert_eq_dbg}; | |||
7 | use libeditor::{ | 7 | use libeditor::{ |
8 | ParsedFile, TextUnit, TextRange, ActionResult, | 8 | ParsedFile, TextUnit, TextRange, ActionResult, |
9 | highlight, runnables, extend_selection, file_structure, | 9 | highlight, runnables, extend_selection, file_structure, |
10 | flip_comma, add_derive, matching_brace, | 10 | flip_comma, add_derive, add_impl, matching_brace, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | #[test] | 13 | #[test] |
@@ -145,6 +145,20 @@ fn test_add_derive() { | |||
145 | } | 145 | } |
146 | 146 | ||
147 | #[test] | 147 | #[test] |
148 | fn test_add_impl() { | ||
149 | check_action( | ||
150 | "struct Foo {<|>}\n", | ||
151 | "struct Foo {}\n\nimpl Foo {\n<|>\n}\n", | ||
152 | |file, off| add_impl(file, off).map(|f| f()), | ||
153 | ); | ||
154 | // check_action( | ||
155 | // "struct Foo<T: Clone> {<|>}", | ||
156 | // "struct Foo<T: Clone> {}\nimpl<T: Clone> Foo<T> {\n<|>\n}", | ||
157 | // |file, off| add_impl(file, off).map(|f| f()), | ||
158 | // ); | ||
159 | } | ||
160 | |||
161 | #[test] | ||
148 | fn test_matching_brace() { | 162 | fn test_matching_brace() { |
149 | fn do_check(before: &str, after: &str) { | 163 | fn do_check(before: &str, after: &str) { |
150 | let (pos, before) = extract_cursor(before); | 164 | let (pos, before) = extract_cursor(before); |
diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs index 0f53e8f4a..6df1d2311 100644 --- a/crates/libsyntax2/src/ast/generated.rs +++ b/crates/libsyntax2/src/ast/generated.rs | |||
@@ -344,8 +344,9 @@ impl<'a> AstNode<'a> for NominalDef<'a> { | |||
344 | } | 344 | } |
345 | } | 345 | } |
346 | 346 | ||
347 | impl<'a> ast::AttrsOwner<'a> for NominalDef<'a> {} | 347 | impl<'a> ast::NameOwner<'a> for NominalDef<'a> {} |
348 | impl<'a> ast::TypeParamsOwner<'a> for NominalDef<'a> {} | 348 | impl<'a> ast::TypeParamsOwner<'a> for NominalDef<'a> {} |
349 | impl<'a> ast::AttrsOwner<'a> for NominalDef<'a> {} | ||
349 | impl<'a> NominalDef<'a> {} | 350 | impl<'a> NominalDef<'a> {} |
350 | 351 | ||
351 | // ParenType | 352 | // ParenType |
diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron index 83b56c349..e56496be1 100644 --- a/crates/libsyntax2/src/grammar.ron +++ b/crates/libsyntax2/src/grammar.ron | |||
@@ -299,7 +299,11 @@ Grammar( | |||
299 | 299 | ||
300 | "NominalDef": ( | 300 | "NominalDef": ( |
301 | enum: ["StructDef", "EnumDef"], | 301 | enum: ["StructDef", "EnumDef"], |
302 | traits: [ "AttrsOwner", "TypeParamsOwner" ], | 302 | traits: [ |
303 | "NameOwner", | ||
304 | "TypeParamsOwner", | ||
305 | "AttrsOwner" | ||
306 | ], | ||
303 | ), | 307 | ), |
304 | 308 | ||
305 | "Name": (), | 309 | "Name": (), |