diff options
Diffstat (limited to 'crates/libeditor/src')
-rw-r--r-- | crates/libeditor/src/code_actions.rs | 27 | ||||
-rw-r--r-- | crates/libeditor/src/lib.rs | 2 |
2 files changed, 26 insertions, 3 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 | ||
diff --git a/crates/libeditor/src/lib.rs b/crates/libeditor/src/lib.rs index b40db2c66..2c46ca45f 100644 --- a/crates/libeditor/src/lib.rs +++ b/crates/libeditor/src/lib.rs | |||
@@ -21,7 +21,7 @@ pub use self::{ | |||
21 | extend_selection::extend_selection, | 21 | extend_selection::extend_selection, |
22 | symbols::{StructureNode, file_structure, FileSymbol, file_symbols}, | 22 | symbols::{StructureNode, file_structure, FileSymbol, file_symbols}, |
23 | edit::{EditBuilder, Edit, AtomEdit}, | 23 | edit::{EditBuilder, Edit, AtomEdit}, |
24 | code_actions::{flip_comma}, | 24 | code_actions::{flip_comma, add_derive}, |
25 | }; | 25 | }; |
26 | 26 | ||
27 | #[derive(Debug)] | 27 | #[derive(Debug)] |