fix: navigation bounds and stale state after model load

- app.rs: scroll_rows (Ctrl+D/U) now clamps to the cross-product row
  count and follows the viewport, matching move_selection's behaviour.
  Previously it could push selected past the last row, causing
  selected_cell_key to return None and silently ignoring edits.
- model.rs: add normalize_view_state() which resets row/col offsets to
  zero on all views.
- main.rs, dispatch.rs, app.rs: call normalize_view_state() after every
  model replacement (initial load, :Load command, wizard import) so
  stale offsets from a previous session can't hide the grid.
- app.rs: clamp formula_cursor to the current formula list length at the
  top of handle_formula_panel_key so a model reload with fewer formulas
  can't leave the cursor pointing past the end.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ed L
2026-03-23 23:32:26 -07:00
parent 0cb491901d
commit 45b848dc67
2 changed files with 21 additions and 4 deletions

View File

@ -73,7 +73,10 @@ fn main() -> Result<()> {
// Load or create model
let mut model = if let Some(ref path) = file_path {
if path.exists() {
persistence::load(path).with_context(|| format!("Failed to load {}", path.display()))?
let mut m = persistence::load(path)
.with_context(|| format!("Failed to load {}", path.display()))?;
m.normalize_view_state();
m
} else {
let name = path.file_stem()
.and_then(|s| s.to_str())