diff options
author | Aleksey Kladov <[email protected]> | 2018-08-14 11:33:44 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-14 11:33:44 +0100 |
commit | 1141d448d960eedba0a5647d525910de706bf778 (patch) | |
tree | 144842663edc382addc6b2cb115717d5bb7eb736 /crates/libeditor/src/code_actions.rs | |
parent | 5953a348bd6102a868f303d3f732a6ec7d465833 (diff) |
Add derive intention
Diffstat (limited to 'crates/libeditor/src/code_actions.rs')
-rw-r--r-- | crates/libeditor/src/code_actions.rs | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/crates/libeditor/src/code_actions.rs b/crates/libeditor/src/code_actions.rs index 7c9874588..6e2c73f29 100644 --- a/crates/libeditor/src/code_actions.rs +++ b/crates/libeditor/src/code_actions.rs | |||
@@ -1,11 +1,12 @@ | |||
1 | use {TextUnit, File, EditBuilder, Edit}; | 1 | use {TextUnit, File, EditBuilder, Edit}; |
2 | use libsyntax2::{ | 2 | use libsyntax2::{ |
3 | ast::AstNode, | 3 | ast::{self, AstNode}, |
4 | SyntaxKind::COMMA, | 4 | SyntaxKind::COMMA, |
5 | SyntaxNodeRef, | 5 | SyntaxNodeRef, |
6 | SyntaxRoot, | ||
6 | algo::{ | 7 | algo::{ |
7 | Direction, siblings, | 8 | Direction, siblings, |
8 | find_leaf_at_offset, | 9 | find_leaf_at_offset, ancestors, |
9 | }, | 10 | }, |
10 | }; | 11 | }; |
11 | 12 | ||
@@ -24,10 +25,32 @@ pub fn flip_comma<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce() | |||
24 | }) | 25 | }) |
25 | } | 26 | } |
26 | 27 | ||
28 | pub fn add_derive<'a>(file: &'a File, offset: TextUnit) -> Option<impl FnOnce() -> Edit + 'a> { | ||
29 | let syntax = file.syntax(); | ||
30 | let syntax = syntax.as_ref(); | ||
31 | let nominal = find_node::<ast::NominalDef<_>>(syntax, offset)?; | ||
32 | Some(move || { | ||
33 | let mut edit = EditBuilder::new(); | ||
34 | edit.insert(nominal.syntax().range().start(), "#[derive()]\n".to_string()); | ||
35 | edit.finish() | ||
36 | }) | ||
37 | } | ||
38 | |||
27 | fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> { | 39 | fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> { |
28 | siblings(node, direction) | 40 | siblings(node, direction) |
29 | .skip(1) | 41 | .skip(1) |
30 | .find(|node| !node.kind().is_trivia()) | 42 | .find(|node| !node.kind().is_trivia()) |
31 | } | 43 | } |
32 | 44 | ||
45 | fn find_non_trivia_leaf(syntax: SyntaxNodeRef, offset: TextUnit) -> Option<SyntaxNodeRef> { | ||
46 | find_leaf_at_offset(syntax, offset) | ||
47 | .find(|leaf| !leaf.kind().is_trivia()) | ||
48 | } | ||
49 | |||
50 | fn find_node<'a, N: AstNode<&'a SyntaxRoot>>(syntax: SyntaxNodeRef<'a>, offset: TextUnit) -> Option<N> { | ||
51 | let leaf = find_non_trivia_leaf(syntax, offset)?; | ||
52 | ancestors(leaf) | ||
53 | .filter_map(N::cast) | ||
54 | .next() | ||
55 | } | ||
33 | 56 | ||