aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-26 08:43:03 +0100
committerAleksey Kladov <[email protected]>2018-08-26 08:43:03 +0100
commit4c121bfa2f2a7a06f01143e3203c650156e2fb4e (patch)
tree4b28671d904079928e005fa04dfbe14c36933e1b
parenta450142aca947b9364e498897f522f854f19781d (diff)
extend selection to comments
-rw-r--r--crates/libeditor/src/extend_selection.rs34
-rw-r--r--crates/libeditor/tests/test.rs12
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 @@
1use libsyntax2::{ 1use 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
7pub fn extend_selection(file: &File, range: TextRange) -> Option<TextRange> { 7pub 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
43fn 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
56fn 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#"
45fn 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]