From 4c2be06a7eb8fc93faf00909384912dc9e9fa39b Mon Sep 17 00:00:00 2001 From: "Jeremy A. Kolb" Date: Wed, 3 Oct 2018 17:04:00 -0400 Subject: [PATCH] Extend comments by single word first Fixes #88 --- crates/ra_editor/src/extend_selection.rs | 40 +++++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/crates/ra_editor/src/extend_selection.rs b/crates/ra_editor/src/extend_selection.rs index b00a457b90..5946824d82 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 if leaves.clone().all(|it| it.kind() == WHITESPACE) { return Some(extend_ws(root, leaves.next()?, offset)); } - let leaf = match leaves { + let leaf_range = match leaves { LeafAtOffset::None => return None, - LeafAtOffset::Single(l) => l, - LeafAtOffset::Between(l, r) => pick_best(l, r), + LeafAtOffset::Single(l) => { + if l.kind() == COMMENT { + extend_single_word_in_comment(l, range).unwrap_or_else(||l.range()) + } else { + l.range() + } + }, + LeafAtOffset::Between(l, r) => pick_best(l, r).range(), }; - return Some(leaf.range()); + return Some(leaf_range); }; let node = find_covering_node(root, range); if node.kind() == COMMENT && range == node.range() { @@ -36,6 +42,24 @@ pub(crate) fn extend(root: SyntaxNodeRef, range: TextRange) -> Option } } +fn extend_single_word_in_comment(leaf: SyntaxNodeRef, range: TextRange) -> Option { + let text : &str = leaf.leaf_text().unwrap(); + let cursor_position: u32 = (range.start() - leaf.range().start()).into(); + + let (before, after) = text.split_at(cursor_position as usize); + let start_idx = before.rfind(char::is_whitespace); + let end_idx = after.find(char::is_whitespace); + + match (start_idx, end_idx) { + (Some(start), Some(end)) => { + let from : TextUnit = (start as u32 + 1).into(); + let to : TextUnit = (cursor_position + (end as u32)).into(); + Some(TextRange::from_to(from, to)) + }, + (_, _) => None + } +} + fn extend_ws(root: SyntaxNodeRef, ws: SyntaxNodeRef, offset: TextUnit) -> TextRange { let ws_text = ws.leaf_text().unwrap(); let suffix = TextRange::from_to(offset, ws.range().end()) - ws.range().start(); @@ -176,4 +200,12 @@ fn main() { foo+<|>bar;} &["'a", "<'a>"] ); } + + #[test] + fn test_extend_selection_select_first_word() { + do_check( + r#"// foo bar b<|>az quxx"#, + &["baz", "// foo bar baz quxx"] + ); + } }