Support modit::Key enum
This commit is contained in:
parent
9efcc41a5a
commit
e8dd8ec7d1
1 changed files with 205 additions and 217 deletions
422
src/edit/vi.rs
422
src/edit/vi.rs
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue