diff options
Diffstat (limited to 'crates/ra_editor/src')
-rw-r--r-- | crates/ra_editor/src/extend_selection.rs | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/crates/ra_editor/src/extend_selection.rs b/crates/ra_editor/src/extend_selection.rs index b00a457b9..5946824d8 100644 --- a/crates/ra_editor/src/extend_selection.rs +++ b/crates/ra_editor/src/extend_selection.rs | |||
@@ -16,12 +16,18 @@ pub(crate) fn extend(root: SyntaxNodeRef, range: TextRange) -> Option<TextRange> | |||
16 | if leaves.clone().all(|it| it.kind() == WHITESPACE) { | 16 | if leaves.clone().all(|it| it.kind() == WHITESPACE) { |
17 | return Some(extend_ws(root, leaves.next()?, offset)); | 17 | return Some(extend_ws(root, leaves.next()?, offset)); |
18 | } | 18 | } |
19 | let leaf = match leaves { | 19 | let leaf_range = match leaves { |
20 | LeafAtOffset::None => return None, | 20 | LeafAtOffset::None => return None, |
21 | LeafAtOffset::Single(l) => l, | 21 | LeafAtOffset::Single(l) => { |
22 | LeafAtOffset::Between(l, r) => pick_best(l, r), | 22 | if l.kind() == COMMENT { |
23 | extend_single_word_in_comment(l, range).unwrap_or_else(||l.range()) | ||
24 | } else { | ||
25 | l.range() | ||
26 | } | ||
27 | }, | ||
28 | LeafAtOffset::Between(l, r) => pick_best(l, r).range(), | ||
23 | }; | 29 | }; |
24 | return Some(leaf.range()); | 30 | return Some(leaf_range); |
25 | }; | 31 | }; |
26 | let node = find_covering_node(root, range); | 32 | let node = find_covering_node(root, range); |
27 | if node.kind() == COMMENT && range == node.range() { | 33 | if node.kind() == COMMENT && range == node.range() { |
@@ -36,6 +42,24 @@ pub(crate) fn extend(root: SyntaxNodeRef, range: TextRange) -> Option<TextRange> | |||
36 | } | 42 | } |
37 | } | 43 | } |
38 | 44 | ||
45 | fn extend_single_word_in_comment(leaf: SyntaxNodeRef, range: TextRange) -> Option<TextRange> { | ||
46 | let text : &str = leaf.leaf_text().unwrap(); | ||
47 | let cursor_position: u32 = (range.start() - leaf.range().start()).into(); | ||
48 | |||
49 | let (before, after) = text.split_at(cursor_position as usize); | ||
50 | let start_idx = before.rfind(char::is_whitespace); | ||
51 | let end_idx = after.find(char::is_whitespace); | ||
52 | |||
53 | match (start_idx, end_idx) { | ||
54 | (Some(start), Some(end)) => { | ||
55 | let from : TextUnit = (start as u32 + 1).into(); | ||
56 | let to : TextUnit = (cursor_position + (end as u32)).into(); | ||
57 | Some(TextRange::from_to(from, to)) | ||
58 | }, | ||
59 | (_, _) => None | ||
60 | } | ||
61 | } | ||
62 | |||
39 | fn extend_ws(root: SyntaxNodeRef, ws: SyntaxNodeRef, offset: TextUnit) -> TextRange { | 63 | fn extend_ws(root: SyntaxNodeRef, ws: SyntaxNodeRef, offset: TextUnit) -> TextRange { |
40 | let ws_text = ws.leaf_text().unwrap(); | 64 | let ws_text = ws.leaf_text().unwrap(); |
41 | let suffix = TextRange::from_to(offset, ws.range().end()) - ws.range().start(); | 65 | let suffix = TextRange::from_to(offset, ws.range().end()) - ws.range().start(); |
@@ -176,4 +200,12 @@ fn main() { foo+<|>bar;} | |||
176 | &["'a", "<'a>"] | 200 | &["'a", "<'a>"] |
177 | ); | 201 | ); |
178 | } | 202 | } |
203 | |||
204 | #[test] | ||
205 | fn test_extend_selection_select_first_word() { | ||
206 | do_check( | ||
207 | r#"// foo bar b<|>az quxx"#, | ||
208 | &["baz", "// foo bar baz quxx"] | ||
209 | ); | ||
210 | } | ||
179 | } | 211 | } |