Fix cursor getting stuck when Enter pressed on last row
move_selection() only clamped at 0, letting the row/col index go past the last valid item. Selected_cell_key() would then return None, leaving the cursor in a phantom position with no selectable cell. Now clamp both row and col against the actual item count so pressing Enter on the last row keeps the cursor on that row. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@ -899,11 +899,31 @@ impl App {
|
||||
// ── Motion helpers ───────────────────────────────────────────────────────
|
||||
|
||||
fn move_selection(&mut self, dr: i32, dc: i32) {
|
||||
// Compute max row/col from actual item counts so we never go out of bounds.
|
||||
let row_max = {
|
||||
let row_cats: Vec<String> = self.model.active_view()
|
||||
.map(|v| v.categories_on(crate::view::Axis::Row).into_iter().map(String::from).collect())
|
||||
.unwrap_or_default();
|
||||
row_cats.first()
|
||||
.and_then(|c| self.model.category(c))
|
||||
.map(|c| c.items.len().saturating_sub(1))
|
||||
.unwrap_or(0)
|
||||
};
|
||||
let col_max = {
|
||||
let col_cats: Vec<String> = self.model.active_view()
|
||||
.map(|v| v.categories_on(crate::view::Axis::Column).into_iter().map(String::from).collect())
|
||||
.unwrap_or_default();
|
||||
col_cats.first()
|
||||
.and_then(|c| self.model.category(c))
|
||||
.map(|c| c.items.len().saturating_sub(1))
|
||||
.unwrap_or(0)
|
||||
};
|
||||
|
||||
if let Some(view) = self.model.active_view_mut() {
|
||||
let (r, c) = view.selected;
|
||||
view.selected = (
|
||||
(r as i32 + dr).max(0) as usize,
|
||||
(c as i32 + dc).max(0) as usize,
|
||||
(r as i32 + dr).clamp(0, row_max as i32) as usize,
|
||||
(c as i32 + dc).clamp(0, col_max as i32) as usize,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
144
whatever.improv
144
whatever.improv
@ -128,29 +128,6 @@
|
||||
"Number": 3.0
|
||||
}
|
||||
],
|
||||
[
|
||||
[
|
||||
[
|
||||
"Month",
|
||||
"Janury"
|
||||
],
|
||||
[
|
||||
"Payer",
|
||||
"Bernadette"
|
||||
],
|
||||
[
|
||||
"Recipient",
|
||||
"Bob"
|
||||
],
|
||||
[
|
||||
"Type",
|
||||
"Food"
|
||||
]
|
||||
],
|
||||
{
|
||||
"Number": 12.0
|
||||
}
|
||||
],
|
||||
[
|
||||
[
|
||||
[
|
||||
@ -196,6 +173,121 @@
|
||||
{
|
||||
"Number": 5.0
|
||||
}
|
||||
],
|
||||
[
|
||||
[
|
||||
[
|
||||
"Month",
|
||||
"February"
|
||||
],
|
||||
[
|
||||
"Payer",
|
||||
"Bernadette"
|
||||
],
|
||||
[
|
||||
"Recipient",
|
||||
"Bob"
|
||||
],
|
||||
[
|
||||
"Type",
|
||||
"Medical"
|
||||
]
|
||||
],
|
||||
{
|
||||
"Number": 33.0
|
||||
}
|
||||
],
|
||||
[
|
||||
[
|
||||
[
|
||||
"Month",
|
||||
"February"
|
||||
],
|
||||
[
|
||||
"Payer",
|
||||
"Bernadette"
|
||||
],
|
||||
[
|
||||
"Recipient",
|
||||
"Bob"
|
||||
],
|
||||
[
|
||||
"Type",
|
||||
"Gas"
|
||||
]
|
||||
],
|
||||
{
|
||||
"Number": 55.0
|
||||
}
|
||||
],
|
||||
[
|
||||
[
|
||||
[
|
||||
"Month",
|
||||
"February"
|
||||
],
|
||||
[
|
||||
"Payer",
|
||||
"Bernadette"
|
||||
],
|
||||
[
|
||||
"Recipient",
|
||||
"Bob"
|
||||
],
|
||||
[
|
||||
"Type",
|
||||
"Food"
|
||||
]
|
||||
],
|
||||
{
|
||||
"Number": 4.0
|
||||
}
|
||||
],
|
||||
[
|
||||
[
|
||||
[
|
||||
"Month",
|
||||
"February"
|
||||
],
|
||||
[
|
||||
"Payer",
|
||||
"Bernadette"
|
||||
],
|
||||
[
|
||||
"Recipient",
|
||||
"Bob"
|
||||
],
|
||||
[
|
||||
"Type",
|
||||
"Clothing"
|
||||
]
|
||||
],
|
||||
{
|
||||
"Text": "i5"
|
||||
}
|
||||
],
|
||||
[
|
||||
[
|
||||
[
|
||||
"Month",
|
||||
"Janury"
|
||||
],
|
||||
[
|
||||
"Payer",
|
||||
"Bernadette"
|
||||
],
|
||||
[
|
||||
"Recipient",
|
||||
"Bob"
|
||||
],
|
||||
[
|
||||
"Type",
|
||||
"Food"
|
||||
]
|
||||
],
|
||||
{
|
||||
"Number": 12.0
|
||||
}
|
||||
]
|
||||
],
|
||||
"formulas": [],
|
||||
@ -217,11 +309,11 @@
|
||||
"row_offset": 0,
|
||||
"col_offset": 0,
|
||||
"selected": [
|
||||
1,
|
||||
1
|
||||
6,
|
||||
2
|
||||
]
|
||||
}
|
||||
},
|
||||
"active_view": "Default",
|
||||
"next_category_id": 4
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user