Skip to content

Commit

Permalink
fix Cut/Change/Delete under visual-mode (follow-up): selection range …
Browse files Browse the repository at this point in the history
…considers UTF8
  • Loading branch information
Jean-FrançoisMillet authored and deephbz committed Jan 18, 2025
1 parent 57c2128 commit 9066490
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/core_editor/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,12 +568,14 @@ impl Editor {
if self.insertion_point() > selection_anchor {
(
selection_anchor,
(self.insertion_point() + 1).min(buffer_len),
self.line_buffer.grapheme_right_index().min(buffer_len),
)
} else {
(
self.insertion_point(),
(selection_anchor + 1).min(buffer_len),
self.line_buffer
.grapheme_right_index_from_pos(selection_anchor)
.min(buffer_len),
)
}
})
Expand Down
31 changes: 31 additions & 0 deletions src/core_editor/line_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,15 @@ impl LineBuffer {
.unwrap_or(0)
}

/// Cursor position *behind* the next unicode grapheme to the right from the given position
pub fn grapheme_right_index_from_pos(&self, pos: usize) -> usize {
self.lines[pos..]
.grapheme_indices(true)
.nth(1)
.map(|(i, _)| pos + i)
.unwrap_or_else(|| self.lines.len())
}

/// Cursor position *behind* the next word to the right
pub fn word_right_index(&self) -> usize {
self.lines[self.insertion_point..]
Expand Down Expand Up @@ -1597,4 +1606,26 @@ mod test {

assert_eq!(index, expected);
}

#[rstest]
#[case("abc", 0, 1)] // Basic ASCII
#[case("abc", 1, 2)] // From middle position
#[case("abc", 2, 3)] // From last char
#[case("abc", 3, 3)] // From end of string
#[case("🦀rust", 0, 4)] // Unicode emoji
#[case("🦀rust", 4, 5)] // After emoji
#[case("é́", 0, 4)] // Combining characters
fn test_grapheme_right_index_from_pos(
#[case] input: &str,
#[case] position: usize,
#[case] expected: usize,
) {
let mut line = LineBuffer::new();
line.insert_str(input);
assert_eq!(
line.grapheme_right_index_from_pos(position),
expected,
"input: {input:?}, pos: {position}"
);
}
}

0 comments on commit 9066490

Please sign in to comment.