From d983995e8fee3b20dca7b2c028f3cd87541f0319 Mon Sep 17 00:00:00 2001 From: Rushmore75 Date: Fri, 6 Feb 2026 11:31:41 -0700 Subject: [PATCH] solve failing test copy and pasting functions with ranges as arguments now works --- src/app/clipboard.rs | 11 +++++++++++ src/app/logic/calc.rs | 19 +++++++++++++------ src/app/logic/cell.rs | 39 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/src/app/clipboard.rs b/src/app/clipboard.rs index c056f37..777ec40 100644 --- a/src/app/clipboard.rs +++ b/src/app/clipboard.rs @@ -384,4 +384,15 @@ fn copy_paste_range_in_function() { let a = app.grid.get_cell("C0").as_ref().expect("Should've been set by paste"); assert_eq!(a.to_string(), "=sum(B:B)"); + + // now copy the range the other direction + app.grid.mv_cursor_to(2, 0); + app.mode = super::mode::Mode::Chord(Chord::new('y')); + Mode::process_key(&mut app, 'y'); + app.grid.mv_cursor_to(1, 1); + Mode::process_key(&mut app, 'p'); + + let a = app.grid.get_cell("B1").as_ref().expect("Should've been set by paste"); + assert_eq!(a.to_string(), "=sum(A:A)"); + } diff --git a/src/app/logic/calc.rs b/src/app/logic/calc.rs index 9533732..7036d05 100644 --- a/src/app/logic/calc.rs +++ b/src/app/logic/calc.rs @@ -393,12 +393,22 @@ impl Grid { } } + pub fn char_to_idx(i: &str) -> usize { + let x_idx = i + .chars() + .filter(|f| f.is_alphabetic()) + .enumerate() + .map(|(idx, c)| ((c.to_ascii_lowercase() as usize).saturating_sub(97)) + (26 * idx)) + .fold(0, |a, b| a + b); + x_idx + } + /// Parse values in the format of A0, C10 ZZ99, etc, and /// turn them into an X,Y index. pub fn parse_to_idx(i: &str) -> Option<(usize, usize)> { let i = i.replace('$', ""); - let chars = i.chars().take_while(|c| c.is_alphabetic()).collect::>(); + let chars = i.chars().take_while(|c| c.is_alphabetic()).collect::(); let nums = i.chars().skip(chars.len()).take_while(|c| c.is_numeric()).collect::(); // At least half the arguments are gone @@ -407,11 +417,7 @@ impl Grid { } // get the x index from the chars - let x_idx = chars - .iter() - .enumerate() - .map(|(idx, c)| (c.to_ascii_lowercase() as usize - 97) + (26 * idx)) - .fold(0, |a, b| a + b); + let x_idx = Self::char_to_idx(&chars); // get the y index from the numbers if let Ok(y_idx) = nums.parse::() { @@ -591,6 +597,7 @@ fn alphanumeric_indexing() { assert_eq!(Grid::parse_to_idx("A"), None); assert_eq!(Grid::parse_to_idx(":"), None); assert_eq!(Grid::parse_to_idx("="), None); + assert_eq!(Grid::parse_to_idx("A:A"), None); assert_eq!(Grid::num_to_char(0).trim(), "A"); assert_eq!(Grid::num_to_char(25).trim(), "Z"); diff --git a/src/app/logic/cell.rs b/src/app/logic/cell.rs index 2e1659e..03855f0 100644 --- a/src/app/logic/cell.rs +++ b/src/app/logic/cell.rs @@ -73,7 +73,10 @@ impl CellType { let mut lock_y = false; if old_var.contains('$') { - let locations = old_var.char_indices().filter(|(_, c)| *c == '$').map(|(i, _)| i).collect::>(); + let locations = old_var + .char_indices() + .filter(|(_, c)| *c == '$').map(|(i, _)| i) + .collect::>(); match locations.len() { 1 => { if locations[0] == 0 { @@ -136,6 +139,40 @@ impl CellType { // rolling = rolling.replace(&old_var, &new_var); } else { // why you coping invalid stuff, nerd? + // + // could be copying a range + if old_var.contains(':') { + let parts = old_var.split(':').collect::>(); + // This means the var was formatted as X:X + if parts.len() == 2 { + // how far is the movement? + let dx = to.0 as i32 - from.0 as i32; + + let range_start = parts[0]; + let range_end = parts[1]; + + // get the letters as numbers + let xs = Grid::char_to_idx(range_start) as i32; + let xe = Grid::char_to_idx(range_end) as i32; + + // apply movement + let mut new_range_start = xs+dx; + let mut new_range_end = xe+dx; + + // bottom out at 0 + if new_range_start < 0 { + new_range_start = 0; + } + if new_range_end < 0 { + new_range_end = 0; + } + + // convert the index back into a letter and then submit it + let start = Grid::num_to_char(new_range_start as usize); + let end = Grid::num_to_char(new_range_end as usize); + equation = replace_fn(&equation, &old_var, &format!("{}:{}", start.trim(), end.trim())); + } + } } } return equation.into();