diff options
author | Aleksey Kladov <[email protected]> | 2018-08-28 09:12:42 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-28 09:12:42 +0100 |
commit | 2fa90e736b026ee979d9eb59178dc1f792228250 (patch) | |
tree | adba3a569241a2030bf66e4e0b24ac5ffeaccbc3 /crates/libeditor | |
parent | 13110f48e948d7554500aefc336e72f96041386b (diff) |
better recovery for exprs
Diffstat (limited to 'crates/libeditor')
-rw-r--r-- | crates/libeditor/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/libeditor/src/typing.rs | 24 | ||||
-rw-r--r-- | crates/libeditor/tests/test.rs | 46 |
3 files changed, 67 insertions, 5 deletions
diff --git a/crates/libeditor/src/lib.rs b/crates/libeditor/src/lib.rs index d39e56d81..34056b3c0 100644 --- a/crates/libeditor/src/lib.rs +++ b/crates/libeditor/src/lib.rs | |||
@@ -27,7 +27,7 @@ pub use self::{ | |||
27 | ActionResult, | 27 | ActionResult, |
28 | flip_comma, add_derive, add_impl, | 28 | flip_comma, add_derive, add_impl, |
29 | }, | 29 | }, |
30 | typing::join_lines, | 30 | typing::{join_lines, on_eq_typed}, |
31 | completion::scope_completion, | 31 | completion::scope_completion, |
32 | }; | 32 | }; |
33 | 33 | ||
diff --git a/crates/libeditor/src/typing.rs b/crates/libeditor/src/typing.rs index 060095f28..48a8d6bb0 100644 --- a/crates/libeditor/src/typing.rs +++ b/crates/libeditor/src/typing.rs | |||
@@ -7,11 +7,11 @@ use libsyntax2::{ | |||
7 | walk::preorder, | 7 | walk::preorder, |
8 | find_covering_node, | 8 | find_covering_node, |
9 | }, | 9 | }, |
10 | text_utils::intersect, | 10 | text_utils::{intersect, contains_offset_nonstrict}, |
11 | SyntaxKind::*, | 11 | SyntaxKind::*, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | use {ActionResult, EditBuilder}; | 14 | use {ActionResult, EditBuilder, find_node_at_offset}; |
15 | 15 | ||
16 | pub fn join_lines(file: &File, range: TextRange) -> ActionResult { | 16 | pub fn join_lines(file: &File, range: TextRange) -> ActionResult { |
17 | let range = if range.is_empty() { | 17 | let range = if range.is_empty() { |
@@ -56,6 +56,26 @@ pub fn join_lines(file: &File, range: TextRange) -> ActionResult { | |||
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
59 | pub fn on_eq_typed(file: &File, offset: TextUnit) -> Option<ActionResult> { | ||
60 | let let_stmt: ast::LetStmt = find_node_at_offset(file.syntax(), offset)?; | ||
61 | if let_stmt.has_semi() { | ||
62 | return None; | ||
63 | } | ||
64 | if let Some(expr) = let_stmt.initializer() { | ||
65 | let expr_range = expr.syntax().range(); | ||
66 | if contains_offset_nonstrict(expr_range, offset) && offset != expr_range.start() { | ||
67 | return None; | ||
68 | } | ||
69 | } | ||
70 | let offset = let_stmt.syntax().range().end(); | ||
71 | let mut edit = EditBuilder::new(); | ||
72 | edit.insert(offset, ";".to_string()); | ||
73 | Some(ActionResult { | ||
74 | edit: edit.finish(), | ||
75 | cursor_position: None, | ||
76 | }) | ||
77 | } | ||
78 | |||
59 | fn remove_newline( | 79 | fn remove_newline( |
60 | edit: &mut EditBuilder, | 80 | edit: &mut EditBuilder, |
61 | node: SyntaxNodeRef, | 81 | node: SyntaxNodeRef, |
diff --git a/crates/libeditor/tests/test.rs b/crates/libeditor/tests/test.rs index d8c24610d..17926d5ae 100644 --- a/crates/libeditor/tests/test.rs +++ b/crates/libeditor/tests/test.rs | |||
@@ -9,7 +9,7 @@ use libeditor::{ | |||
9 | ActionResult, | 9 | ActionResult, |
10 | highlight, runnables, extend_selection, file_structure, | 10 | highlight, runnables, extend_selection, file_structure, |
11 | flip_comma, add_derive, add_impl, matching_brace, | 11 | flip_comma, add_derive, add_impl, matching_brace, |
12 | join_lines, scope_completion, | 12 | join_lines, on_eq_typed, scope_completion, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | #[test] | 15 | #[test] |
@@ -227,7 +227,7 @@ pub fn reparse(&self, edit: &AtomEdit) -> File { | |||
227 | #[test] | 227 | #[test] |
228 | fn test_join_lines_selection() { | 228 | fn test_join_lines_selection() { |
229 | fn do_check(before: &str, after: &str) { | 229 | fn do_check(before: &str, after: &str) { |
230 | let (sel, before) = extract_range(&before); | 230 | let (sel, before) = extract_range(before); |
231 | let file = file(&before); | 231 | let file = file(&before); |
232 | let result = join_lines(&file, sel); | 232 | let result = join_lines(&file, sel); |
233 | let actual = result.edit.apply(&before); | 233 | let actual = result.edit.apply(&before); |
@@ -257,6 +257,48 @@ struct Foo { f: u32 } | |||
257 | } | 257 | } |
258 | 258 | ||
259 | #[test] | 259 | #[test] |
260 | fn test_on_eq_typed() { | ||
261 | fn do_check(before: &str, after: &str) { | ||
262 | let (offset, before) = extract_offset(before); | ||
263 | let file = file(&before); | ||
264 | let result = on_eq_typed(&file, offset).unwrap(); | ||
265 | let actual = result.edit.apply(&before); | ||
266 | assert_eq_text!(after, &actual); | ||
267 | } | ||
268 | |||
269 | do_check(r" | ||
270 | fn foo() { | ||
271 | let foo =<|> | ||
272 | } | ||
273 | ", r" | ||
274 | fn foo() { | ||
275 | let foo =; | ||
276 | } | ||
277 | "); | ||
278 | do_check(r" | ||
279 | fn foo() { | ||
280 | let foo =<|> 1 + 1 | ||
281 | } | ||
282 | ", r" | ||
283 | fn foo() { | ||
284 | let foo = 1 + 1; | ||
285 | } | ||
286 | "); | ||
287 | // do_check(r" | ||
288 | // fn foo() { | ||
289 | // let foo =<|> | ||
290 | // let bar = 1; | ||
291 | // } | ||
292 | // ", r" | ||
293 | // fn foo() { | ||
294 | // let foo =; | ||
295 | // let bar = 1; | ||
296 | // } | ||
297 | // "); | ||
298 | |||
299 | } | ||
300 | |||
301 | #[test] | ||
260 | fn test_completion() { | 302 | fn test_completion() { |
261 | fn do_check(code: &str, expected_completions: &str) { | 303 | fn do_check(code: &str, expected_completions: &str) { |
262 | let (off, code) = extract_offset(&code); | 304 | let (off, code) = extract_offset(&code); |