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 {
Char(char), // Insert a character
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
PaneOpen(Dir), // Create a new pane
PaneClose, // Close the current pane
@ -38,6 +38,14 @@ pub enum Action {
Save, // Save the current buffer
}
/// How far should movement go?
#[derive(Clone, Debug)]
pub enum Dist {
Char,
Page,
Doc,
}
#[derive(Debug)]
pub enum Event {
// 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 word = modifiers.contains(KeyModifiers::CONTROL);
let (dir, page) = match code {
KeyCode::PageUp => (Dir::Up, true),
KeyCode::PageDown => (Dir::Down, true),
KeyCode::Left => (Dir::Left, false),
KeyCode::Right => (Dir::Right, false),
KeyCode::Up => (Dir::Up, false),
KeyCode::Down => (Dir::Down, false),
let (dir, dist) = match code {
KeyCode::Home => (Dir::Up, Dist::Doc),
KeyCode::End => (Dir::Down, Dist::Doc),
KeyCode::PageUp => (Dir::Up, Dist::Page),
KeyCode::PageDown => (Dir::Down, Dist::Page),
KeyCode::Left => (Dir::Left, Dist::Char),
KeyCode::Right => (Dir::Right, Dist::Char),
KeyCode::Up => (Dir::Up, Dist::Char),
KeyCode::Down => (Dir::Down, Dist::Char),
_ => 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> {

View file

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

View file

@ -269,7 +269,7 @@ impl Search {
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 {
Dir::Up => {
self.selected = (self.selected + self.results.len().saturating_sub(1))

View file

@ -78,11 +78,12 @@ impl Input {
self.refocus(buffer, cursor_id);
Ok(Resp::handled(None))
}
Some(Action::Move(dir, page, retain_base, word)) => {
let dist = if page {
self.last_size.map(|s| s.saturating_sub(3).max(1))
} else {
[1, 1]
Some(Action::Move(dir, dist, retain_base, word)) => {
let dist = match dist {
Dist::Char => [1, 1],
Dist::Page => self.last_size.map(|s| s.saturating_sub(3).max(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);
self.refocus(buffer, cursor_id);

View file

@ -14,6 +14,8 @@ pub use self::{
status::Status,
};
use super::*;
use crate::{
Action, Dir, Event, State,
terminal::{Color, Rect},
@ -149,7 +151,7 @@ impl<T> Options<T> {
impl<T: Clone> Element<T> for Options<T> {
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())) {
Some(Action::Move(dir, false, false, false)) => {
Some(Action::Move(dir, Dist::Char, false, false)) => {
match dir {
Dir::Up => {
self.selected =