diff --git a/helix-core/src/state.rs b/helix-core/src/state.rs index 7cecba29a..ffe88c3f6 100644 --- a/helix-core/src/state.rs +++ b/helix-core/src/state.rs @@ -159,10 +159,9 @@ impl State { (Direction::Forward, Granularity::Character) => { // Clamp to line let line = text.char_to_line(pos); - let start = text.line_to_char(line); - let len = text.line(line).len_chars(); - // convert to 0-indexed, subtract another 1 because len_chars() counts \n - let end = start + len.saturating_sub(2); + // Line end is pos at the start of next line - 1 + // subtract another 1 because the line ends with \n + let end = text.line_to_char(line + 1).saturating_sub(2); std::cmp::min(nth_next_grapheme_boundary(&text.slice(..), pos, count), end) } (Direction::Forward, Granularity::Word) => { diff --git a/helix-view/src/commands.rs b/helix-view/src/commands.rs index fc18e3a73..d611e4f66 100644 --- a/helix-view/src/commands.rs +++ b/helix-view/src/commands.rs @@ -50,9 +50,10 @@ pub fn move_line_end(view: &mut View, count: usize) { .into_iter() .map(|index| { // adjust all positions to the end of the line. - let line = view.state.doc.line(index); - let line_start = view.state.doc.line_to_char(index); - line_start + line.len_chars() - 1 + + // Line end is pos at the start of next line - 1 + // subtract another 1 because the line ends with \n + view.state.doc.line_to_char(index + 1).saturating_sub(2) }) .map(|pos| Range::new(pos, pos)); @@ -236,10 +237,8 @@ pub fn open_below(view: &mut View, _count: usize) { let positions: Vec<_> = lines .into_iter() .map(|index| { - // adjust all positions to the end of the line. - let line = view.state.doc.line(index); - let line_start = view.state.doc.line_to_char(index); - line_start + line.len_chars() + // adjust all positions to the end of the line/start of the next one. + view.state.doc.line_to_char(index + 1) }) .collect();