This commit is contained in:
alice pellerin
2026-03-17 03:07:30 -05:00
parent 1d348ca5f8
commit 72dfcdb6c9
2 changed files with 119 additions and 61 deletions
+102 -48
View File
@@ -11,7 +11,20 @@ pub struct App {
pub window_rows: usize, pub window_rows: usize,
pub scroll_position: usize, pub scroll_position: usize,
pub cursor: Cursor, pub cursor: Cursor,
pub should_quit: bool pub should_quit: bool,
pub mode: Mode,
pub partial_shortcut: Option<PartialShortcut>,
pub logs: Vec<String>,
}
#[derive(Debug)]
pub enum Mode {
Normal, Visual, Insert
}
#[derive(Debug)]
pub enum PartialShortcut {
Goto, Zview
} }
impl App { impl App {
@@ -36,7 +49,10 @@ impl App {
window_rows: window_size().unwrap().rows as usize, window_rows: window_size().unwrap().rows as usize,
scroll_position: 0, scroll_position: 0,
cursor: Cursor::default(), cursor: Cursor::default(),
should_quit: false should_quit: false,
mode: Mode::Normal,
partial_shortcut: None,
logs: Vec::new(),
} }
} }
@@ -48,14 +64,18 @@ impl App {
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub fn handle_events(&mut self) { pub fn handle_events(&mut self) {
#[allow(clippy::collapsible_match)] #[allow(clippy::collapsible_match)]
match event::read().unwrap() { match (&self.mode, event::read().unwrap(), &self.partial_shortcut) {
Event::Resize(_, height) => { (Mode::Normal, Event::Resize(_, height), _) => {
self.window_rows = height as usize; self.window_rows = height as usize;
} }
Event::Key(key_event) if key_event.code == KeyCode::Char('q') => {
(Mode::Normal, Event::Key(key_event), None)
if key_event.code == KeyCode::Char('q') => {
self.should_quit = true; self.should_quit = true;
} }
Event::Key(key_event) if key_event.modifiers.contains(KeyModifiers::CONTROL) &&
(Mode::Normal, Event::Key(key_event), None)
if key_event.modifiers.contains(KeyModifiers::CONTROL) &&
key_event.code == KeyCode::Char('e') => { key_event.code == KeyCode::Char('e') => {
self.scroll_position = min( self.scroll_position = min(
self.scroll_position + BYTES_PER_LINE, self.scroll_position + BYTES_PER_LINE,
@@ -63,12 +83,17 @@ impl App {
); );
self.cursor.clamp(self.scroll_position, self.screen_size()); self.cursor.clamp(self.scroll_position, self.screen_size());
} }
Event::Key(key_event) if key_event.modifiers.contains(KeyModifiers::CONTROL) &&
(Mode::Normal, Event::Key(key_event), None)
if key_event.modifiers.contains(KeyModifiers::CONTROL) &&
key_event.code == KeyCode::Char('y') => { key_event.code == KeyCode::Char('y') => {
self.scroll_position = self.scroll_position.saturating_sub(BYTES_PER_LINE); self.scroll_position = self.scroll_position.saturating_sub(BYTES_PER_LINE);
self.cursor.clamp(self.scroll_position, self.screen_size()); self.cursor.clamp(self.scroll_position, self.screen_size());
} }
Event::Key(key_event) if key_event.modifiers.contains(KeyModifiers::CONTROL) &&
// TODO: for up/down, keep cursor at same relative position on screen
(Mode::Normal, Event::Key(key_event), None)
if key_event.modifiers.contains(KeyModifiers::CONTROL) &&
key_event.code == KeyCode::Char('d') => { key_event.code == KeyCode::Char('d') => {
self.scroll_position = min( self.scroll_position = min(
self.scroll_position + self.screen_size() / 2, self.scroll_position + self.screen_size() / 2,
@@ -76,15 +101,18 @@ impl App {
); );
self.cursor.clamp(self.scroll_position, self.screen_size()); self.cursor.clamp(self.scroll_position, self.screen_size());
} }
// TODO: for up/down, keep cursor at same relative position on screen
Event::Key(key_event) if key_event.modifiers.contains(KeyModifiers::CONTROL) && (Mode::Normal, Event::Key(key_event), None)
if key_event.modifiers.contains(KeyModifiers::CONTROL) &&
key_event.code == KeyCode::Char('u') => { key_event.code == KeyCode::Char('u') => {
self.scroll_position = self.scroll_position.saturating_sub( self.scroll_position = self.scroll_position.saturating_sub(
self.screen_size() / 2 self.screen_size() / 2
); );
self.cursor.clamp(self.scroll_position, self.screen_size()); self.cursor.clamp(self.scroll_position, self.screen_size());
} }
Event::Key(key_event) if key_event.modifiers.contains(KeyModifiers::CONTROL) &&
(Mode::Normal, Event::Key(key_event), None)
if key_event.modifiers.contains(KeyModifiers::CONTROL) &&
key_event.code == KeyCode::Char('f') => { key_event.code == KeyCode::Char('f') => {
self.scroll_position = min( self.scroll_position = min(
self.scroll_position + self.screen_size(), self.scroll_position + self.screen_size(),
@@ -92,24 +120,42 @@ impl App {
); );
self.cursor.clamp(self.scroll_position, self.screen_size()); self.cursor.clamp(self.scroll_position, self.screen_size());
} }
Event::Key(key_event) if key_event.modifiers.contains(KeyModifiers::CONTROL) &&
(Mode::Normal, Event::Key(key_event), None)
if key_event.modifiers.contains(KeyModifiers::CONTROL) &&
key_event.code == KeyCode::Char('b') => { key_event.code == KeyCode::Char('b') => {
self.scroll_position = self.scroll_position.saturating_sub( self.scroll_position = self.scroll_position.saturating_sub(
self.screen_size() self.screen_size()
); );
self.cursor.clamp(self.scroll_position, self.screen_size()); self.cursor.clamp(self.scroll_position, self.screen_size());
} }
// Event::Key(key_event) if key_event.code == KeyCode::Char('g') => {
// } (Mode::Normal, Event::Key(key_event), None)
Event::Key(key_event) if key_event.code == KeyCode::Char('G') => { if key_event.code == KeyCode::Char('g') => {
self.partial_shortcut = Some(PartialShortcut::Goto);
}
(Mode::Normal, Event::Key(key_event), Some(PartialShortcut::Goto))
if key_event.code == KeyCode::Char('g') => {
self.partial_shortcut = None;
self.cursor.head %= BYTES_PER_LINE;
self.cursor.collapse();
self.clamp_screen_to_cursor();
}
(Mode::Normal, Event::Key(key_event), None)
if key_event.code == KeyCode::Char('G') => {
self.cursor.head = previous_multiple_of(BYTES_PER_LINE, self.contents.len()) + self.cursor.head = previous_multiple_of(BYTES_PER_LINE, self.contents.len()) +
(self.cursor.head % BYTES_PER_LINE); (self.cursor.head % BYTES_PER_LINE);
self.cursor.collapse(); self.cursor.collapse();
self.clamp_screen_to_cursor(); self.clamp_screen_to_cursor();
} }
Event::Key(key_event) if key_event.code == KeyCode::Char('i') ||
(Mode::Normal, Event::Key(key_event), None)
if key_event.code == KeyCode::Char('i') ||
key_event.code == KeyCode::Up => { key_event.code == KeyCode::Up => {
self.partial_shortcut = None;
if self.cursor.head >= BYTES_PER_LINE { if self.cursor.head >= BYTES_PER_LINE {
self.cursor.head -= BYTES_PER_LINE; self.cursor.head -= BYTES_PER_LINE;
self.cursor.collapse(); self.cursor.collapse();
@@ -117,7 +163,9 @@ impl App {
self.clamp_screen_to_cursor(); self.clamp_screen_to_cursor();
} }
} }
Event::Key(key_event) if key_event.code == KeyCode::Char('j') ||
(Mode::Normal, Event::Key(key_event), None)
if key_event.code == KeyCode::Char('j') ||
key_event.code == KeyCode::Left => { key_event.code == KeyCode::Left => {
if self.cursor.head >= 1 { if self.cursor.head >= 1 {
self.cursor.head -= 1; self.cursor.head -= 1;
@@ -126,7 +174,17 @@ impl App {
self.clamp_screen_to_cursor(); self.clamp_screen_to_cursor();
} }
} }
Event::Key(key_event) if key_event.code == KeyCode::Char('k') ||
(Mode::Normal, Event::Key(key_event), Some(PartialShortcut::Goto))
if key_event.code == KeyCode::Char('j') ||
key_event.code == KeyCode::Left => {
self.partial_shortcut = None;
self.cursor.head -= self.cursor.head % BYTES_PER_LINE;
self.cursor.collapse();
}
(Mode::Normal, Event::Key(key_event), None)
if key_event.code == KeyCode::Char('k') ||
key_event.code == KeyCode::Down => { key_event.code == KeyCode::Down => {
if self.contents.len() - 1 - self.cursor.head >= BYTES_PER_LINE { if self.contents.len() - 1 - self.cursor.head >= BYTES_PER_LINE {
self.cursor.head += BYTES_PER_LINE; self.cursor.head += BYTES_PER_LINE;
@@ -135,7 +193,9 @@ impl App {
self.clamp_screen_to_cursor(); self.clamp_screen_to_cursor();
} }
} }
Event::Key(key_event) if key_event.code == KeyCode::Char('l') ||
(Mode::Normal, Event::Key(key_event), None)
if key_event.code == KeyCode::Char('l') ||
key_event.code == KeyCode::Right => { key_event.code == KeyCode::Right => {
if self.contents.len() - 1 - self.cursor.head >= 1 { if self.contents.len() - 1 - self.cursor.head >= 1 {
self.cursor.head += 1; self.cursor.head += 1;
@@ -144,49 +204,43 @@ impl App {
self.clamp_screen_to_cursor(); self.clamp_screen_to_cursor();
} }
} }
Event::Key(key_event) if key_event.code == KeyCode::Char('I') => {
if self.cursor.head >= BYTES_PER_LINE {
self.cursor.head -= BYTES_PER_LINE;
self.clamp_screen_to_cursor(); (Mode::Normal, Event::Key(key_event), Some(PartialShortcut::Goto))
if key_event.code == KeyCode::Char('l') ||
key_event.code == KeyCode::Right => {
self.partial_shortcut = None;
self.cursor.head += BYTES_PER_LINE - 1 - (self.cursor.head % BYTES_PER_LINE);
self.cursor.collapse();
} }
}
Event::Key(key_event) if key_event.code == KeyCode::Char('J') => {
if self.cursor.head >= 1 {
self.cursor.head -= 1;
self.clamp_screen_to_cursor(); (Mode::Normal, Event::Key(key_event), None)
} if key_event.code == KeyCode::Char('w') => {
}
Event::Key(key_event) if key_event.code == KeyCode::Char('K') => {
if self.contents.len() - 1 - self.cursor.head >= BYTES_PER_LINE {
self.cursor.head += BYTES_PER_LINE;
self.clamp_screen_to_cursor();
}
}
Event::Key(key_event) if key_event.code == KeyCode::Char('L') => {
if self.contents.len() - 1 - self.cursor.head >= 1 {
self.cursor.head += 1;
self.clamp_screen_to_cursor();
}
}
Event::Key(key_event) if key_event.code == KeyCode::Char('w') => {
self.cursor.move_to_next_word(self.contents.len() - 1); self.cursor.move_to_next_word(self.contents.len() - 1);
self.clamp_screen_to_cursor(); self.clamp_screen_to_cursor();
} }
Event::Key(key_event) if key_event.code == KeyCode::Char('e') => {
(Mode::Normal, Event::Key(key_event), None)
if key_event.code == KeyCode::Char('e') => {
self.cursor.move_to_next_end(self.contents.len() - 1); self.cursor.move_to_next_end(self.contents.len() - 1);
self.clamp_screen_to_cursor(); self.clamp_screen_to_cursor();
} }
Event::Key(key_event) if key_event.code == KeyCode::Char('b') => {
(Mode::Normal, Event::Key(key_event), None)
if key_event.code == KeyCode::Char('b') => {
self.cursor.move_to_previous_beginning(); self.cursor.move_to_previous_beginning();
self.clamp_screen_to_cursor(); self.clamp_screen_to_cursor();
} }
Event::Key(key_event) if key_event.code == KeyCode::Char(';') => {
(Mode::Normal, Event::Key(key_event), None)
if key_event.code == KeyCode::Char(';') => {
self.cursor.collapse(); self.cursor.collapse();
} }
(Mode::Normal, Event::Key(_), Some(_)) => {
self.logs.push("key press!".to_string());
self.partial_shortcut = None;
}
_ => {} _ => {}
} }
} }
+4
View File
@@ -36,4 +36,8 @@ fn main() {
} }
ratatui::restore(); ratatui::restore();
for log in app.logs {
println!("{log}");
}
} }