diff options
-rw-r--r-- | crates/ra_editor/src/code_actions.rs | 49 | ||||
-rw-r--r-- | crates/ra_editor/src/edit.rs | 2 |
2 files changed, 44 insertions, 7 deletions
diff --git a/crates/ra_editor/src/code_actions.rs b/crates/ra_editor/src/code_actions.rs index 37e963bbd..6979251d1 100644 --- a/crates/ra_editor/src/code_actions.rs +++ b/crates/ra_editor/src/code_actions.rs | |||
@@ -122,7 +122,7 @@ pub fn introduce_variable<'a>( | |||
122 | let node = find_covering_node(file.syntax(), range); | 122 | let node = find_covering_node(file.syntax(), range); |
123 | let expr = node.ancestors().filter_map(ast::Expr::cast).next()?; | 123 | let expr = node.ancestors().filter_map(ast::Expr::cast).next()?; |
124 | 124 | ||
125 | let anchor_stmt = ahchor_stmt(expr)?; | 125 | let anchor_stmt = anchor_stmt(expr)?; |
126 | let indent = anchor_stmt.prev_sibling()?; | 126 | let indent = anchor_stmt.prev_sibling()?; |
127 | if indent.kind() != WHITESPACE { | 127 | if indent.kind() != WHITESPACE { |
128 | return None; | 128 | return None; |
@@ -133,7 +133,12 @@ pub fn introduce_variable<'a>( | |||
133 | 133 | ||
134 | buf.push_str("let var_name = "); | 134 | buf.push_str("let var_name = "); |
135 | expr.syntax().text().push_to(&mut buf); | 135 | expr.syntax().text().push_to(&mut buf); |
136 | if expr.syntax().range().start() == anchor_stmt.range().start() { | 136 | let is_full_stmt = if let Some(expr_stmt) = ast::ExprStmt::cast(anchor_stmt) { |
137 | Some(expr.syntax()) == expr_stmt.expr().map(|e| e.syntax()) | ||
138 | } else { | ||
139 | false | ||
140 | }; | ||
141 | if is_full_stmt { | ||
137 | edit.replace(expr.syntax().range(), buf); | 142 | edit.replace(expr.syntax().range(), buf); |
138 | } else { | 143 | } else { |
139 | buf.push_str(";"); | 144 | buf.push_str(";"); |
@@ -150,7 +155,7 @@ pub fn introduce_variable<'a>( | |||
150 | 155 | ||
151 | /// Statement or last in the block expression, which will follow | 156 | /// Statement or last in the block expression, which will follow |
152 | /// the freshly introduced var. | 157 | /// the freshly introduced var. |
153 | fn ahchor_stmt(expr: ast::Expr) -> Option<SyntaxNodeRef> { | 158 | fn anchor_stmt(expr: ast::Expr) -> Option<SyntaxNodeRef> { |
154 | expr.syntax().ancestors().find(|&node| { | 159 | expr.syntax().ancestors().find(|&node| { |
155 | if ast::Stmt::cast(node).is_some() { | 160 | if ast::Stmt::cast(node).is_some() { |
156 | return true; | 161 | return true; |
@@ -250,7 +255,7 @@ struct Foo { a: i32, } | |||
250 | } | 255 | } |
251 | 256 | ||
252 | #[test] | 257 | #[test] |
253 | fn test_intrdoduce_var_simple() { | 258 | fn test_introduce_var_simple() { |
254 | check_action_range( | 259 | check_action_range( |
255 | " | 260 | " |
256 | fn foo() { | 261 | fn foo() { |
@@ -266,7 +271,7 @@ fn foo() { | |||
266 | } | 271 | } |
267 | 272 | ||
268 | #[test] | 273 | #[test] |
269 | fn test_intrdoduce_var_expr_stmt() { | 274 | fn test_introduce_var_expr_stmt() { |
270 | check_action_range( | 275 | check_action_range( |
271 | " | 276 | " |
272 | fn foo() { | 277 | fn foo() { |
@@ -281,7 +286,23 @@ fn foo() { | |||
281 | } | 286 | } |
282 | 287 | ||
283 | #[test] | 288 | #[test] |
284 | fn test_intrdoduce_var_last_expr() { | 289 | fn test_introduce_var_part_of_expr_stmt() { |
290 | check_action_range( | ||
291 | " | ||
292 | fn foo() { | ||
293 | <|>1<|> + 1; | ||
294 | }", | ||
295 | " | ||
296 | fn foo() { | ||
297 | let <|>var_name = 1; | ||
298 | var_name + 1; | ||
299 | }", | ||
300 | |file, range| introduce_variable(file, range).map(|f| f()), | ||
301 | ); | ||
302 | } | ||
303 | |||
304 | #[test] | ||
305 | fn test_introduce_var_last_expr() { | ||
285 | check_action_range( | 306 | check_action_range( |
286 | " | 307 | " |
287 | fn foo() { | 308 | fn foo() { |
@@ -296,4 +317,20 @@ fn foo() { | |||
296 | ); | 317 | ); |
297 | } | 318 | } |
298 | 319 | ||
320 | #[test] | ||
321 | fn test_introduce_var_last_full_expr() { | ||
322 | check_action_range( | ||
323 | " | ||
324 | fn foo() { | ||
325 | <|>bar(1 + 1)<|> | ||
326 | }", | ||
327 | " | ||
328 | fn foo() { | ||
329 | let <|>var_name = bar(1 + 1); | ||
330 | var_name | ||
331 | }", | ||
332 | |file, range| introduce_variable(file, range).map(|f| f()), | ||
333 | ); | ||
334 | } | ||
335 | |||
299 | } | 336 | } |
diff --git a/crates/ra_editor/src/edit.rs b/crates/ra_editor/src/edit.rs index c3149ec54..372b8d14c 100644 --- a/crates/ra_editor/src/edit.rs +++ b/crates/ra_editor/src/edit.rs | |||
@@ -26,7 +26,7 @@ impl EditBuilder { | |||
26 | } | 26 | } |
27 | pub fn finish(self) -> Edit { | 27 | pub fn finish(self) -> Edit { |
28 | let mut atoms = self.atoms; | 28 | let mut atoms = self.atoms; |
29 | atoms.sort_by_key(|a| a.delete.start()); | 29 | atoms.sort_by_key(|a| (a.delete.start(), a.delete.end())); |
30 | for (a1, a2) in atoms.iter().zip(atoms.iter().skip(1)) { | 30 | for (a1, a2) in atoms.iter().zip(atoms.iter().skip(1)) { |
31 | assert!(a1.delete.end() <= a2.delete.start()) | 31 | assert!(a1.delete.end() <= a2.delete.start()) |
32 | } | 32 | } |