diff --git a/.gitignore b/.gitignore index 374729b..47aa619 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /target /.vscode -/*.csv \ No newline at end of file +/*.csv +/*.nscim \ No newline at end of file diff --git a/src/app/clipboard.rs b/src/app/clipboard.rs index 95838ad..c32c37e 100644 --- a/src/app/clipboard.rs +++ b/src/app/clipboard.rs @@ -1,6 +1,4 @@ -use evalexpr::eval_with_context; - -use crate::app::logic::{calc::Grid, cell::CellType, ctx::ExtractionContext}; +use crate::app::logic::{calc::Grid, cell::CellType}; #[cfg(test)] use crate::app::{ diff --git a/src/app/logic/calc.rs b/src/app/logic/calc.rs index ba47d85..c5c88a5 100644 --- a/src/app/logic/calc.rs +++ b/src/app/logic/calc.rs @@ -1,6 +1,5 @@ use std::{ cmp::{max, min}, - fmt::Display, fs, io::{Read, Write}, path::PathBuf, @@ -8,10 +7,10 @@ use std::{ use evalexpr::*; -use crate::app::logic::{ +use crate::app::{logic::{ cell::{CSV_DELIMITER, CellType}, ctx, -}; +}, mode::Mode}; #[cfg(test)] use crate::app::app::App; @@ -114,7 +113,7 @@ impl Grid { { val.to_string() } else { - cell.to_string_csv_escaped() + cell.escaped_csv_string() } } else { CSV_DELIMITER.to_string() @@ -235,6 +234,42 @@ impl Grid { self.mv_cursor_to(x, y); } + pub fn insert_row_above(&mut self, (x, y): (usize, usize)) {todo!()} + pub fn insert_row_below(&mut self, (x, y): (usize, usize)) {todo!()} + pub fn insert_column_before(&mut self, (insertion_x, _y): (usize, usize)) { + let mut v = Vec::with_capacity(LEN); + for _ in 0..LEN { + v.push(None); + } + self.cells.insert(insertion_x, v); + // keep the grid LEN + self.cells.pop(); + for x in 0..LEN { + for y in 0..LEN { + if let Some(cell) = self + .get_cell_raw(x, y) + .as_ref() + .map(|f| f + .custom_translate_cell((0,0), (1,0), |rolling, old, new| { + if let Some((arg_x, _)) = Grid::parse_to_idx(old) { + // add 1 because of the insertion + if arg_x < insertion_x { + rolling.to_owned() + } else { + rolling.replace(old, new) + } + } else { + unimplemented!("Invalid variable wanted to be translated") + } + })) { + self.set_cell_raw((x,y), Some(cell)); + } + } + } + } + pub fn insert_column_after(&mut self, (x, y): (usize, usize)) { + self.insert_column_before((x+1,y)); + } /// Iterate over the entire grid and see where /// the farthest modified cell is. #[must_use] @@ -759,3 +794,60 @@ fn cursor_fns() { app.grid.mv_cursor_to(1, 0); assert_eq!(app.grid.cursor(), (1, 0)); } + +#[test] +fn insert_col_before_1() { + let mut grid = Grid::new(); + + grid.set_cell("A0", 2.); + grid.set_cell("B0", "=A0*2".to_string()); + grid.set_cell("B1", "=B0".to_string()); + + grid.mv_cursor_to(1, 0); + + grid.insert_column_before(grid.cursor()); + + // cell didn't get translated + let cell = grid.get_cell("A0").as_ref().expect("Just set it"); + assert_eq!(cell.to_string(), "2"); + + // cell referencing another cell on the same side of the insertion + let cell = grid.get_cell("C1").as_ref().expect("Just set it"); + assert_eq!(cell.to_string(), "=C0"); +} + +#[test] +fn insert_col_before_2() { + let mut grid = Grid::new(); + + grid.set_cell("A0", 2.); + grid.set_cell("B0", "=A0*2".to_string()); + grid.set_cell("B1", "=B0".to_string()); + + grid.mv_cursor_to(0, 0); + + grid.insert_column_before(grid.cursor()); + + let cell = grid.get_cell("B0").as_ref().expect("Just set it"); + assert_eq!(cell.to_string(), "2"); + + // cell referencing another cell on the same side of the insertion + let cell = grid.get_cell("C1").as_ref().expect("Just set it"); + assert_eq!(cell.to_string(), "=C0"); +} + +#[test] +fn insert_col_before_3() { + let mut grid = Grid::new(); + + grid.set_cell("A0", 2.); + grid.set_cell("A1", 2.); + grid.set_cell("B0", "=A0*A1".to_string()); + + grid.mv_cursor_to(0, 0); + + grid.insert_column_before(grid.cursor()); + + let cell = grid.get_cell("C0").as_ref().expect("Just set it"); + assert_eq!(cell.to_string(), "=B0*B1"); +} diff --git a/src/app/logic/cell.rs b/src/app/logic/cell.rs index 99ef761..aab317c 100644 --- a/src/app/logic/cell.rs +++ b/src/app/logic/cell.rs @@ -27,7 +27,7 @@ pub const CSV_DELIMITER: char = ','; const CSV_ESCAPE: char = '"'; impl CellType { - pub fn to_string_csv_escaped(&self) -> String { + pub fn escaped_csv_string(&self) -> String { let mut display = self.to_string(); // escape quotes " -> "" @@ -53,7 +53,8 @@ impl CellType { if value.starts_with('=') { Self::Equation(value) } else { Self::String(value) } } } - pub fn translate_cell(&self, from: (usize, usize), to: (usize, usize)) -> CellType { + + pub fn custom_translate_cell(&self, from: (usize, usize), to: (usize, usize), replace_fn: impl Fn(&str, &str, &str) -> String) -> CellType { match self { // don't translate non-equations CellType::Number(_) | CellType::String(_) => return self.clone(), @@ -81,7 +82,8 @@ impl CellType { let new_var = format!("{alpha}{dest_y}"); // swap out vars - rolling = rolling.replace(&old_var, &new_var); + rolling = replace_fn(&rolling, &old_var, &new_var); + // rolling = rolling.replace(&old_var, &new_var); } else { // why you coping invalid stuff, nerd? } @@ -90,6 +92,10 @@ impl CellType { } } } + + pub fn translate_cell(&self, from: (usize, usize), to: (usize, usize)) -> CellType { + self.custom_translate_cell(from, to, |a,b,c| a.replace(b, c)) + } } impl Display for CellType { diff --git a/src/app/logic/ctx.rs b/src/app/logic/ctx.rs index fd92352..0171ec0 100644 --- a/src/app/logic/ctx.rs +++ b/src/app/logic/ctx.rs @@ -280,8 +280,9 @@ impl Context for ExtractionContext { fn get_value(&self, identifier: &str) -> Option> { if let Ok(mut registry) = self.var_registry.write() { registry.push(identifier.to_owned()); - } - None + } else { panic!("The RwLock should always be write-able") } + + Some(Value::Int(1)) } fn call_function( @@ -292,8 +293,9 @@ impl Context for ExtractionContext { let _ = argument; if let Ok(mut registry) = self.fn_registry.write() { registry.push(identifier.to_owned()) - } - Ok(Value::Empty) + } else { panic!("The RwLock should always be write-able") } + // Ok(Value::Int(1)) + todo!(); } fn are_builtin_functions_disabled(&self) -> bool { diff --git a/src/app/mode.rs b/src/app/mode.rs index 2c55526..c79f30a 100644 --- a/src/app/mode.rs +++ b/src/app/mode.rs @@ -160,8 +160,14 @@ impl Mode { 'r' => { app.mode = Mode::Insert(Chord::from(String::new())); } - 'I' => { /* insert col before */ } - 'A' => { /* insert col after */ } + // insert column before + 'I' => { + app.grid.insert_column_before(app.grid.cursor()); + } + // insert column after + 'A' => { + app.grid.insert_column_after(app.grid.cursor()); + } 'o' => { /* insert row below */ } 'O' => { /* insert row above */ } 'v' => app.mode = Mode::Visual(app.grid.cursor()),