Checked against Excel-cached TEXT() results in number- and text-format test workbooks: 226 of 352 TEXT cells mismatched before, 0 after.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The badge painter only covered five sites, so pressing Alt+H showed
nothing past the tab letter. Now every control with a catalog command id
paints its badge automatically:
- control_badge(prefix, id): the rest of a control's unique sequence
(HFC -> "FC" on Font Color), or the common group letter when many
variants land on one control (HBA..HBW -> "B" on Borders).
- anchor_badge(prefix, targets): menu anchors resolve to the dominant
group-level candidate (Pictures shows "P", not SmartArt's "M").
- ribbon.rs: 90+ control sites now paint through control_keytip/
anchor_keytip (mechanical sweep + hand-wired anchors); split buttons
paint at their arrow rect.
- Offscreen snapshot verified: at prefix H the Home ribbon paints
V/X/C/FP/1/2/3U/FC/H/FG/FK/AL/AC/AR/5/6/WW/MC/K/0/9/L/T/J/I/D/O.
- Tests: 29 lib + 14 keytips, all 8 CI gates green.
Population of keytips.json from the collected Excel Alt-sequence set:
- 408 curated entries: 10 tabs, 354 command binds (64 reserved pending,
290 live catalog commands), 2 dialog openers, 42 group levels.
- Bind-all policy: sequences whose command does not exist yet bind to the
canonical future id as Action::Pending -- badge shows, invocation is a
silent no-op until the command lands (ids from docs/parity-checklist).
- Group levels: 46 command entries that are strict prefixes of deeper
sequences were demoted to menu openers so the trie never fires early
(HV must not paste; it waits for the variant letter).
- Fire-immediately restores: HC Copy, HAN Accounting, FA Save As, FO Open,
FI Info. Unreachable legacy aliases (HCC, HANM, FA1, FAY3, FOC, FOO, FIP)
dropped: the parent fires first.
- ES stays a terminal dialog opener as in Excel: the A/F/T/V variants are
dialog mnemonics, not trie sequences.
- Escape pops one trie level and returns to the armed root at a single
letter; keytips.json is the single modifiable source; xtask keytips now
emits through rustfmt so --check is byte-stable.
- Tests: 99 pass (27 lib + 14 keytips + suite), all 8 CI gates green.
Move the hardcoded keytip sequence list into keytip_table.rs as the single
source of truth for both the matcher and the ribbon badge painter.
- Generalize Action::Home into Action::Tab(&'static str); the legacy
Edit/Format prefix special-case in lib.rs is absorbed into the table.
- Badge helpers: tab_sequence (tabs), group_extension (menu anchors),
item_letter (menu items), control_badges (command controls).
- Add tab letters for Insert (N), Page Layout (P), Formulas (M), Data (A),
Review (R), View (W); Draw/Automate stay unbadged until contextual
letters land.
- Tests: 5 table unit tests + tab_letters_switch_to_their_ribbon_tabs
integration test. All 7 xtask ci gates green.
Inside DATEDIF( the hint showed only the signature, so the values unit
takes weren't visible while typing it (#363). The hint now adds the
function's description under the signature, wrapped to the hint's
width, the same text the autocomplete list shows (translated where a
Spanish entry exists).
Claude-Session: https://claude.ai/code/session_01BGBBGBC2gRpQ7GDuwQ6WPt
FnSpec::accepts holds the arity check (including Excel's 255-argument
limit) that functions::call and the entry check both use, so entry also
refuses 256 arguments to a variadic function. The evaluator's own check
in calc is unchanged.
Claude-Session: https://claude.ai/code/session_01BGBBGBC2gRpQ7GDuwQ6WPt
The sequence table is no longer hand-maintained Rust: keytips.json is the
single human-edited source (one line per sequence, grouped by tab, pending
reserves sequences for future commands), and `cargo xtask keytips`
regenerates keytip_table/generated.rs deterministically. `cargo xtask ci`
now fails if the generated table is stale.
- Action::Pending: reserved sequences show their badge and invoke silently
until the command exists (bind-all policy).
- Intermediate group levels are implicit: the matcher waits whenever a
pressed letter starts a deeper sequence; only terminal entries are
listed (two-letter units like Draw's "JI" work with no extra rows).
- First populated sequence beyond the legacy set: W,V,G toggles gridlines,
proven end-to-end by view_gridlines_sequence_runs_end_to_end.
Excel shows some access keys as one multi-letter unit (Draw's "JI") that
fires only once complete. The matcher now follows the trie shape:
- A pressed letter that matches a complete sequence fires immediately.
- If it only starts deeper sequences, the matcher waits for more input
(implicit group level, no table entry required).
- A tab with deeper sequences stays as an active level so group badges
show; a terminal unit clears the prefix.
- tab_sequence() returns multi-letter tab units as one badge.
Draw: Alt+JI switches to the Draw tab; deeper Draw letters are left
blank for future contributors (GridCraft's Draw differs from Excel's).
Move the hardcoded keytip sequence list into keytip_table.rs as the single
source of truth for both the matcher and the ribbon badge painter.
- Generalize Action::Home into Action::Tab(&'static str); the legacy
Edit/Format prefix special-case in lib.rs is absorbed into the table.
- Badge helpers: tab_sequence (tabs), group_extension (menu anchors),
item_letter (menu items), control_badges (command controls).
- Add tab letters for Insert (N), Page Layout (P), Formulas (M), Data (A),
Review (R), View (W); Draw/Automate stay unbadged until contextual
letters land.
- Tests: 5 table unit tests + tab_letters_switch_to_their_ribbon_tabs
integration test. All 7 xtask ci gates green.
A complete 379-entry catalog covering every JAPANESE key (the coverage
reference), registered as a Fr variant in the Language enum. The
uniqueness/coverage test now asserts French alongside the other
languages; locale tags fr-FR and fr_CA resolve.
A save without a recent user gesture (e.g. over the control channel) is refused with SecurityError and would otherwise fail silently.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
XLSX headerFooter kept only oddHeader/oddFooter: a workbook whose header is on a
different first page (differentFirst + firstHeader) or on even pages showed no
header, and saving dropped it. The model now keeps the first/even headers and
footers and the differentFirst / differentOddEven / scaleWithDoc / alignWithMargins
flags; XLSX reads and writes them; the PDF and the Page Layout view use the right
pair per page; in-place editing edits the page's own pair, and the Header & Footer
tab has Different First Page and Different Odd & Even Pages. pageLayout.headerFooter
takes the variants and a page: odd|even|first for one-section edits.
Insert › Header & Footer now switches to Page Layout view and edits the first
page's centre header, as in Excel, instead of opening the codes dialog.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>