diff options
author | Aleksey Kladov <[email protected]> | 2019-01-03 15:59:17 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-01-03 15:59:17 +0000 |
commit | a4635a199bc446bd103aa5821e57dc19b8a15751 (patch) | |
tree | 5dcdd940d8627f021062245cb79589a790b60e04 /crates/ra_editor/src/assists/introduce_variable.rs | |
parent | aea2183799e7975d3d9000cec9bb9a3c001a3d4e (diff) |
more enterprisey assists API
Diffstat (limited to 'crates/ra_editor/src/assists/introduce_variable.rs')
-rw-r--r-- | crates/ra_editor/src/assists/introduce_variable.rs | 84 |
1 files changed, 36 insertions, 48 deletions
diff --git a/crates/ra_editor/src/assists/introduce_variable.rs b/crates/ra_editor/src/assists/introduce_variable.rs index 17ab521fa..782861023 100644 --- a/crates/ra_editor/src/assists/introduce_variable.rs +++ b/crates/ra_editor/src/assists/introduce_variable.rs | |||
@@ -1,19 +1,13 @@ | |||
1 | use ra_text_edit::TextEditBuilder; | ||
2 | use ra_syntax::{ | 1 | use ra_syntax::{ |
3 | algo::{find_covering_node}, | ||
4 | ast::{self, AstNode}, | 2 | ast::{self, AstNode}, |
5 | SourceFileNode, | 3 | SyntaxKind::WHITESPACE, |
6 | SyntaxKind::{WHITESPACE}, | 4 | SyntaxNodeRef, TextUnit, |
7 | SyntaxNodeRef, TextRange, TextUnit, | ||
8 | }; | 5 | }; |
9 | 6 | ||
10 | use crate::assists::LocalEdit; | 7 | use crate::assists::{AssistCtx, Assist}; |
11 | 8 | ||
12 | pub fn introduce_variable<'a>( | 9 | pub fn introduce_variable<'a>(ctx: AssistCtx) -> Option<Assist> { |
13 | file: &'a SourceFileNode, | 10 | let node = ctx.covering_node(); |
14 | range: TextRange, | ||
15 | ) -> Option<impl FnOnce() -> LocalEdit + 'a> { | ||
16 | let node = find_covering_node(file.syntax(), range); | ||
17 | let expr = node.ancestors().filter_map(ast::Expr::cast).next()?; | 11 | let expr = node.ancestors().filter_map(ast::Expr::cast).next()?; |
18 | 12 | ||
19 | let anchor_stmt = anchor_stmt(expr)?; | 13 | let anchor_stmt = anchor_stmt(expr)?; |
@@ -21,9 +15,8 @@ pub fn introduce_variable<'a>( | |||
21 | if indent.kind() != WHITESPACE { | 15 | if indent.kind() != WHITESPACE { |
22 | return None; | 16 | return None; |
23 | } | 17 | } |
24 | return Some(move || { | 18 | ctx.build("introduce variable", move |edit| { |
25 | let mut buf = String::new(); | 19 | let mut buf = String::new(); |
26 | let mut edit = TextEditBuilder::new(); | ||
27 | 20 | ||
28 | buf.push_str("let var_name = "); | 21 | buf.push_str("let var_name = "); |
29 | expr.syntax().text().push_to(&mut buf); | 22 | expr.syntax().text().push_to(&mut buf); |
@@ -40,43 +33,39 @@ pub fn introduce_variable<'a>( | |||
40 | edit.replace(expr.syntax().range(), "var_name".to_string()); | 33 | edit.replace(expr.syntax().range(), "var_name".to_string()); |
41 | edit.insert(anchor_stmt.range().start(), buf); | 34 | edit.insert(anchor_stmt.range().start(), buf); |
42 | } | 35 | } |
43 | let cursor_position = anchor_stmt.range().start() + TextUnit::of_str("let "); | 36 | edit.set_cursor(anchor_stmt.range().start() + TextUnit::of_str("let ")); |
44 | LocalEdit { | 37 | }) |
45 | label: "introduce variable".to_string(), | 38 | } |
46 | edit: edit.finish(), | ||
47 | cursor_position: Some(cursor_position), | ||
48 | } | ||
49 | }); | ||
50 | 39 | ||
51 | /// Statement or last in the block expression, which will follow | 40 | /// Statement or last in the block expression, which will follow |
52 | /// the freshly introduced var. | 41 | /// the freshly introduced var. |
53 | fn anchor_stmt(expr: ast::Expr) -> Option<SyntaxNodeRef> { | 42 | fn anchor_stmt(expr: ast::Expr) -> Option<SyntaxNodeRef> { |
54 | expr.syntax().ancestors().find(|&node| { | 43 | expr.syntax().ancestors().find(|&node| { |
55 | if ast::Stmt::cast(node).is_some() { | 44 | if ast::Stmt::cast(node).is_some() { |
45 | return true; | ||
46 | } | ||
47 | if let Some(expr) = node | ||
48 | .parent() | ||
49 | .and_then(ast::Block::cast) | ||
50 | .and_then(|it| it.expr()) | ||
51 | { | ||
52 | if expr.syntax() == node { | ||
56 | return true; | 53 | return true; |
57 | } | 54 | } |
58 | if let Some(expr) = node | 55 | } |
59 | .parent() | 56 | false |
60 | .and_then(ast::Block::cast) | 57 | }) |
61 | .and_then(|it| it.expr()) | ||
62 | { | ||
63 | if expr.syntax() == node { | ||
64 | return true; | ||
65 | } | ||
66 | } | ||
67 | false | ||
68 | }) | ||
69 | } | ||
70 | } | 58 | } |
71 | 59 | ||
72 | #[cfg(test)] | 60 | #[cfg(test)] |
73 | mod tests { | 61 | mod tests { |
74 | use super::*; | 62 | use super::*; |
75 | use crate::test_utils::check_action_range; | 63 | use crate::assists::check_assist_range; |
76 | 64 | ||
77 | #[test] | 65 | #[test] |
78 | fn test_introduce_var_simple() { | 66 | fn test_introduce_var_simple() { |
79 | check_action_range( | 67 | check_assist_range( |
68 | introduce_variable, | ||
80 | " | 69 | " |
81 | fn foo() { | 70 | fn foo() { |
82 | foo(<|>1 + 1<|>); | 71 | foo(<|>1 + 1<|>); |
@@ -86,13 +75,13 @@ fn foo() { | |||
86 | let <|>var_name = 1 + 1; | 75 | let <|>var_name = 1 + 1; |
87 | foo(var_name); | 76 | foo(var_name); |
88 | }", | 77 | }", |
89 | |file, range| introduce_variable(file, range).map(|f| f()), | ||
90 | ); | 78 | ); |
91 | } | 79 | } |
92 | 80 | ||
93 | #[test] | 81 | #[test] |
94 | fn test_introduce_var_expr_stmt() { | 82 | fn test_introduce_var_expr_stmt() { |
95 | check_action_range( | 83 | check_assist_range( |
84 | introduce_variable, | ||
96 | " | 85 | " |
97 | fn foo() { | 86 | fn foo() { |
98 | <|>1 + 1<|>; | 87 | <|>1 + 1<|>; |
@@ -101,13 +90,13 @@ fn foo() { | |||
101 | fn foo() { | 90 | fn foo() { |
102 | let <|>var_name = 1 + 1; | 91 | let <|>var_name = 1 + 1; |
103 | }", | 92 | }", |
104 | |file, range| introduce_variable(file, range).map(|f| f()), | ||
105 | ); | 93 | ); |
106 | } | 94 | } |
107 | 95 | ||
108 | #[test] | 96 | #[test] |
109 | fn test_introduce_var_part_of_expr_stmt() { | 97 | fn test_introduce_var_part_of_expr_stmt() { |
110 | check_action_range( | 98 | check_assist_range( |
99 | introduce_variable, | ||
111 | " | 100 | " |
112 | fn foo() { | 101 | fn foo() { |
113 | <|>1<|> + 1; | 102 | <|>1<|> + 1; |
@@ -117,13 +106,13 @@ fn foo() { | |||
117 | let <|>var_name = 1; | 106 | let <|>var_name = 1; |
118 | var_name + 1; | 107 | var_name + 1; |
119 | }", | 108 | }", |
120 | |file, range| introduce_variable(file, range).map(|f| f()), | ||
121 | ); | 109 | ); |
122 | } | 110 | } |
123 | 111 | ||
124 | #[test] | 112 | #[test] |
125 | fn test_introduce_var_last_expr() { | 113 | fn test_introduce_var_last_expr() { |
126 | check_action_range( | 114 | check_assist_range( |
115 | introduce_variable, | ||
127 | " | 116 | " |
128 | fn foo() { | 117 | fn foo() { |
129 | bar(<|>1 + 1<|>) | 118 | bar(<|>1 + 1<|>) |
@@ -133,13 +122,13 @@ fn foo() { | |||
133 | let <|>var_name = 1 + 1; | 122 | let <|>var_name = 1 + 1; |
134 | bar(var_name) | 123 | bar(var_name) |
135 | }", | 124 | }", |
136 | |file, range| introduce_variable(file, range).map(|f| f()), | ||
137 | ); | 125 | ); |
138 | } | 126 | } |
139 | 127 | ||
140 | #[test] | 128 | #[test] |
141 | fn test_introduce_var_last_full_expr() { | 129 | fn test_introduce_var_last_full_expr() { |
142 | check_action_range( | 130 | check_assist_range( |
131 | introduce_variable, | ||
143 | " | 132 | " |
144 | fn foo() { | 133 | fn foo() { |
145 | <|>bar(1 + 1)<|> | 134 | <|>bar(1 + 1)<|> |
@@ -149,7 +138,6 @@ fn foo() { | |||
149 | let <|>var_name = bar(1 + 1); | 138 | let <|>var_name = bar(1 + 1); |
150 | var_name | 139 | var_name |
151 | }", | 140 | }", |
152 | |file, range| introduce_variable(file, range).map(|f| f()), | ||
153 | ); | 141 | ); |
154 | } | 142 | } |
155 | 143 | ||