feat(cmd): unify jump-to-edge and fix viewport scrolling
Replaces separate jump-to-edge commands with a unified `JumpToEdge` command. Simplifies the command registry using a macro and updates `ScrollRows` to use a shared `viewport_effects` helper for consistent scrolling behavior. This fixes a bug where viewport scrolling was based on a hardcoded constant (20) instead of the actual visible row count. Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-31B-it-GGUF:UD-Q5_K_XL)
This commit is contained in:
@ -313,75 +313,32 @@ impl Cmd for MoveSelection {
|
||||
}
|
||||
}
|
||||
|
||||
/// Unified jump-to-edge: jump to first/last row or column.
|
||||
/// `is_row` selects the axis; `end` selects first (false) or last (true).
|
||||
#[derive(Debug)]
|
||||
pub struct JumpToFirstRow {
|
||||
pub col: usize,
|
||||
pub struct JumpToEdge {
|
||||
pub cursor: CursorState,
|
||||
pub is_row: bool,
|
||||
pub end: bool,
|
||||
pub cmd_name: &'static str,
|
||||
}
|
||||
impl Cmd for JumpToFirstRow {
|
||||
impl Cmd for JumpToEdge {
|
||||
fn name(&self) -> &'static str {
|
||||
"jump-first-row"
|
||||
self.cmd_name
|
||||
}
|
||||
fn execute(&self, _ctx: &CmdContext) -> Vec<Box<dyn Effect>> {
|
||||
vec![
|
||||
Box::new(effect::SetSelected(0, self.col)),
|
||||
Box::new(effect::SetRowOffset(0)),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct JumpToLastRow {
|
||||
pub col: usize,
|
||||
pub row_count: usize,
|
||||
pub row_offset: usize,
|
||||
}
|
||||
impl Cmd for JumpToLastRow {
|
||||
fn name(&self) -> &'static str {
|
||||
"jump-last-row"
|
||||
}
|
||||
fn execute(&self, _ctx: &CmdContext) -> Vec<Box<dyn Effect>> {
|
||||
let last = self.row_count.saturating_sub(1);
|
||||
let mut effects: Vec<Box<dyn Effect>> = vec![Box::new(effect::SetSelected(last, self.col))];
|
||||
if last >= self.row_offset + 20 {
|
||||
effects.push(Box::new(effect::SetRowOffset(last.saturating_sub(19))));
|
||||
}
|
||||
effects
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct JumpToFirstCol {
|
||||
pub row: usize,
|
||||
}
|
||||
impl Cmd for JumpToFirstCol {
|
||||
fn name(&self) -> &'static str {
|
||||
"jump-first-col"
|
||||
}
|
||||
fn execute(&self, _ctx: &CmdContext) -> Vec<Box<dyn Effect>> {
|
||||
vec![
|
||||
Box::new(effect::SetSelected(self.row, 0)),
|
||||
Box::new(effect::SetColOffset(0)),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct JumpToLastCol {
|
||||
pub row: usize,
|
||||
pub col_count: usize,
|
||||
pub col_offset: usize,
|
||||
}
|
||||
impl Cmd for JumpToLastCol {
|
||||
fn name(&self) -> &'static str {
|
||||
"jump-last-col"
|
||||
}
|
||||
fn execute(&self, _ctx: &CmdContext) -> Vec<Box<dyn Effect>> {
|
||||
let last = self.col_count.saturating_sub(1);
|
||||
let mut effects: Vec<Box<dyn Effect>> = vec![Box::new(effect::SetSelected(self.row, last))];
|
||||
if last >= self.col_offset + 8 {
|
||||
effects.push(Box::new(effect::SetColOffset(last.saturating_sub(7))));
|
||||
}
|
||||
effects
|
||||
let (nr, nc) = if self.is_row {
|
||||
let r = if self.end { self.cursor.row_count.saturating_sub(1) } else { 0 };
|
||||
(r, self.cursor.col)
|
||||
} else {
|
||||
let c = if self.end { self.cursor.col_count.saturating_sub(1) } else { 0 };
|
||||
(self.cursor.row, c)
|
||||
};
|
||||
viewport_effects(
|
||||
nr, nc,
|
||||
self.cursor.row_offset, self.cursor.col_offset,
|
||||
self.cursor.visible_rows, self.cursor.visible_cols,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -397,19 +354,14 @@ impl Cmd for ScrollRows {
|
||||
fn execute(&self, _ctx: &CmdContext) -> Vec<Box<dyn Effect>> {
|
||||
let row_max = self.cursor.row_count.saturating_sub(1) as i32;
|
||||
let nr = (self.cursor.row as i32 + self.delta).clamp(0, row_max) as usize;
|
||||
let mut effects: Vec<Box<dyn Effect>> =
|
||||
vec![Box::new(effect::SetSelected(nr, self.cursor.col))];
|
||||
let mut row_offset = self.cursor.row_offset;
|
||||
if nr < row_offset {
|
||||
row_offset = nr;
|
||||
}
|
||||
if nr >= row_offset + 20 {
|
||||
row_offset = nr.saturating_sub(19);
|
||||
}
|
||||
if row_offset != self.cursor.row_offset {
|
||||
effects.push(Box::new(effect::SetRowOffset(row_offset)));
|
||||
}
|
||||
effects
|
||||
viewport_effects(
|
||||
nr,
|
||||
self.cursor.col,
|
||||
self.cursor.row_offset,
|
||||
self.cursor.col_offset,
|
||||
self.cursor.visible_rows,
|
||||
self.cursor.visible_cols,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2549,58 +2501,20 @@ pub fn default_registry() -> CmdRegistry {
|
||||
}))
|
||||
},
|
||||
);
|
||||
r.register(
|
||||
&JumpToFirstRow { col: 0 },
|
||||
|_| Ok(Box::new(JumpToFirstRow { col: 0 })),
|
||||
|_, ctx| {
|
||||
Ok(Box::new(JumpToFirstRow {
|
||||
col: ctx.selected.1,
|
||||
}))
|
||||
},
|
||||
);
|
||||
r.register(
|
||||
&JumpToLastRow { col: 0, row_count: 0, row_offset: 0 },
|
||||
|_| {
|
||||
Ok(Box::new(JumpToLastRow {
|
||||
col: 0,
|
||||
row_count: 0,
|
||||
row_offset: 0,
|
||||
}))
|
||||
},
|
||||
|_, ctx| {
|
||||
Ok(Box::new(JumpToLastRow {
|
||||
col: ctx.selected.1,
|
||||
row_count: ctx.row_count,
|
||||
row_offset: ctx.row_offset,
|
||||
}))
|
||||
},
|
||||
);
|
||||
r.register(
|
||||
&JumpToFirstCol { row: 0 },
|
||||
|_| Ok(Box::new(JumpToFirstCol { row: 0 })),
|
||||
|_, ctx| {
|
||||
Ok(Box::new(JumpToFirstCol {
|
||||
row: ctx.selected.0,
|
||||
}))
|
||||
},
|
||||
);
|
||||
r.register(
|
||||
&JumpToLastCol { row: 0, col_count: 0, col_offset: 0 },
|
||||
|_| {
|
||||
Ok(Box::new(JumpToLastCol {
|
||||
row: 0,
|
||||
col_count: 0,
|
||||
col_offset: 0,
|
||||
}))
|
||||
},
|
||||
|_, ctx| {
|
||||
Ok(Box::new(JumpToLastCol {
|
||||
row: ctx.selected.0,
|
||||
col_count: ctx.col_count,
|
||||
col_offset: ctx.col_offset,
|
||||
}))
|
||||
},
|
||||
);
|
||||
// Jump-to-edge commands: first/last row/col
|
||||
macro_rules! reg_jump {
|
||||
($r:expr, $is_row:expr, $end:expr, $name:expr) => {
|
||||
$r.register(
|
||||
&JumpToEdge { cursor: CursorState::default(), is_row: $is_row, end: $end, cmd_name: $name },
|
||||
|_| Ok(Box::new(JumpToEdge { cursor: CursorState::default(), is_row: $is_row, end: $end, cmd_name: $name })),
|
||||
|_, ctx| Ok(Box::new(JumpToEdge { cursor: CursorState::from_ctx(ctx), is_row: $is_row, end: $end, cmd_name: $name })),
|
||||
);
|
||||
};
|
||||
}
|
||||
reg_jump!(r, true, false, "jump-first-row");
|
||||
reg_jump!(r, true, true, "jump-last-row");
|
||||
reg_jump!(r, false, false, "jump-first-col");
|
||||
reg_jump!(r, false, true, "jump-last-col");
|
||||
r.register(
|
||||
&ScrollRows { delta: 0, cursor: CursorState::default() },
|
||||
|args| {
|
||||
|
||||
Reference in New Issue
Block a user