Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions src/app/navigation.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use crate::app::AppState;
use crate::excel::{EXCEL_MAX_COLS, EXCEL_MAX_ROWS};
use crate::utils::find_non_empty_cell;
use crate::utils::Direction;

impl AppState<'_> {
pub fn move_cursor(&mut self, delta_row: isize, delta_col: isize) {
// Calculate new position
let new_row = (self.selected_cell.0 as isize + delta_row).max(1) as usize;
let new_col = (self.selected_cell.1 as isize + delta_col).max(1) as usize;
let new_row =
(self.selected_cell.0 as isize + delta_row).clamp(1, EXCEL_MAX_ROWS as isize) as usize;
let new_col =
(self.selected_cell.1 as isize + delta_col).clamp(1, EXCEL_MAX_COLS as isize) as usize;

// Update selected position
self.selected_cell = (new_row, new_col);
Expand Down Expand Up @@ -155,6 +158,7 @@ impl AppState<'_> {
}

pub fn ensure_column_visible(&mut self, column: usize) {
let column = column.min(EXCEL_MAX_COLS);
let frozen_cols = self.workbook.get_current_sheet().freeze_panes.cols;
let min_scroll_col = frozen_cols + 1;

Expand Down Expand Up @@ -187,11 +191,8 @@ impl AppState<'_> {
}

// If the column is already visible but at the right edge, try to add a margin
let sheet = self.workbook.get_current_sheet();
let max_col = sheet.max_cols;

// Only apply margin logic if not at the max column
if column < max_col && column == last_visible_col && scroll_cols_visible > 1 {
if column < EXCEL_MAX_COLS && column == last_visible_col && scroll_cols_visible > 1 {
// Adjust start column to show more columns to the left
// This creates a margin on the right
self.start_col = (column - (scroll_cols_visible - 2)).max(min_scroll_col);
Expand Down
73 changes: 16 additions & 57 deletions src/app/sheet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,10 @@ impl AppState<'_> {

// Restore cell position and view position for the new sheet
if let Some(saved_position) = self.sheet_cell_positions.get(&new_sheet_name) {
// Ensure the saved position is valid for the current sheet
let sheet = self.workbook.get_current_sheet();
let valid_row = saved_position.selected.0.min(sheet.max_rows.max(1));
let valid_col = saved_position.selected.1.min(sheet.max_cols.max(1));

self.selected_cell = (valid_row, valid_col);
self.selected_cell = Self::clamp_cell_to_excel_bounds(saved_position.selected);
self.start_row = saved_position.view.0;
self.start_col = saved_position.view.1;
self.clamp_selected_cell_to_excel_bounds();

// Make sure the view position is valid relative to the selected cell
self.handle_scrolling();
Expand Down Expand Up @@ -230,14 +226,10 @@ impl AppState<'_> {

// Restore saved cell position for the new current sheet or use default
if let Some(saved_position) = self.sheet_cell_positions.get(&new_sheet_name) {
// Ensure the saved position is valid for the current sheet
let sheet = self.workbook.get_current_sheet();
let valid_row = saved_position.selected.0.min(sheet.max_rows.max(1));
let valid_col = saved_position.selected.1.min(sheet.max_cols.max(1));

self.selected_cell = (valid_row, valid_col);
self.selected_cell = Self::clamp_cell_to_excel_bounds(saved_position.selected);
self.start_row = saved_position.view.0;
self.start_col = saved_position.view.1;
self.clamp_selected_cell_to_excel_bounds();

// Make sure the view position is valid relative to the selected cell
self.handle_scrolling();
Expand Down Expand Up @@ -314,11 +306,7 @@ impl AppState<'_> {

self.workbook.recalculate_max_rows();
self.workbook.recalculate_max_cols();
let sheet = self.workbook.get_current_sheet();

if self.selected_cell.0 > sheet.max_rows {
self.selected_cell.0 = sheet.max_rows.max(1);
}
self.clamp_selected_cell_to_excel_bounds();

self.handle_scrolling();
self.search_results.clear();
Expand Down Expand Up @@ -360,11 +348,7 @@ impl AppState<'_> {

self.workbook.recalculate_max_rows();
self.workbook.recalculate_max_cols();
let sheet = self.workbook.get_current_sheet();

if self.selected_cell.0 > sheet.max_rows {
self.selected_cell.0 = sheet.max_rows.max(1);
}
self.clamp_selected_cell_to_excel_bounds();

self.handle_scrolling();
self.search_results.clear();
Expand Down Expand Up @@ -420,11 +404,7 @@ impl AppState<'_> {

self.workbook.recalculate_max_rows();
self.workbook.recalculate_max_cols();
let sheet = self.workbook.get_current_sheet();

if self.selected_cell.0 > sheet.max_rows {
self.selected_cell.0 = sheet.max_rows.max(1);
}
self.clamp_selected_cell_to_excel_bounds();

self.handle_scrolling();
self.search_results.clear();
Expand Down Expand Up @@ -477,21 +457,14 @@ impl AppState<'_> {

self.workbook.recalculate_max_rows();
self.workbook.recalculate_max_cols();
let sheet = self.workbook.get_current_sheet();

if col > sheet.max_cols {
self.selected_cell.1 = sheet.max_cols.max(1);
}

if self.selected_cell.0 > sheet.max_rows {
self.selected_cell.0 = sheet.max_rows.max(1);
}
let max_cols = self.workbook.get_current_sheet().max_cols;
self.clamp_selected_cell_to_excel_bounds();

if self.column_widths.len() > col {
self.column_widths.remove(col);
}

self.adjust_column_widths(sheet.max_cols);
self.adjust_column_widths(max_cols);

self.handle_scrolling();
self.search_results.clear();
Expand Down Expand Up @@ -544,21 +517,14 @@ impl AppState<'_> {

self.workbook.recalculate_max_rows();
self.workbook.recalculate_max_cols();
let sheet = self.workbook.get_current_sheet();

if self.selected_cell.1 > sheet.max_cols {
self.selected_cell.1 = sheet.max_cols.max(1);
}

if self.selected_cell.0 > sheet.max_rows {
self.selected_cell.0 = sheet.max_rows.max(1);
}
let max_cols = self.workbook.get_current_sheet().max_cols;
self.clamp_selected_cell_to_excel_bounds();

if self.column_widths.len() > col {
self.column_widths.remove(col);
}

self.adjust_column_widths(sheet.max_cols);
self.adjust_column_widths(max_cols);

self.handle_scrolling();
self.search_results.clear();
Expand Down Expand Up @@ -630,23 +596,16 @@ impl AppState<'_> {

self.workbook.recalculate_max_rows();
self.workbook.recalculate_max_cols();
let sheet = self.workbook.get_current_sheet();

if self.selected_cell.1 > sheet.max_cols {
self.selected_cell.1 = sheet.max_cols.max(1);
}

if self.selected_cell.0 > sheet.max_rows {
self.selected_cell.0 = sheet.max_rows.max(1);
}
let max_cols = self.workbook.get_current_sheet().max_cols;
self.clamp_selected_cell_to_excel_bounds();

for col in (start_col..=effective_end_col).rev() {
if self.column_widths.len() > col {
self.column_widths.remove(col);
}
}

self.adjust_column_widths(sheet.max_cols);
self.adjust_column_widths(max_cols);

self.handle_scrolling();
self.search_results.clear();
Expand Down
20 changes: 18 additions & 2 deletions src/app/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use tui_textarea::TextArea;

use crate::actions::UndoHistory;
use crate::app::VimState;
use crate::excel::Workbook;
use crate::excel::{Workbook, EXCEL_MAX_COLS, EXCEL_MAX_ROWS};

/// Represents a cell position in a sheet, including both the selected cell and view position
#[derive(Clone, Copy)]
Expand Down Expand Up @@ -170,12 +170,28 @@ impl AppState<'_> {

/// Updates the row number width based on the maximum row number in the current sheet
pub fn update_row_number_width(&mut self) {
let max_rows = self.workbook.get_current_sheet().max_rows;
let max_rows = self
.workbook
.get_current_sheet()
.max_rows
.max(self.selected_cell.0)
.max(self.start_row)
.clamp(1, EXCEL_MAX_ROWS);
let width = max_rows.to_string().len();
// Ensure a minimum width of 4 for row numbers
self.row_number_width = width.max(4);
}

pub fn clamp_cell_to_excel_bounds((row, col): (usize, usize)) -> (usize, usize) {
(row.clamp(1, EXCEL_MAX_ROWS), col.clamp(1, EXCEL_MAX_COLS))
}

pub fn clamp_selected_cell_to_excel_bounds(&mut self) {
self.selected_cell = Self::clamp_cell_to_excel_bounds(self.selected_cell);
self.start_row = self.start_row.clamp(1, EXCEL_MAX_ROWS);
self.start_col = self.start_col.clamp(1, EXCEL_MAX_COLS);
}

pub fn adjust_info_panel_height(&mut self, delta: isize) {
let new_height = (self.info_panel_height as isize + delta).clamp(6, 16) as usize;
if new_height != self.info_panel_height {
Expand Down
45 changes: 8 additions & 37 deletions src/app/undo_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,7 @@ impl AppState<'_> {
self.workbook.recalculate_max_cols();
self.ensure_column_widths();

// Update cursor position if it's outside the valid range
let sheet = self.workbook.get_current_sheet();
if self.selected_cell.0 > sheet.max_rows {
self.selected_cell.0 = sheet.max_rows.max(1);
}
if self.selected_cell.1 > sheet.max_cols {
self.selected_cell.1 = sheet.max_cols.max(1);
}
self.clamp_selected_cell_to_excel_bounds();

if self.undo_history.all_undone() {
self.workbook.set_modified(false);
Expand All @@ -44,14 +37,7 @@ impl AppState<'_> {
self.workbook.recalculate_max_cols();
self.ensure_column_widths();

// Update cursor position if it's outside the valid range
let sheet = self.workbook.get_current_sheet();
if self.selected_cell.0 > sheet.max_rows {
self.selected_cell.0 = sheet.max_rows.max(1);
}
if self.selected_cell.1 > sheet.max_cols {
self.selected_cell.1 = sheet.max_cols.max(1);
}
self.clamp_selected_cell_to_excel_bounds();

self.workbook.set_modified(true);
} else {
Expand Down Expand Up @@ -175,9 +161,7 @@ impl AppState<'_> {
sheet.data.remove(row_action.row);
sheet.max_rows = sheet.max_rows.saturating_sub(1);

if self.selected_cell.0 > sheet.max_rows {
self.selected_cell.0 = sheet.max_rows.max(1);
}
self.clamp_selected_cell_to_excel_bounds();

self.add_notification(format!("Redid row {} deletion", row_action.row));
}
Expand Down Expand Up @@ -256,9 +240,7 @@ impl AppState<'_> {
self.column_widths.push(15);
}

if self.selected_cell.1 > sheet.max_cols {
self.selected_cell.1 = sheet.max_cols.max(1);
}
self.clamp_selected_cell_to_excel_bounds();

self.add_notification(format!("Redid column {} deletion", index_to_col_name(col)));
}
Expand Down Expand Up @@ -309,14 +291,10 @@ impl AppState<'_> {

// Restore saved cell position for the new current sheet or use default
if let Some(saved_position) = self.sheet_cell_positions.get(&new_sheet_name) {
// Ensure the saved position is valid for the current sheet
let sheet = self.workbook.get_current_sheet();
let valid_row = saved_position.selected.0.min(sheet.max_rows.max(1));
let valid_col = saved_position.selected.1.min(sheet.max_cols.max(1));

self.selected_cell = (valid_row, valid_col);
self.selected_cell = Self::clamp_cell_to_excel_bounds(saved_position.selected);
self.start_row = saved_position.view.0;
self.start_col = saved_position.view.1;
self.clamp_selected_cell_to_excel_bounds();

// Make sure the view position is valid relative to the selected cell
self.handle_scrolling();
Expand Down Expand Up @@ -446,11 +424,7 @@ impl AppState<'_> {
} else {
self.workbook.delete_rows(start_row, end_row)?;

let sheet = self.workbook.get_current_sheet();

if self.selected_cell.0 > sheet.max_rows {
self.selected_cell.0 = sheet.max_rows.max(1);
}
self.clamp_selected_cell_to_excel_bounds();

self.add_notification(format!("Redid rows {} to {} deletion", start_row, end_row));
}
Expand Down Expand Up @@ -519,12 +493,9 @@ impl AppState<'_> {
} else {
self.workbook.delete_columns(start_col, end_col)?;

let sheet = self.workbook.get_current_sheet();
Self::remove_column_widths(&mut self.column_widths, start_col, end_col);

if self.selected_cell.1 > sheet.max_cols {
self.selected_cell.1 = sheet.max_cols.max(1);
}
self.clamp_selected_cell_to_excel_bounds();

self.add_notification(format!(
"Redid columns {} to {} deletion",
Expand Down
Loading
Loading