aboutsummaryrefslogtreecommitdiff
path: root/crates/libeditor
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libeditor')
-rw-r--r--crates/libeditor/src/code_actions.rs27
-rw-r--r--crates/libeditor/src/lib.rs2
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 @@
1use {TextUnit, File, EditBuilder, Edit}; 1use {TextUnit, File, EditBuilder, Edit};
2use libsyntax2::{ 2use 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
28pub 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
27fn non_trivia_sibling(node: SyntaxNodeRef, direction: Direction) -> Option<SyntaxNodeRef> { 39fn 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
45fn 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
50fn 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)]