- fixed 'I' command in normal mode not moving to exact start of line

This commit is contained in:
2026-02-23 14:42:53 -05:00
parent 96425fb48f
commit 1a44a783e0
2 changed files with 51 additions and 2 deletions

View File

@@ -2055,9 +2055,10 @@ impl LineBuf {
} }
MotionCmd(_, Motion::BeginningOfFirstWord) => { MotionCmd(_, Motion::BeginningOfFirstWord) => {
let start = self.start_of_line(); let start = self.start_of_line();
let mut indices = self.directional_indices_iter_from(start, Direction::Forward); self.update_graphemes_lazy();
let indices = self.grapheme_indices().to_vec();
let mut first_graphical = None; let mut first_graphical = None;
while let Some(idx) = indices.next() { for &idx in indices.iter().skip(start) {
let grapheme = self.grapheme_at(idx).unwrap(); let grapheme = self.grapheme_at(idx).unwrap();
if !is_whitespace(grapheme) { if !is_whitespace(grapheme) {
first_graphical = Some(idx); first_graphical = Some(idx);

View File

@@ -174,6 +174,10 @@ impl LineWriter for TestWriter {
fn flush_write(&mut self, _buf: &str) -> libsh::error::ShResult<()> { fn flush_write(&mut self, _buf: &str) -> libsh::error::ShResult<()> {
Ok(()) Ok(())
} }
fn send_bell(&mut self) -> ShResult<()> {
Ok(())
}
} }
// NOTE: FernVi structure has changed significantly and readline() method no // NOTE: FernVi structure has changed significantly and readline() method no
@@ -598,6 +602,50 @@ fn editor_delete_line_up() {
) )
} }
#[test]
fn editor_insert_at_line_start() {
// I should move cursor to position 0 when line starts with non-whitespace
assert_eq!(
normal_cmd("I", "hello world", 5),
("hello world".into(), 0)
);
// I should skip leading whitespace
assert_eq!(
normal_cmd("I", " hello world", 8),
(" hello world".into(), 2)
);
// I should move to the first non-whitespace on the current line in a multiline buffer
assert_eq!(
normal_cmd("I", "first line\nsecond line", 14),
("first line\nsecond line".into(), 11)
);
// I should land on position 0 when cursor is already at 0
assert_eq!(
normal_cmd("I", "hello", 0),
("hello".into(), 0)
);
}
#[test]
fn editor_f_char_from_position_zero() {
// f<char> at position 0 should skip the cursor and find the next occurrence
// Regression: previously at pos 0, f would match the char under the cursor itself
assert_eq!(
normal_cmd("fa", "abcaef", 0),
("abcaef".into(), 3) // should find second 'a', not the 'a' at position 0
);
// f<char> from position 0 finding a char that only appears later
assert_eq!(
normal_cmd("fo", "hello world", 0),
("hello world".into(), 4)
);
// f<char> from middle of buffer
assert_eq!(
normal_cmd("fd", "hello world", 5),
("hello world".into(), 10)
);
}
// NOTE: These tests disabled because fernvi_test() helper is commented out // NOTE: These tests disabled because fernvi_test() helper is commented out
/* /*
#[test] #[test]