Support modit::Key enum

This commit is contained in:
Jeremy Soller 2023-11-10 09:47:45 -07:00
parent 9efcc41a5a
commit e8dd8ec7d1
No known key found for this signature in database
GPG key ID: DCFCA852D3906975

View file

@ -1,6 +1,6 @@
use alloc::string::String; use alloc::string::String;
use core::cmp; use core::cmp;
use modit::{Event, Motion, Parser, TextObject, WordIter}; use modit::{Event, Key, Motion, Parser, TextObject, WordIter};
use unicode_segmentation::UnicodeSegmentation; use unicode_segmentation::UnicodeSegmentation;
use crate::{ use crate::{
@ -183,15 +183,15 @@ impl<'a> Edit for ViEditor<'a> {
fn action(&mut self, font_system: &mut FontSystem, action: Action) { fn action(&mut self, font_system: &mut FontSystem, action: Action) {
let editor = &mut self.editor; let editor = &mut self.editor;
log::info!("Action {:?}", action); log::info!("Action {:?}", action);
let c = match action { let key = match action {
Action::Escape => modit::ESCAPE, Action::Backspace => Key::Backspace,
Action::Insert(c) => c, Action::Delete => Key::Delete,
Action::Enter => modit::ENTER, Action::Enter => Key::Enter,
Action::Backspace => modit::BACKSPACE, Action::Escape => Key::Escape,
Action::Delete => modit::DELETE, Action::Insert(c) => Key::Char(c),
_ => return editor.action(font_system, action), _ => return editor.action(font_system, action),
}; };
self.parser.parse(c, false, |event| { self.parser.parse(key, false, |event| {
log::info!(" Event {:?}", event); log::info!(" Event {:?}", event);
let action = match event { let action = match event {
Event::AutoIndent => { Event::AutoIndent => {
@ -333,225 +333,213 @@ impl<'a> Edit for ViEditor<'a> {
log::info!("TODO"); log::info!("TODO");
return; return;
} }
Event::Motion(motion, count) => { Event::Motion(motion) => {
for _ in 0..count { match motion {
let action = match motion { Motion::Down => Action::Down,
Motion::Down => Action::Down, Motion::End => Action::End,
Motion::End => Action::End, Motion::GotoLine(line) => Action::GotoLine(line.saturating_sub(1)),
Motion::GotoLine(line) => Action::GotoLine(line.saturating_sub(1)), Motion::GotoEof => {
Motion::GotoEof => { Action::GotoLine(editor.buffer().lines.len().saturating_sub(1))
Action::GotoLine(editor.buffer().lines.len().saturating_sub(1)) }
Motion::Home => Action::Home,
Motion::Left => Action::Left,
Motion::NextChar(find_c) => {
let mut cursor = editor.cursor();
let buffer = editor.buffer();
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 => {}
}
} }
Motion::Home => Action::Home, return;
Motion::Left => Action::Left, }
Motion::NextChar(find_c) => { Motion::NextCharTill(find_c) => {
let mut cursor = editor.cursor(); let mut cursor = editor.cursor();
let buffer = editor.buffer(); let buffer = editor.buffer();
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;
}
}
}
return;
}
Motion::NextWordEnd(word) => {
let mut cursor = editor.cursor();
let buffer = editor.buffer();
loop {
let text = buffer.lines[cursor.line].text(); let text = buffer.lines[cursor.line].text();
if cursor.index < text.len() { if cursor.index < text.len() {
match text[cursor.index..] cursor.index = WordIter::new(text, word)
.char_indices() .map(|(i, w)| {
.filter(|&(i, c)| i > 0 && c == find_c) i + w.char_indices().last().map(|(i, _)| i).unwrap_or(0)
.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();
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();
loop {
let text = buffer.lines[cursor.line].text();
if cursor.index < text.len() {
cursor.index = WordIter::new(text, word)
.map(|(i, w)| {
i + w
.char_indices()
.last()
.map(|(i, _)| i)
.unwrap_or(0)
})
.find(|&i| i > cursor.index)
.unwrap_or(text.len());
if cursor.index == text.len() {
// Try again, searching next line
continue;
}
} else if cursor.line + 1 < buffer.lines.len() {
// Go to next line and rerun loop
cursor.line += 1;
cursor.index = 0;
continue;
}
break;
}
editor.set_cursor(cursor);
continue;
}
Motion::NextWordStart(word) => {
let mut cursor = editor.cursor();
let buffer = editor.buffer();
loop {
let text = buffer.lines[cursor.line].text();
if cursor.index < text.len() {
cursor.index = WordIter::new(text, word)
.map(|(i, _)| i)
.find(|&i| i > cursor.index)
.unwrap_or(text.len());
if cursor.index == text.len() {
// Try again, searching next line
continue;
}
} else if cursor.line + 1 < buffer.lines.len() {
// Go to next line and rerun loop
cursor.line += 1;
cursor.index = 0;
continue;
}
break;
}
editor.set_cursor(cursor);
continue;
}
Motion::PreviousChar(find_c) => {
let mut cursor = editor.cursor();
let buffer = editor.buffer();
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();
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() .find(|&i| i > cursor.index)
{ .unwrap_or(text.len());
Some(i) => { if cursor.index == text.len() {
cursor.index = i; // Try again, searching next line
editor.set_cursor(cursor);
}
None => {}
}
}
continue;
}
Motion::PreviousWordEnd(word) => {
let mut cursor = editor.cursor();
let buffer = editor.buffer();
loop {
let text = buffer.lines[cursor.line].text();
if cursor.index > 0 {
cursor.index = WordIter::new(text, word)
.map(|(i, w)| {
i + w
.char_indices()
.last()
.map(|(i, _)| i)
.unwrap_or(0)
})
.filter(|&i| i < cursor.index)
.last()
.unwrap_or(0);
if cursor.index == 0 {
// Try again, searching previous line
continue;
}
} else if cursor.line > 0 {
// Go to previous line and rerun loop
cursor.line -= 1;
cursor.index = buffer.lines[cursor.line].text().len();
continue; continue;
} }
break; } else if cursor.line + 1 < buffer.lines.len() {
// Go to next line and rerun loop
cursor.line += 1;
cursor.index = 0;
continue;
} }
editor.set_cursor(cursor);
continue;
}
Motion::PreviousWordStart(word) => {
let mut cursor = editor.cursor();
let buffer = editor.buffer();
loop {
let text = buffer.lines[cursor.line].text();
if cursor.index > 0 {
cursor.index = WordIter::new(text, word)
.map(|(i, _)| i)
.filter(|&i| i < cursor.index)
.last()
.unwrap_or(0);
if cursor.index == 0 {
// Try again, searching previous line
continue;
}
} else if cursor.line > 0 {
// Go to previous line and rerun loop
cursor.line -= 1;
cursor.index = buffer.lines[cursor.line].text().len();
continue;
}
break;
}
editor.set_cursor(cursor);
continue;
}
Motion::Right => Action::Right,
Motion::SoftHome => Action::SoftHome,
Motion::Up => Action::Up,
_ => {
log::info!("TODO: {:?}", motion);
break; break;
} }
}; editor.set_cursor(cursor);
editor.action(font_system, action); return;
}
Motion::NextWordStart(word) => {
let mut cursor = editor.cursor();
let buffer = editor.buffer();
loop {
let text = buffer.lines[cursor.line].text();
if cursor.index < text.len() {
cursor.index = WordIter::new(text, word)
.map(|(i, _)| i)
.find(|&i| i > cursor.index)
.unwrap_or(text.len());
if cursor.index == text.len() {
// Try again, searching next line
continue;
}
} else if cursor.line + 1 < buffer.lines.len() {
// Go to next line and rerun loop
cursor.line += 1;
cursor.index = 0;
continue;
}
break;
}
editor.set_cursor(cursor);
return;
}
Motion::PreviousChar(find_c) => {
let mut cursor = editor.cursor();
let buffer = editor.buffer();
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 => {}
}
}
return;
}
Motion::PreviousCharTill(find_c) => {
let mut cursor = editor.cursor();
let buffer = editor.buffer();
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 => {}
}
}
return;
}
Motion::PreviousWordEnd(word) => {
let mut cursor = editor.cursor();
let buffer = editor.buffer();
loop {
let text = buffer.lines[cursor.line].text();
if cursor.index > 0 {
cursor.index = WordIter::new(text, word)
.map(|(i, w)| {
i + w.char_indices().last().map(|(i, _)| i).unwrap_or(0)
})
.filter(|&i| i < cursor.index)
.last()
.unwrap_or(0);
if cursor.index == 0 {
// Try again, searching previous line
continue;
}
} else if cursor.line > 0 {
// Go to previous line and rerun loop
cursor.line -= 1;
cursor.index = buffer.lines[cursor.line].text().len();
continue;
}
break;
}
editor.set_cursor(cursor);
return;
}
Motion::PreviousWordStart(word) => {
let mut cursor = editor.cursor();
let buffer = editor.buffer();
loop {
let text = buffer.lines[cursor.line].text();
if cursor.index > 0 {
cursor.index = WordIter::new(text, word)
.map(|(i, _)| i)
.filter(|&i| i < cursor.index)
.last()
.unwrap_or(0);
if cursor.index == 0 {
// Try again, searching previous line
continue;
}
} else if cursor.line > 0 {
// Go to previous line and rerun loop
cursor.line -= 1;
cursor.index = buffer.lines[cursor.line].text().len();
continue;
}
break;
}
editor.set_cursor(cursor);
return;
}
Motion::Right => Action::Right,
Motion::SoftHome => Action::SoftHome,
Motion::Up => Action::Up,
_ => {
log::info!("TODO: {:?}", motion);
return;
}
} }
return;
} }
}; };
editor.action(font_system, action); editor.action(font_system, action);