Review follow-up. item_letter_with compared the compact params string, so a key
order or spacing difference between keytips.json and the caller would miss the
item. It now takes a serde_json::Value and compares parsed values. Tests add
prefixes that must not open the Borders menu (a finished sequence, another
group's level, another control) and an unknown preset.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review follow-up. Inside Borders is GridCraft's own Borders menu item (Excel's
menu has none), so it had no letter and was the one preset the keyboard
couldn't reach from the open menu. It takes J, unused under HB.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
At the "HB" level every Borders sequence (HBA..HBW) shares the prefix, so
control_badge drew no badge and nothing opened: after B the screen showed no
key tips at all, although the next letter still applied its preset. The
Borders menu now opens at its group level, as Excel's does, with each preset's
letter (told apart by its params) and More Borders' M. A letter or Esc changes
the prefix, which closes the menu as before; clicking the arrow still toggles it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Function Library group was a big Insert Function button followed by
AutoSum and seven big category buttons that all drew the same icon, the
widest group on the Formulas tab. It is now laid out as Excel lays it
out when the window is not wide enough for a big button per category:
big Insert Function and AutoSum buttons, then the categories as
labelled small buttons in columns of three:
Recently Used Text Math & Trig
Financial Date & Time More Functions
Logical Lookup & Reference
- The category buttons draw a new code-drawn icon, Icon::FnBook, a book
whose spine and glyph (star, coins, question mark, letter, clock,
magnifier, theta, dots) take the category's colour from the theme's
category palette. icons::paint_accent draws an icon with an accent
colour, and widgets::small_button_accent is a small button that uses
it; small_button is unchanged for its callers.
- AutoSum stays the big split button: the icon inserts SUM, the label
and arrow open the AutoSum menu, which now reads Sum, Average, Count
Numbers, Max, Min and More Functions… and is shared with Home ›
Editing. Its tooltip names the control only, so the shortcut comes
from the platform lookup (Alt+= on Windows and Linux).
- Each category menu lists its functions with their descriptions on
hover and ends with Insert Function…, which opens the dialog with
that category. More Functions cascades into Statistical, Engineering,
Cube, Information, Compatibility and Web. Recently Used lists what
the engine's formulas.recentlyUsed returns.
- The function categories, the function list (built once) and the menus
live in a new function_library module; the dialog's category labels
come from it.
- keytips.json gains MR for Recently Used, Excel's sequence. Labelled
small and big buttons report their label to accessibility.
- The one-line labels (Date & Time, Lookup & Reference, Math & Trig,
More Functions) replace the two-line keys in every interface
language, with the same words. Recently Used is translated in Czech,
German, Spanish, French, Japanese, Korean, Portuguese, Russian and
Chinese; the other languages show it in English, their fallback.
Tests: tests/it/function_library.rs covers the layout (columns of three
level with the tab's other columns), each category menu and its Insert
Function… row, the More Functions cascade, the AutoSum split button and
its menu, and the MR key tip. A ribbon unit test keeps Command-key
glyphs out of the ribbon's text. chart_resize picks the chart menu's
Delete now that Home › Cells' Delete has an accessible name.
The Automate tab gains a Macros group: Macros opens the Macros dialog,
Record Macro opens the Record Macro dialog (name, Ctrl+Shift shortcut
letter, description, Use Relative References) and turns into Stop
Recording while recording, Use Relative References sets how the next
recording starts, and Run Macro runs the macro run last; its menu lists
the recent macros, then every macro. While recording, the status bar
shows a red dot, "Recording · N steps" and Stop.
The Macros dialog (Automate › Macros, View › Macros, Alt+F8) lists the
workbook's macros with their shortcuts, then its Automate scripts, and
says when the file carries a VBA project, which is kept and not run.
Run, Delete (which asks first) and Options (shortcut letter and
description) act on the selected row. The dialog keeps the result of
view.macros, so the scripts and the VBA entry are listed as before.
A macro that needs approval asks with Run, and one whose output would
land on data asks with Overwrite, Shift Down and Shift Right; each
button runs the command again with its answer. Ctrl+Shift+letter
(Cmd+Shift on a Mac) runs the macro with that shortcut; the letters
GridCraft uses keep their meaning. The View › Macros keytips (WMR, WMV)
now open the Record Macro and Macros dialogs.
Icons for macros, recording and relative references are drawn in code,
the recording dot is a theme token covered by the contrast test, and
large and small ribbon buttons and icon buttons carry accessible names.
formulas.pasteName lists the names the active sheet can use (workbook
names and the sheet's own, without hidden names, in alphabetical order).
With name it puts the name at the caret of the formula being edited,
replacing selected text, or starts =Name; with list: true it writes each
name and the text of what it refers to in two columns from the active
cell. The Paste Name dialog opens from F3 when the workbook has names,
from Use in Formula's new Paste Names… item and from Alt+M, S, P. While
a dialog is open over the edit, the editor takes no keys.
Use in Formula lists the same names, and formulas.useInFormula inserts
at the caret instead of replacing the text being edited.
Every Alt, H, B letter ran home.borders with no params, which defaults to
a bottom border, so H,B,N (No Border) and H,B,A (All Borders) both drew a
bottom border. keytips.json entries now take optional fixed `params`
(Action::CommandWith / DialogWith), and each Borders menu letter passes the
preset Excel's menu gives it. H,B,M opens Format Cells on the Border tab.
Erase Border, Line Color and Line Style are reserved (pending) instead of
drawing a bottom border.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Side-by-side and synchronous-scrolling keytips removed (do not exist in
James's Excel); Copy H,C / Spelling R,S / Fill H,H / Sparklines N,Z,K
confirmed already correct
- QAT digits 0-9 and Backstage account/home/options + legacy Share Workbook
sequences dropped (no meaningful GridCraft target; not left as trash)
- Colour palette (H,H fill and F,C font colour): arrow keys move a highlight
through the swatches, Enter applies; key events are stripped so the grid
behind the popup does not react
- Arrows/Enter while a keytip combo is open now navigate the list instead
of moving the filter field's text cursor (events stripped from TextEdit)
- Reopening a combo resets the filter: the reset frame requests a repaint
so the stale filtered list never lingers on screen
- Page Layout Sheet Options: Gridlines View/Print and Headings View/Print
checkboxes painted with VG/PG/VH/PH badges and keytip toggles
- Background rebound from PG to PGB (Excel's Page Setup GB badge); PG is
no longer terminal
- editable_combo: every dropdown keytip opens with a filter field focused;
typing narrows the list, Up/Down move the highlight (wrapping), Enter or
click applies, custom text applies where valid (font size). Fixes arrows
and typing in ALT+H FF/FS/N.
- Audited all 54 painted ribbon ids against the table: real mismatches fixed
(Data Sort/Text-to-Columns/Remove-Duplicates/Subtotal, Review Spelling/
Accessibility/New Comment/Notes, View Zoom/Freeze, Formulas Insert Function/
Name Manager/Define Name/Use-in-Formula/Error Checking/Evaluate, Insert Link/
Comment/Header-Footer/Sparklines, Home Protect Sheet).
- keytips.json: dialog kind for real dialog openers; control kind for the 6
chart-type buttons, 7 formula-category buttons, and Orientation (HFQ added,
was missing); M-family restructured to Excel semantics (ML/MT/ME/MO/MG/MQ
fire directly, MI1 opens Financial) with 14 unreachable children dropped;
383 entries total.
- New Action::Control routes a keytip to its ribbon control (popup/dropdown
open, checkbox toggle, button handler) instead of an engine command with
empty params. Fixes ALT+H FF/FS/N/H/H error boxes.
- Ribbon consumes a one-shot ui.keytip_invoke: font/size/number combos
converted to the popup pattern (ComboBox has no open_memory), fill/font
color menus force-open via SetOpenCommand, 100% zoom and Formula Bar run
their handlers.
- keytips.json: FF/FS/N/H/H -> control kind; View/Formulas/Data dialog
openers (WQ zoom, HFM format cells, HO*, MV, AWG, sparkline types) and
control WVF; MSP/HVP re-targeted; dropped 15 unreachable Home sub-items
and non-Excel HWS shrink-to-fit.
- View tab: badges on workbook views, gridlines/headings, formula bar.
- Generated suite: 399 tests incl control-kind arm; direct tests 18.
cargo xtask keytips now emits tests/keytips_generated.rs alongside the
table: one end-to-end test per sequence, asserting exactly what its
action does today. The generator probes the live engine catalog at
generation time (blank workbook, empty params), so each live command
asserts journaled / ran clean / surfaced its missing-params error;
pending asserts silence; dialogs assert the dialog opens; tabs assert
the ribbon switch; group levels assert the prefix stays armed.
- pending-but-landed targets get live assertions and a generation
warning (HWS home.shrinkToFit and MAA formulas.removeArrows had
landed since population - flipped to live)
- unreachable-sequence validation: any seq with a terminal prefix
entry is rejected (HCP dropped - HC Copy fires first)
- ENV_SENSITIVE list keeps the checked-in file byte-stable across
machines (review.spelling uses the system dictionary)
- sample_sequences_work_with_text_before_key covers IME text-first
event order for one representative of each action kind
- generated_test_count_matches_the_table pins the table size
518 ui-egui tests green; all 8 CI gates pass.
- Action::Pending now consults the engine catalog at fire time: silent
no-op while the command is missing, runs it once it exists - no table
edit needed when a future feature lands.
- Stripped stray backticks from 7 pending target ids so catalog lookup
can ever match them.
- gridcraft-engine: doc(hidden) register_test_command hook so UI tests
can prove the go-live path without touching production code.
- Tests: pending_sequences_are_silent_no_ops (no dialog/toast/journal),
pending_sequences_go_live_when_the_command_lands (fake command fires
via its reserved sequence), every_sequence_terminates_without_panicking
(all 413 sequences pressed end-to-end).
- HP -> home.percent (was wrongly numberFormat); HN stays the Number dropdown.
- H3 -> home.underline fires directly; H3U/H3D dropped as unreachable.
- HAT/HAM/HAB -> Top/Middle/Bottom Align (were unbound).
- NCM/NZT/NZS -> modern Comment/Text Box/Symbol (NC2/NZTX/NU kept as
legacy aliases); MI1 -> Financial first item.
- Badges on the three dropdowns (font FF, font size FS, number format N)
and the vertical alignment buttons; Print Titles paints PI.
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.
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.