From fb7b23dbade9c10738ab731be25ba924fe90996e Mon Sep 17 00:00:00 2001 From: Mouhand-Kaddo Date: Mon, 19 Oct 2026 14:05:16 +0400 Subject: [PATCH] M12.AR8: count characters, not bytes, in name length limits --- crates/engine/src/cmd/formulas.rs | 16 +++++++++++++++- docs/localization-parity.md | 6 +++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/crates/engine/src/cmd/formulas.rs b/crates/engine/src/cmd/formulas.rs index 40df72df0..454c545d0 100644 --- a/crates/engine/src/cmd/formulas.rs +++ b/crates/engine/src/cmd/formulas.rs @@ -229,7 +229,7 @@ fn valid_name(n: &str) -> bool { if !(first.is_alphabetic() || first == '_' || first == '\\') { return false; } - if n.len() > 255 || CellRef::parse(n).is_some() || is_r1c1(n) { + if n.chars().count() > 255 || CellRef::parse(n).is_some() || is_r1c1(n) { return false; } n.chars().all(|c| c.is_alphanumeric() || matches!(c, '_' | '.' | '\\' | '?')) @@ -610,4 +610,18 @@ mod tests { let r = s.execute("formulas.defineName", json!({"name": "First", "refersTo": "=Sheet1!$A$1"})).unwrap(); assert_eq!(r["refersTo"], "=Sheet1!$A$1"); } + + #[test] + fn arabic_defined_names_count_characters_not_bytes() { + let mut s = Session::new(); + s.new_workbook(); + let arabic = |n: usize| "س".repeat(n); + for ok in [200, 255] { + s.execute("formulas.defineName", json!({"name": arabic(ok), "refersTo": "=1"})).unwrap(); + } + assert!(s.execute("formulas.defineName", json!({"name": arabic(256), "refersTo": "=1"})).is_err()); + s.execute("range.setValues", json!({"range": "A1", "values": [[format!("ع{}", arabic(199))], [1]]})).unwrap(); + let r = s.execute("formulas.createFromSelection", json!({"range": "A1:A2", "top": true})).unwrap(); + assert_eq!(r["created"], 1); + } } diff --git a/docs/localization-parity.md b/docs/localization-parity.md index 09197ff6c..6885a595a 100644 --- a/docs/localization-parity.md +++ b/docs/localization-parity.md @@ -1,6 +1,6 @@ # Localization parity -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-12 · **Change:** minor (Format Cells dialog looks its labels up in the catalog) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4 +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-19 · **Change:** minor (defined-name length limit counts characters, so long Arabic names are accepted) · **Target:** Microsoft Excel (Microsoft 365), Excel for Mac 16.113.4 Per-language status against Excel, which ships its UI in dozens of languages (Windows language packs cover 100+), with localized function names, argument separators, number and date formats, @@ -33,6 +33,9 @@ right-to-left sheets and full complex-script support. Part of arrow keys, editor, popups and floating objects follow; text stays left-to-right inside its box (no bidi), and the sheet tabs, horizontal scrollbar and printing/PDF are not mirrored yet. IME input goes through egui/winit and is unverified for Chinese, Japanese and Korean. +- **Names in any script.** Defined names (Define Name, Create from Selection) are limited to + 255 characters, counted as characters rather than UTF-8 bytes, so a 255-letter Arabic name is + accepted as in Excel. Sheet names already counted characters (31). - **PDF export** uses only the 14 standard PDF fonts: non-Latin text cannot export. ## Languages @@ -78,6 +81,7 @@ language (none so far) and of localized function names. | Date | Change | Summary | |---|---|---| +| 2026-10-19 | minor | Defined-name length counts characters, not bytes: Arabic names up to 255 letters are accepted, and Create from Selection keeps long Arabic headers | | 2026-10-12 | minor | Format Cells looks up its tabs, labels, options and note through `Language::tr` (Fill tab keyed `Format Cells\|Fill`); dialog titles and OK/Cancel too. Labels already in a table (Number, Currency, Fill…) show translated; the rest fall back to English until the tables add them | | 2026-10-12 | minor | Brazilian Portuguese catalog (`i18n/pt.rs`) grows from 377 to 923 entries: every key the other catalogs translate, including the dialog strings #669 starts looking up (~42%) | | 2026-10-11 | minor | German ribbon catalog (`i18n/de.rs`, 266 labels, ~12%); `de` locale tags (de-DE, de-AT, de-CH…) resolve to German. PR #163 (localized German formulas/numbers) still open |