ranges now move correctly with column inserts
All checks were successful
Test Rust project / test (ubuntu-latest, stable) (push) Successful in 1m1s
All checks were successful
Test Rust project / test (ubuntu-latest, stable) (push) Successful in 1m1s
This commit is contained in:
@@ -77,6 +77,7 @@ mod internal {
|
|||||||
}
|
}
|
||||||
&self.cells[x][y]
|
&self.cells[x][y]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_cell_raw<T: Into<CellType>>(&mut self, (x, y): (usize, usize), val: Option<T>) {
|
pub fn set_cell_raw<T: Into<CellType>>(&mut self, (x, y): (usize, usize), val: Option<T>) {
|
||||||
// TODO check oob
|
// TODO check oob
|
||||||
self.cells[x][y] = val.map(|v| v.into());
|
self.cells[x][y] = val.map(|v| v.into());
|
||||||
@@ -242,6 +243,7 @@ impl Grid {
|
|||||||
pub fn undo(&mut self) {
|
pub fn undo(&mut self) {
|
||||||
self.current_grid = self.current_grid.saturating_sub(1);
|
self.current_grid = self.current_grid.saturating_sub(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn redo(&mut self) {
|
pub fn redo(&mut self) {
|
||||||
self.current_grid = min(self.grid_history.len() - 1, self.current_grid + 1);
|
self.current_grid = min(self.grid_history.len() - 1, self.current_grid + 1);
|
||||||
}
|
}
|
||||||
@@ -391,12 +393,10 @@ impl Grid {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn insert_row_below(&mut self, (x, y): (usize, usize)) {
|
pub fn insert_row_below(&mut self, (x, y): (usize, usize)) {
|
||||||
self.insert_row_above((x, y + 1));
|
self.insert_row_above((x, y + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn insert_column_before(&mut self, (insertion_x, _y): (usize, usize)) {
|
pub fn insert_column_before(&mut self, (insertion_x, _y): (usize, usize)) {
|
||||||
self.transact_on_grid(|grid| {
|
self.transact_on_grid(|grid| {
|
||||||
grid.insert_column(insertion_x);
|
grid.insert_column(insertion_x);
|
||||||
@@ -407,6 +407,20 @@ impl Grid {
|
|||||||
if let Some((arg_x, _)) = Grid::parse_to_idx(old) {
|
if let Some((arg_x, _)) = Grid::parse_to_idx(old) {
|
||||||
// add 1 because of the insertion
|
// add 1 because of the insertion
|
||||||
if arg_x < insertion_x { rolling.to_owned() } else { rolling.replace(old, new) }
|
if arg_x < insertion_x { rolling.to_owned() } else { rolling.replace(old, new) }
|
||||||
|
} else if let Some((start, end)) = Grid::range_as_indices(old) {
|
||||||
|
let mut range_start = Grid::num_to_char(start);
|
||||||
|
let mut range_end = Grid::num_to_char(end);
|
||||||
|
|
||||||
|
if start >= insertion_x {
|
||||||
|
range_start = Grid::num_to_char(start+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if end >= insertion_x {
|
||||||
|
range_end = Grid::num_to_char(end+1);
|
||||||
|
}
|
||||||
|
let new = format!("{range_start}:{range_end}");
|
||||||
|
|
||||||
|
rolling.replace(old, &new)
|
||||||
} else {
|
} else {
|
||||||
unimplemented!("Invalid variable wanted to be translated")
|
unimplemented!("Invalid variable wanted to be translated")
|
||||||
}
|
}
|
||||||
@@ -419,7 +433,6 @@ impl Grid {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn insert_column_after(&mut self, (x, y): (usize, usize)) {
|
pub fn insert_column_after(&mut self, (x, y): (usize, usize)) {
|
||||||
self.insert_column_before((x + 1, y));
|
self.insert_column_before((x + 1, y));
|
||||||
}
|
}
|
||||||
@@ -479,7 +492,7 @@ impl Grid {
|
|||||||
let start_idx = Grid::char_to_idx(start_col);
|
let start_idx = Grid::char_to_idx(start_col);
|
||||||
let end_idx = Grid::char_to_idx(end_col);
|
let end_idx = Grid::char_to_idx(end_col);
|
||||||
|
|
||||||
return Some((start_idx, end_idx))
|
return Some((start_idx, end_idx));
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -562,7 +575,7 @@ impl Grid {
|
|||||||
}
|
}
|
||||||
word[1] = ((idx % 26) + 65) as u8 as char;
|
word[1] = ((idx % 26) + 65) as u8 as char;
|
||||||
|
|
||||||
word.iter().collect()
|
word.iter().filter(|a| !a.is_ascii_whitespace()).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,8 +701,8 @@ fn alphanumeric_indexing() {
|
|||||||
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::parse_to_idx("A:A"), None);
|
||||||
|
|
||||||
assert_eq!(Grid::num_to_char(0).trim(), "A");
|
assert_eq!(Grid::num_to_char(0), "A");
|
||||||
assert_eq!(Grid::num_to_char(25).trim(), "Z");
|
assert_eq!(Grid::num_to_char(25), "Z");
|
||||||
assert_eq!(Grid::num_to_char(26), "AA");
|
assert_eq!(Grid::num_to_char(26), "AA");
|
||||||
assert_eq!(Grid::num_to_char(51), "AZ");
|
assert_eq!(Grid::num_to_char(51), "AZ");
|
||||||
assert_eq!(Grid::num_to_char(701), "ZZ");
|
assert_eq!(Grid::num_to_char(701), "ZZ");
|
||||||
@@ -1103,7 +1116,7 @@ fn insert_col_before_static_range() {
|
|||||||
grid.set_cell("A1", 2.);
|
grid.set_cell("A1", 2.);
|
||||||
grid.set_cell("B0", "=sum(A:A)".to_string());
|
grid.set_cell("B0", "=sum(A:A)".to_string());
|
||||||
|
|
||||||
grid.mv_cursor_to(0, 1);
|
grid.mv_cursor_to(1, 0);
|
||||||
grid.insert_column_before(grid.cursor());
|
grid.insert_column_before(grid.cursor());
|
||||||
|
|
||||||
let cell = grid.get_cell("C0").as_ref().expect("Just set it");
|
let cell = grid.get_cell("C0").as_ref().expect("Just set it");
|
||||||
|
|||||||
@@ -37,11 +37,7 @@ impl CellType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// escape string of it has a comma
|
// escape string of it has a comma
|
||||||
if display.contains(CSV_DELIMITER) {
|
if display.contains(CSV_DELIMITER) { format!("\"{display}\"") } else { display }
|
||||||
format!("\"{display}\"")
|
|
||||||
} else {
|
|
||||||
display
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn duck_type<'a>(value: impl Into<String>) -> Self {
|
fn duck_type<'a>(value: impl Into<String>) -> Self {
|
||||||
@@ -56,7 +52,12 @@ impl CellType {
|
|||||||
|
|
||||||
/// `replace_fn` takes the string, the old value, and then the new value.
|
/// `replace_fn` takes the string, the old value, and then the new value.
|
||||||
/// It can be thought of as `echo $1 | sed s/$2/$3/g`
|
/// It can be thought of as `echo $1 | sed s/$2/$3/g`
|
||||||
pub fn custom_translate_cell(&self, from: (usize, usize), to: (usize, usize), replace_fn: impl Fn(&str, &str, &str) -> String) -> CellType {
|
pub fn custom_translate_cell(
|
||||||
|
&self,
|
||||||
|
from: (usize, usize),
|
||||||
|
to: (usize, usize),
|
||||||
|
replace_fn: impl Fn(&str, &str, &str) -> String,
|
||||||
|
) -> CellType {
|
||||||
match self {
|
match self {
|
||||||
// don't translate non-equations
|
// don't translate non-equations
|
||||||
CellType::Number(_) | CellType::String(_) => return self.clone(),
|
CellType::Number(_) | CellType::String(_) => return self.clone(),
|
||||||
@@ -73,10 +74,8 @@ impl CellType {
|
|||||||
let mut lock_y = false;
|
let mut lock_y = false;
|
||||||
|
|
||||||
if old_var.contains('$') {
|
if old_var.contains('$') {
|
||||||
let locations = old_var
|
let locations =
|
||||||
.char_indices()
|
old_var.char_indices().filter(|(_, c)| *c == '$').map(|(i, _)| i).collect::<Vec<usize>>();
|
||||||
.filter(|(_, c)| *c == '$').map(|(i, _)| i)
|
|
||||||
.collect::<Vec<usize>>();
|
|
||||||
match locations.len() {
|
match locations.len() {
|
||||||
1 => {
|
1 => {
|
||||||
if locations[0] == 0 {
|
if locations[0] == 0 {
|
||||||
@@ -89,7 +88,7 @@ impl CellType {
|
|||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
// Ignore this variable all together, effectively lockng X & Y
|
// Ignore this variable all together, effectively lockng X & Y
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// There are 0 or >2 "$" in this string.
|
// There are 0 or >2 "$" in this string.
|
||||||
@@ -100,7 +99,7 @@ impl CellType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((src_x, src_y)) = Grid::parse_to_idx(&old_var) {
|
if let Some((src_x, src_y)) = Grid::parse_to_idx(&old_var) {
|
||||||
// Use i32s instead of usize in case of negative numbers
|
// Use i32s instead of usize in case of negative numbers
|
||||||
let (x1, y1) = from;
|
let (x1, y1) = from;
|
||||||
@@ -110,20 +109,11 @@ impl CellType {
|
|||||||
let x2 = x2 as i32;
|
let x2 = x2 as i32;
|
||||||
let y2 = y2 as i32;
|
let y2 = y2 as i32;
|
||||||
|
|
||||||
let dest_x = if lock_x {
|
let dest_x = if lock_x { src_x as usize } else { (src_x as i32 + (x2 - x1)) as usize };
|
||||||
src_x as usize
|
|
||||||
} else {
|
|
||||||
(src_x as i32 + (x2 - x1)) as usize
|
|
||||||
};
|
|
||||||
|
|
||||||
let dest_y = if lock_y {
|
let dest_y = if lock_y { src_y as usize } else { (src_y as i32 + (y2 - y1)) as usize };
|
||||||
src_y as usize
|
|
||||||
} else {
|
|
||||||
(src_y as i32 + (y2 - y1)) as usize
|
|
||||||
};
|
|
||||||
|
|
||||||
let alpha = Grid::num_to_char(dest_x);
|
let alpha = Grid::num_to_char(dest_x);
|
||||||
let alpha = alpha.trim();
|
|
||||||
|
|
||||||
// Persist the "$" locking
|
// Persist the "$" locking
|
||||||
let new_var = if lock_x {
|
let new_var = if lock_x {
|
||||||
@@ -141,37 +131,29 @@ impl CellType {
|
|||||||
// why you coping invalid stuff, nerd?
|
// why you coping invalid stuff, nerd?
|
||||||
//
|
//
|
||||||
// could be copying a range
|
// could be copying a range
|
||||||
if old_var.contains(':') {
|
if let Some(parts) = Grid::range_as_indices(&old_var) {
|
||||||
let parts = old_var.split(':').collect::<Vec<&str>>();
|
// how far is the movement?
|
||||||
// This means the var was formatted as X:X
|
let dx = to.0 as i32 - from.0 as i32;
|
||||||
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 xs = parts.0 as i32;
|
||||||
let range_end = parts[1];
|
let xe = parts.1 as i32;
|
||||||
|
|
||||||
// get the letters as numbers
|
// apply movement
|
||||||
let xs = Grid::char_to_idx(range_start) as i32;
|
let mut new_range_start = xs + dx;
|
||||||
let xe = Grid::char_to_idx(range_end) as i32;
|
let mut new_range_end = xe + dx;
|
||||||
|
|
||||||
// apply movement
|
|
||||||
let mut new_range_start = xs+dx;
|
|
||||||
let mut new_range_end = xe+dx;
|
|
||||||
|
|
||||||
// bottom out at 0
|
// bottom out at 0
|
||||||
if new_range_start < 0 {
|
if new_range_start < 0 {
|
||||||
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()));
|
|
||||||
}
|
}
|
||||||
|
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}:{end}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,7 +163,7 @@ impl CellType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn translate_cell(&self, from: (usize, usize), to: (usize, usize)) -> 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))
|
self.custom_translate_cell(from, to, |a, b, c| a.replace(b, c))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,4 +188,3 @@ impl PartialEq for CellType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user