diff options
Diffstat (limited to 'crates/libeditor')
-rw-r--r-- | crates/libeditor/src/code_actions.rs | 28 | ||||
-rw-r--r-- | crates/libeditor/tests/test.rs | 7 |
2 files changed, 25 insertions, 10 deletions
diff --git a/crates/libeditor/src/code_actions.rs b/crates/libeditor/src/code_actions.rs index 4987964d2..6df64be12 100644 --- a/crates/libeditor/src/code_actions.rs +++ b/crates/libeditor/src/code_actions.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use {TextUnit, File, EditBuilder, Edit}; | 1 | use {TextUnit, File, EditBuilder, Edit}; |
2 | use libsyntax2::{ | 2 | use libsyntax2::{ |
3 | ast::{self, AstNode}, | 3 | ast::{self, AstNode, AttrsOwner}, |
4 | SyntaxKind::COMMA, | 4 | SyntaxKind::COMMA, |
5 | SyntaxNodeRef, | 5 | SyntaxNodeRef, |
6 | SyntaxRoot, | 6 | SyntaxRoot, |
@@ -39,18 +39,28 @@ pub fn flip_comma<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce() | |||
39 | } | 39 | } |
40 | 40 | ||
41 | pub fn add_derive<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce() -> ActionResult + 'a> { | 41 | pub fn add_derive<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce() -> ActionResult + 'a> { |
42 | let syntax = file.syntax(); | 42 | let nominal = find_node::<ast::NominalDef<_>>(file.syntax_ref(), offset)?; |
43 | let syntax = syntax.as_ref(); | ||
44 | let nominal = find_node::<ast::NominalDef<_>>(syntax, offset)?; | ||
45 | Some(move || { | 43 | Some(move || { |
44 | let derive_attr = nominal | ||
45 | .attrs() | ||
46 | .filter_map(|x| x.as_call()) | ||
47 | .filter(|(name, _arg)| name == "derive") | ||
48 | .map(|(_name, arg)| arg) | ||
49 | .next(); | ||
46 | let mut edit = EditBuilder::new(); | 50 | let mut edit = EditBuilder::new(); |
47 | let node_start = nominal.syntax().range().start(); | 51 | let offset = match derive_attr { |
48 | edit.insert(node_start, "#[derive()]\n".to_string()); | 52 | None => { |
53 | let node_start = nominal.syntax().range().start(); | ||
54 | edit.insert(node_start, "#[derive()]\n".to_string()); | ||
55 | node_start + TextUnit::of_str("#[derive(") | ||
56 | } | ||
57 | Some(tt) => { | ||
58 | tt.syntax().range().end() - TextUnit::of_char(')') | ||
59 | } | ||
60 | }; | ||
49 | ActionResult { | 61 | ActionResult { |
50 | edit: edit.finish(), | 62 | edit: edit.finish(), |
51 | cursor_position: CursorPosition::Offset( | 63 | cursor_position: CursorPosition::Offset(offset), |
52 | node_start + TextUnit::of_str("#[derive(") | ||
53 | ), | ||
54 | } | 64 | } |
55 | }) | 65 | }) |
56 | } | 66 | } |
diff --git a/crates/libeditor/tests/test.rs b/crates/libeditor/tests/test.rs index d5df9d0cc..97919d347 100644 --- a/crates/libeditor/tests/test.rs +++ b/crates/libeditor/tests/test.rs | |||
@@ -116,7 +116,12 @@ fn test_add_derive() { | |||
116 | "struct Foo { a: i32, <|>}", | 116 | "struct Foo { a: i32, <|>}", |
117 | "#[derive(<|>)]\nstruct Foo { a: i32, }", | 117 | "#[derive(<|>)]\nstruct Foo { a: i32, }", |
118 | |file, off| add_derive(file, off).map(|f| f()), | 118 | |file, off| add_derive(file, off).map(|f| f()), |
119 | ) | 119 | ); |
120 | check_action( | ||
121 | "#[derive(Clone)]\nstruct Foo { a: i32<|>, }", | ||
122 | "#[derive(Clone<|>)]\nstruct Foo { a: i32, }", | ||
123 | |file, off| add_derive(file, off).map(|f| f()), | ||
124 | ); | ||
120 | } | 125 | } |
121 | 126 | ||
122 | #[test] | 127 | #[test] |