diff options
author | Aleksey Kladov <[email protected]> | 2018-08-26 08:43:03 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-26 08:43:03 +0100 |
commit | 4c121bfa2f2a7a06f01143e3203c650156e2fb4e (patch) | |
tree | 4b28671d904079928e005fa04dfbe14c36933e1b | |
parent | a450142aca947b9364e498897f522f854f19781d (diff) |
extend selection to comments
-rw-r--r-- | crates/libeditor/src/extend_selection.rs | 34 | ||||
-rw-r--r-- | crates/libeditor/tests/test.rs | 12 |
2 files changed, 44 insertions, 2 deletions
diff --git a/crates/libeditor/src/extend_selection.rs b/crates/libeditor/src/extend_selection.rs index d1724b528..154f89671 100644 --- a/crates/libeditor/src/extend_selection.rs +++ b/crates/libeditor/src/extend_selection.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use libsyntax2::{ | 1 | use libsyntax2::{ |
2 | File, TextRange, SyntaxNodeRef, | 2 | File, TextRange, SyntaxNodeRef, |
3 | SyntaxKind::WHITESPACE, | 3 | SyntaxKind::*, |
4 | algo::{find_leaf_at_offset, find_covering_node, ancestors}, | 4 | algo::{find_leaf_at_offset, find_covering_node, ancestors, Direction, siblings}, |
5 | }; | 5 | }; |
6 | 6 | ||
7 | pub fn extend_selection(file: &File, range: TextRange) -> Option<TextRange> { | 7 | pub fn extend_selection(file: &File, range: TextRange) -> Option<TextRange> { |
@@ -28,9 +28,39 @@ pub(crate) fn extend(root: SyntaxNodeRef, range: TextRange) -> Option<TextRange> | |||
28 | return Some(ws.range()); | 28 | return Some(ws.range()); |
29 | }; | 29 | }; |
30 | let node = find_covering_node(root, range); | 30 | let node = find_covering_node(root, range); |
31 | if node.kind() == COMMENT && range == node.range() { | ||
32 | if let Some(range) = extend_comments(node) { | ||
33 | return Some(range); | ||
34 | } | ||
35 | } | ||
31 | 36 | ||
32 | match ancestors(node).skip_while(|n| n.range() == range).next() { | 37 | match ancestors(node).skip_while(|n| n.range() == range).next() { |
33 | None => None, | 38 | None => None, |
34 | Some(parent) => Some(parent.range()), | 39 | Some(parent) => Some(parent.range()), |
35 | } | 40 | } |
36 | } | 41 | } |
42 | |||
43 | fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> { | ||
44 | let left = adj_comments(node, Direction::Backward); | ||
45 | let right = adj_comments(node, Direction::Forward); | ||
46 | if left != right { | ||
47 | Some(TextRange::from_to( | ||
48 | left.range().start(), | ||
49 | right.range().end(), | ||
50 | )) | ||
51 | } else { | ||
52 | None | ||
53 | } | ||
54 | } | ||
55 | |||
56 | fn adj_comments(node: SyntaxNodeRef, dir: Direction) -> SyntaxNodeRef { | ||
57 | let mut res = node; | ||
58 | for node in siblings(node, dir) { | ||
59 | match node.kind() { | ||
60 | COMMENT => res = node, | ||
61 | WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (), | ||
62 | _ => break | ||
63 | } | ||
64 | } | ||
65 | res | ||
66 | } | ||
diff --git a/crates/libeditor/tests/test.rs b/crates/libeditor/tests/test.rs index 9d59f4cdf..20de2f240 100644 --- a/crates/libeditor/tests/test.rs +++ b/crates/libeditor/tests/test.rs | |||
@@ -40,6 +40,18 @@ impl S { | |||
40 | }"#, | 40 | }"#, |
41 | &["fn foo() {\n\n }"] | 41 | &["fn foo() {\n\n }"] |
42 | ); | 42 | ); |
43 | do_check( | ||
44 | r#" | ||
45 | fn bar(){} | ||
46 | |||
47 | // fn foo() { | ||
48 | // 1 + <|>1 | ||
49 | // } | ||
50 | |||
51 | // fn foo(){} | ||
52 | "#, | ||
53 | &["// 1 + 1", "// fn foo() {\n// 1 + 1\n// }"] | ||
54 | ); | ||
43 | } | 55 | } |
44 | 56 | ||
45 | #[test] | 57 | #[test] |