diff options
Diffstat (limited to 'crates/ra_editor/src/extend_selection.rs')
-rw-r--r-- | crates/ra_editor/src/extend_selection.rs | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/crates/ra_editor/src/extend_selection.rs b/crates/ra_editor/src/extend_selection.rs index b00a457b9..6977900e6 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, offset).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,20 @@ 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, offset: TextUnit) -> Option<TextRange> { | ||
46 | let text : &str = leaf.leaf_text()?; | ||
47 | let cursor_position: u32 = (offset - 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)? as u32; | ||
51 | let end_idx = after.find(char::is_whitespace)? as u32; | ||
52 | |||
53 | let from : TextUnit = (start_idx + 1).into(); | ||
54 | let to : TextUnit = (cursor_position + end_idx).into(); | ||
55 | |||
56 | Some(TextRange::from_to(from, to)) | ||
57 | } | ||
58 | |||
39 | fn extend_ws(root: SyntaxNodeRef, ws: SyntaxNodeRef, offset: TextUnit) -> TextRange { | 59 | fn extend_ws(root: SyntaxNodeRef, ws: SyntaxNodeRef, offset: TextUnit) -> TextRange { |
40 | let ws_text = ws.leaf_text().unwrap(); | 60 | let ws_text = ws.leaf_text().unwrap(); |
41 | let suffix = TextRange::from_to(offset, ws.range().end()) - ws.range().start(); | 61 | let suffix = TextRange::from_to(offset, ws.range().end()) - ws.range().start(); |
@@ -176,4 +196,12 @@ fn main() { foo+<|>bar;} | |||
176 | &["'a", "<'a>"] | 196 | &["'a", "<'a>"] |
177 | ); | 197 | ); |
178 | } | 198 | } |
199 | |||
200 | #[test] | ||
201 | fn test_extend_selection_select_first_word() { | ||
202 | do_check( | ||
203 | r#"// foo bar b<|>az quxx"#, | ||
204 | &["baz", "// foo bar baz quxx"] | ||
205 | ); | ||
206 | } | ||
179 | } | 207 | } |