From b8d067015a69635a8ff0cc66e152750434688299 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Tue, 1 Oct 2024 23:13:08 +0800 Subject: [PATCH] Word movement select from first range 3w currently selects the 3rd word, this changes the behavior to select all 3 words rather than just the last. --- helix-core/src/movement.rs | 40 ++++++++++++++++++++++---------------- helix-term/src/commands.rs | 21 +++++++++++++++++--- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/helix-core/src/movement.rs b/helix-core/src/movement.rs index 09a99db25..f1092d6c2 100644 --- a/helix-core/src/movement.rs +++ b/helix-core/src/movement.rs @@ -251,14 +251,20 @@ fn word_move(slice: RopeSlice, range: Range, count: usize, target: WordMotionTar // Do the main work. let mut range = start_range; + let mut first_range = None; for _ in 0..count { let next_range = slice.chars_at(range.head).range_to_target(target, range); if range == next_range { break; } range = next_range; + if first_range.is_none() { + first_range = Some(range); + } } - range + let first_range = first_range.unwrap_or(range); + let last_range = range; + Range::new(first_range.anchor, last_range.head) } pub fn move_prev_paragraph( @@ -1042,11 +1048,11 @@ mod test { ]), ("Multiple motions at once resolve correctly", vec![ - (3, Range::new(0, 0), Range::new(17, 20)), + (3, Range::new(0, 0), Range::new(0, 20)), ]), ("Excessive motions are performed partially", vec![ - (999, Range::new(0, 0), Range::new(32, 41)), + (999, Range::new(0, 0), Range::new(0, 41)), ]), ("", // Edge case of moving forward in empty string vec![ @@ -1298,11 +1304,11 @@ mod test { ]), ("Multiple motions at once resolve correctly", vec![ - (3, Range::new(0, 0), Range::new(17, 20)), + (3, Range::new(0, 0), Range::new(0, 20)), ]), ("Excessive motions are performed partially", vec![ - (999, Range::new(0, 0), Range::new(32, 41)), + (999, Range::new(0, 0), Range::new(0, 41)), ]), ("", // Edge case of moving forward in empty string vec![ @@ -1383,11 +1389,11 @@ mod test { ]), ("Multiple motions at once resolve correctly", vec![ - (3, Range::new(18, 18), Range::new(9, 0)), + (3, Range::new(18, 18), Range::new(19, 0)), ]), ("Excessive motions are performed partially", vec![ - (999, Range::new(40, 40), Range::new(10, 0)), + (999, Range::new(40, 40), Range::new(41, 0)), ]), ("", // Edge case of moving backwards in empty string vec![ @@ -1566,11 +1572,11 @@ mod test { ), ( "Multiple motions at once resolve correctly", - vec![(3, Range::new(19, 19), Range::new(9, 0))], + vec![(3, Range::new(0, 19), Range::new(19, 0))], ), ( "Excessive motions are performed partially", - vec![(999, Range::new(40, 40), Range::new(10, 0))], + vec![(999, Range::new(40, 40), Range::new(41, 0))], ), ( "", // Edge case of moving backwards in empty string @@ -1650,11 +1656,11 @@ mod test { ]), ("Multiple motions at once resolve correctly", vec![ - (3, Range::new(0, 0), Range::new(16, 19)), + (3, Range::new(0, 0), Range::new(0, 19)), ]), ("Excessive motions are performed partially", vec![ - (999, Range::new(0, 0), Range::new(31, 41)), + (999, Range::new(0, 0), Range::new(0, 41)), ]), ("", // Edge case of moving forward in empty string vec![ @@ -1732,11 +1738,11 @@ mod test { ]), ("Multiple motions at once resolve correctly", vec![ - (3, Range::new(24, 24), Range::new(16, 8)), + (3, Range::new(24, 24), Range::new(24, 8)), ]), ("Excessive motions are performed partially", vec![ - (999, Range::new(40, 40), Range::new(9, 0)), + (999, Range::new(40, 40), Range::new(41, 0)), ]), ("", // Edge case of moving backwards in empty string vec![ @@ -1900,11 +1906,11 @@ mod test { ]), ("Multiple motions at once resolve correctly", vec![ - (3, Range::new(0, 0), Range::new(16, 19)), + (3, Range::new(0, 0), Range::new(0, 19)), ]), ("Excessive motions are performed partially", vec![ - (999, Range::new(0, 0), Range::new(31, 41)), + (999, Range::new(0, 0), Range::new(0, 41)), ]), ("", // Edge case of moving forward in empty string vec![ @@ -1994,11 +2000,11 @@ mod test { ), ( "Multiple motions at once resolve correctly", - vec![(3, Range::new(19, 19), Range::new(8, 0))], + vec![(3, Range::new(19, 19), Range::new(19, 0))], ), ( "Excessive motions are performed partially", - vec![(999, Range::new(40, 40), Range::new(9, 0))], + vec![(999, Range::new(40, 40), Range::new(41, 0))], ), ( "", // Edge case of moving backwards in empty string diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 2cbdeb451..1211a773a 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -814,7 +814,11 @@ fn goto_line_end_impl(view: &mut View, doc: &mut Document, movement: Movement) { let pos = graphemes::prev_grapheme_boundary(text, line_end_char_index(&text, line)) .max(line_start); - range.put_cursor(text, pos, movement == Movement::Extend) + if movement != Movement::Extend { + Range::point(range.cursor(text)).put_cursor(text, pos, range.head <= pos) + } else { + range.put_cursor(text, pos, true) + } }); doc.set_selection(view.id, selection); } @@ -875,7 +879,14 @@ fn goto_line_start_impl(view: &mut View, doc: &mut Document, movement: Movement) // adjust to start of the line let pos = text.line_to_char(line); - range.put_cursor(text, pos, movement == Movement::Extend) + if movement != Movement::Extend { + // ignore head placed at newline, no point to `gh d`? + let head = graphemes::prev_grapheme_boundary(text, line_end_char_index(&text, line)) + .min(range.cursor(text)); + Range::point(head).put_cursor(text, pos, true) + } else { + range.put_cursor(text, pos, true) + } }); doc.set_selection(view.id, selection); } @@ -1005,7 +1016,11 @@ fn goto_first_nonwhitespace_impl(view: &mut View, doc: &mut Document, movement: if let Some(pos) = text.line(line).first_non_whitespace_char() { let pos = pos + text.line_to_char(line); - range.put_cursor(text, pos, movement == Movement::Extend) + if movement != Movement::Extend { + Range::point(range.cursor(text)).put_cursor(text, pos, true) + } else { + range.put_cursor(text, pos, true) + } } else { range }