mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-24 10:46:50 -06:00
rows/cols parameters: accept a single row or column
home.insertRows {"rows":"3"} and home.insertColumns {"cols":"B"}
failed with "not a range": only spans such as 3:3 or B:B parsed. The
same went for deleting, hiding, sizing and grouping rows and columns.
A single row number or column letter now means that one line.
This commit is contained in:
@@ -1127,10 +1127,10 @@ fn circle_invalid(s: &mut Session, _: &Json) -> Result<Json> {
|
||||
// ---------------------------------------------------------------- outline
|
||||
|
||||
fn outline_lines(s: &Session, p: &Json) -> Result<(bool, u32, u32)> {
|
||||
if let Some(r) = str_param(p, "rows").and_then(RangeRef::parse) {
|
||||
if let Some(r) = str_param(p, "rows").and_then(parse_lines) {
|
||||
return Ok((true, r.start.row, r.end.row));
|
||||
}
|
||||
if let Some(r) = str_param(p, "cols").and_then(RangeRef::parse) {
|
||||
if let Some(r) = str_param(p, "cols").and_then(parse_lines) {
|
||||
return Ok((false, r.start.col, r.end.col));
|
||||
}
|
||||
let r = s.doc()?.selection.current();
|
||||
@@ -1493,6 +1493,20 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_row_and_column_parameters() {
|
||||
let mut s = Session::new();
|
||||
s.new_workbook();
|
||||
s.execute("range.setValues", json!({"range": "A1", "values": [[1, 2], [3, 4]]})).unwrap();
|
||||
s.execute("home.insertRows", json!({"rows": "2"})).unwrap();
|
||||
s.execute("home.insertColumns", json!({"cols": "B"})).unwrap();
|
||||
let v = |s: &mut Session, a: &str| s.execute("cell.get", json!({"cell": a})).unwrap()["value"].clone();
|
||||
assert_eq!(v(&mut s, "C3"), json!(4.0));
|
||||
s.execute("home.hideRows", json!({"rows": "1"})).unwrap();
|
||||
s.execute("data.group", json!({"cols": "C"})).unwrap();
|
||||
assert!(s.execute("home.deleteRows", json!({"rows": "0"})).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn split() {
|
||||
assert_eq!(split_delimited("a,b,,c", &[','], false, '"'), ["a", "b", "", "c"]);
|
||||
|
||||
@@ -940,7 +940,7 @@ fn line_targets(s: &Session, p: &Json, rows: bool) -> Result<Vec<(u32, u32)>> {
|
||||
return t
|
||||
.split(',')
|
||||
.map(|part| {
|
||||
let r = RangeRef::parse(part).ok_or_else(|| bad(key, format!("not a range: {part}")))?;
|
||||
let r = parse_lines(part).ok_or_else(|| bad(key, format!("not a range: {part}")))?;
|
||||
Ok(if rows { (r.start.row, r.end.row) } else { (r.start.col, r.end.col) })
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -246,6 +246,11 @@ pub(crate) fn target_ranges(s: &Session, p: &Json) -> Result<Vec<RangeRef>> {
|
||||
Ok(s.doc()?.selection.ranges.clone())
|
||||
}
|
||||
|
||||
/// A `rows`/`cols` parameter: `3:5` and `B:C`, or a single `3` or `B`.
|
||||
pub(crate) fn parse_lines(t: &str) -> Option<RangeRef> {
|
||||
RangeRef::parse(t).or_else(|| if t.contains(':') { None } else { RangeRef::parse(&format!("{t}:{t}")) })
|
||||
}
|
||||
|
||||
pub(crate) fn target_range(s: &Session, p: &Json) -> Result<RangeRef> {
|
||||
Ok(target_ranges(s, p)?.first().copied().unwrap_or_default())
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
fn lines(s: &Session, p: &Json, axis: Axis) -> Result<(u32, u32)> {
|
||||
let key = if axis == Axis::Rows { "rows" } else { "cols" };
|
||||
let r = match str_param(p, key).or_else(|| str_param(p, "range")) {
|
||||
Some(t) => RangeRef::parse(t).ok_or_else(|| bad(key, format!("not a range: {t}")))?,
|
||||
Some(t) => parse_lines(t).ok_or_else(|| bad(key, format!("not a range: {t}")))?,
|
||||
None => s.doc()?.selection.current(),
|
||||
};
|
||||
let (a, b) = if axis == Axis::Rows { (r.start.row, r.end.row) } else { (r.start.col, r.end.col) };
|
||||
|
||||
Reference in New Issue
Block a user