Merge pull request #597 from MarekSpodBiedry:issue-567

This commit is contained in:
Brandon Thomas 2026-10-13 00:07:24 -04:00
commit c7f04be6d3
3 changed files with 20 additions and 5 deletions

View File

@ -264,11 +264,10 @@ pub fn rename_sheet(e: Expr, old: &str, new: &str) -> Expr {
}
Expr::Ref(r)
}
// Sheet-qualified defined name `Old!MyName` is stored as one string.
// Sheet-qualified defined name `Old!MyName` is stored as one string, with the bare sheet name as the parser
// stores it (the printer adds the quotes).
Expr::Name(n) => match n.split_at_checked(old.len()) {
Some((head, rest)) if head.eq_ignore_ascii_case(old) && rest.starts_with('!') => {
Expr::Name(format!("{}{rest}", crate::printer::quote_sheet(new)))
}
Some((head, rest)) if head.eq_ignore_ascii_case(old) && rest.starts_with('!') => Expr::Name(format!("{new}{rest}")),
_ => Expr::Name(n),
},
other => other,

View File

@ -188,7 +188,15 @@ fn write_expr(s: &mut String, e: &Expr, r1c1: Option<CellRef>) {
Some(at) => s.push_str(&reference_r1c1(r, at)),
None => s.push_str(&reference_a1(r)),
},
Expr::Name(n) => s.push_str(n),
Expr::Name(n) => match n.rsplit_once('!') {
// A sheet-qualified name is stored with the bare sheet name (`My Sheet!Total`): quote it so it parses back.
Some((sheet, name)) => {
s.push_str(&quote_sheet(sheet));
s.push('!');
s.push_str(name);
}
_ => s.push_str(n),
},
Expr::Struct(st) => s.push_str(&struct_ref(st)),
Expr::Unary(op, x) => match op {
UnOp::Neg => {

View File

@ -6,6 +6,10 @@ fn rt(src: &str) -> String {
}
#[test]
fn quoted_sheet_qualified_name_keeps_quotes() {
assert_eq!(rt("'My Sheet'!Total"), "'My Sheet'!Total");
assert_eq!(rt("'Data'!Total"), "Data!Total");
assert_eq!(rt("'It''s'!Total+1"), "'It''s'!Total+1");
fn intersection_with_deleted_operand_reparses() {
// Deleting the columns of an intersection operand prints `A1:B2 #REF!`; that text must parse back.
assert_eq!(rt("A1:B2 #REF!"), "A1:B2 #REF!");
@ -201,6 +205,10 @@ fn rename_sheet_updates_qualified_names() {
assert_eq!(print(&rename_sheet(e, "data", "Numbers")), "Numbers!MyName+MyName+Other!MyName");
let e = parse("Data!MyName").unwrap();
assert_eq!(print(&rename_sheet(e, "Data", "New Name")), "'New Name'!MyName");
// Stored bare, like a parsed name, so the evaluator finds the sheet and a second rename still matches.
let e = rename_sheet(parse("Data!MyName").unwrap(), "Data", "It's");
assert_eq!(e, Expr::Name("It's!MyName".into()));
assert_eq!(print(&rename_sheet(e, "It's", "Totals")), "Totals!MyName");
}
#[test]