aboutsummaryrefslogtreecommitdiff
path: root/crates/libeditor
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-16 11:11:20 +0100
committerAleksey Kladov <[email protected]>2018-08-16 11:11:20 +0100
commita5515d9d6f215da4351b482d839aab5212fa0e6f (patch)
treea0557e07f57fad65ad32b80010cce08b5559f9e5 /crates/libeditor
parent7094291573dc819e3115950ec3b2316bd5e9ea33 (diff)
Add derive handles cursor
Diffstat (limited to 'crates/libeditor')
-rw-r--r--crates/libeditor/src/code_actions.rs28
-rw-r--r--crates/libeditor/tests/test.rs7
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 @@
1use {TextUnit, File, EditBuilder, Edit}; 1use {TextUnit, File, EditBuilder, Edit};
2use libsyntax2::{ 2use 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
41pub fn add_derive<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce() -> ActionResult + 'a> { 41pub 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]