Added support for home/end cursor movement

This commit is contained in:
Joshua Barretto 2025-09-22 14:10:19 +01:00
parent 0b484e8592
commit 85c88402ca
5 changed files with 30 additions and 17 deletions

View file

@ -14,7 +14,7 @@ pub enum Dir {
pub enum Action { pub enum Action {
Char(char), // Insert a character Char(char), // Insert a character
Indent(bool), // Indent (indent vs deindent) Indent(bool), // Indent (indent vs deindent)
Move(Dir, bool, bool, bool), // Move the cursor (dir, page, retain_base, word) Move(Dir, Dist, bool, bool), // Move the cursor (dir, page, retain_base, word)
PaneMove(Dir), // Move panes PaneMove(Dir), // Move panes
PaneOpen(Dir), // Create a new pane PaneOpen(Dir), // Create a new pane
PaneClose, // Close the current pane PaneClose, // Close the current pane
@ -38,6 +38,14 @@ pub enum Action {
Save, // Save the current buffer Save, // Save the current buffer
} }
/// How far should movement go?
#[derive(Clone, Debug)]
pub enum Dist {
Char,
Page,
Doc,
}
#[derive(Debug)] #[derive(Debug)]
pub enum Event { pub enum Event {
// The incoming event is an action generated by some other internal component. // The incoming event is an action generated by some other internal component.
@ -162,17 +170,19 @@ impl RawEvent {
let retain_base = modifiers.contains(KeyModifiers::SHIFT); let retain_base = modifiers.contains(KeyModifiers::SHIFT);
let word = modifiers.contains(KeyModifiers::CONTROL); let word = modifiers.contains(KeyModifiers::CONTROL);
let (dir, page) = match code { let (dir, dist) = match code {
KeyCode::PageUp => (Dir::Up, true), KeyCode::Home => (Dir::Up, Dist::Doc),
KeyCode::PageDown => (Dir::Down, true), KeyCode::End => (Dir::Down, Dist::Doc),
KeyCode::Left => (Dir::Left, false), KeyCode::PageUp => (Dir::Up, Dist::Page),
KeyCode::Right => (Dir::Right, false), KeyCode::PageDown => (Dir::Down, Dist::Page),
KeyCode::Up => (Dir::Up, false), KeyCode::Left => (Dir::Left, Dist::Char),
KeyCode::Down => (Dir::Down, false), KeyCode::Right => (Dir::Right, Dist::Char),
KeyCode::Up => (Dir::Up, Dist::Char),
KeyCode::Down => (Dir::Down, Dist::Char),
_ => return None, _ => return None,
}; };
Some(Action::Move(dir, page, retain_base, word)) Some(Action::Move(dir, dist, retain_base, word))
} }
pub fn to_select_token(&self) -> Option<Action> { pub fn to_select_token(&self) -> Option<Action> {

View file

@ -6,7 +6,7 @@ mod theme;
mod ui; mod ui;
use crate::{ use crate::{
action::{Action, Dir, Event}, action::{Action, Dir, Dist, Event},
state::State, state::State,
terminal::{Color, Terminal, TerminalEvent}, terminal::{Color, Terminal, TerminalEvent},
ui::{Element as _, Visual as _}, ui::{Element as _, Visual as _},

View file

@ -269,7 +269,7 @@ impl Search {
return Ok(Resp::end(None)); return Ok(Resp::end(None));
} }
Some(Action::Go) => return Ok(Resp::end(None)), Some(Action::Go) => return Ok(Resp::end(None)),
Some(Action::Move(dir, false, false, false)) => { Some(Action::Move(dir, Dist::Char, false, false)) => {
match dir { match dir {
Dir::Up => { Dir::Up => {
self.selected = (self.selected + self.results.len().saturating_sub(1)) self.selected = (self.selected + self.results.len().saturating_sub(1))

View file

@ -78,11 +78,12 @@ impl Input {
self.refocus(buffer, cursor_id); self.refocus(buffer, cursor_id);
Ok(Resp::handled(None)) Ok(Resp::handled(None))
} }
Some(Action::Move(dir, page, retain_base, word)) => { Some(Action::Move(dir, dist, retain_base, word)) => {
let dist = if page { let dist = match dist {
self.last_size.map(|s| s.saturating_sub(3).max(1)) Dist::Char => [1, 1],
} else { Dist::Page => self.last_size.map(|s| s.saturating_sub(3).max(1)),
[1, 1] // TODO: Don't just use an arbitrary very large number
Dist::Doc => [1_000_000_000; 2],
}; };
buffer.move_cursor(cursor_id, dir, dist, retain_base, word); buffer.move_cursor(cursor_id, dir, dist, retain_base, word);
self.refocus(buffer, cursor_id); self.refocus(buffer, cursor_id);

View file

@ -14,6 +14,8 @@ pub use self::{
status::Status, status::Status,
}; };
use super::*;
use crate::{ use crate::{
Action, Dir, Event, State, Action, Dir, Event, State,
terminal::{Color, Rect}, terminal::{Color, Rect},
@ -149,7 +151,7 @@ impl<T> Options<T> {
impl<T: Clone> Element<T> for Options<T> { impl<T: Clone> Element<T> for Options<T> {
fn handle(&mut self, state: &mut State, event: Event) -> Result<Resp<T>, Event> { fn handle(&mut self, state: &mut State, event: Event) -> Result<Resp<T>, Event> {
match event.to_action(|e| e.to_go().or_else(|| e.to_move())) { match event.to_action(|e| e.to_go().or_else(|| e.to_move())) {
Some(Action::Move(dir, false, false, false)) => { Some(Action::Move(dir, Dist::Char, false, false)) => {
match dir { match dir {
Dir::Up => { Dir::Up => {
self.selected = self.selected =