From fa83b2efe9cda4ff360eb0cb156b91451f17d65b Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Wed, 8 Nov 2023 11:03:53 -0700 Subject: [PATCH] Support NextChar and PreviousChar modit motions --- src/edit/vi.rs | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/edit/vi.rs b/src/edit/vi.rs index 13027bd..bb6f3ac 100644 --- a/src/edit/vi.rs +++ b/src/edit/vi.rs @@ -216,6 +216,43 @@ impl<'a> Edit for ViEditor<'a> { } Motion::Home => Action::Home, Motion::Left => Action::Left, + Motion::NextChar(find_c) => { + let mut cursor = editor.cursor(); + let buffer = editor.buffer_mut(); + let text = buffer.lines[cursor.line].text(); + if cursor.index < text.len() { + match text[cursor.index..] + .char_indices() + .filter(|&(i, c)| i > 0 && c == find_c) + .next() + { + Some((i, _)) => { + cursor.index += i; + editor.set_cursor(cursor); + } + None => {} + } + } + continue; + } + Motion::NextCharTill(find_c) => { + let mut cursor = editor.cursor(); + let buffer = editor.buffer_mut(); + let text = buffer.lines[cursor.line].text(); + if cursor.index < text.len() { + let mut last_i = 0; + for (i, c) in text[cursor.index..].char_indices() { + if last_i > 0 && c == find_c { + cursor.index += last_i; + editor.set_cursor(cursor); + break; + } else { + last_i = i; + } + } + } + continue; + } Motion::NextWordEnd(word) => { let mut cursor = editor.cursor(); let buffer = editor.buffer_mut(); @@ -272,6 +309,52 @@ impl<'a> Edit for ViEditor<'a> { editor.set_cursor(cursor); continue; } + Motion::PreviousChar(find_c) => { + let mut cursor = editor.cursor(); + let buffer = editor.buffer_mut(); + let text = buffer.lines[cursor.line].text(); + if cursor.index > 0 { + match text[..cursor.index] + .char_indices() + .filter(|&(_, c)| c == find_c) + .last() + { + Some((i, _)) => { + cursor.index = i; + editor.set_cursor(cursor); + } + None => {} + } + } + continue; + } + Motion::PreviousCharTill(find_c) => { + let mut cursor = editor.cursor(); + let buffer = editor.buffer_mut(); + let text = buffer.lines[cursor.line].text(); + if cursor.index > 0 { + match text[..cursor.index] + .char_indices() + .filter_map(|(i, c)| { + if c == find_c { + let end = i + c.len_utf8(); + if end < cursor.index { + return Some(end); + } + } + None + }) + .last() + { + Some(i) => { + cursor.index = i; + editor.set_cursor(cursor); + } + None => {} + } + } + continue; + } Motion::PreviousWordEnd(word) => { let mut cursor = editor.cursor(); let buffer = editor.buffer_mut();