formulas.recentlyUsed scanned the session journal for cell.set inputs.
It missed formulas entered by range.* commands, lost them when the
journal dropped its oldest entries (a large file open or a long script
is enough), and started empty in every session. The Function Library's
Recently Used menu and the Insert Function dialog list what it returns.
- Prefs::recent_functions (a new engine module, recent.rs) holds the
ten functions most recently entered in a formula, newest first.
Session::execute updates it for every cell.* and range.* command it
journals, from any source (the interface, the control channel, MCP or
a script). It reads at most 2,000 of the formulas a command enters,
starting from the last one; formulas longer than Excel's limit are
skipped. formulas.recentlyUsed
returns it. It never reads the journal back, so the journal's caps do
not affect it.
- The list is kept with the other engine preferences (prefs.json, the
browser's storage on the web), so it survives a restart as Excel's
does. It is read leniently: a malformed value loses only this list. A
fresh install starts from common functions.
The Insert Function dialog is titled "Insert Function", as in Excel (it
said "Formula Builder"), and gains a working category list: Most
Recently Used, All, then each category in Excel's order. A category may
be given by label or by engine id, so a Function Library menu or the
control channel (ui.dialog.set) opens it on one, and a new search
switches to All. The dialog keeps its translated labels and its search
in the interface language. Each row shows the function's name and its
category in two columns; the category column starts after the widest
name shown, so a long name in any font or formula language stays clear
of it. A function counts as recently used once its formula is entered,
not when OK is pressed. The unused "Formula Builder" translations are
removed.
Tests: engine unit tests for reading functions from formulas (strings,
unknown names, over-long and malformed formulas), the formulas a
command enters (newest first, within the budget), the ten-name list
and the lenient read of prefs.json; tests/it/recently_used.rs for
cell.set and range.setValues from the session, a failed command, a
cleared journal and a save and reload of the preferences. UI tests for
the menu's order and the dialog's title, categories, engine-id
category, search and OK, and for the category column with a wide font.
Insert > Line or Area and the All Charts list offer 100% Stacked Area,
and insert.chart and chart.set take it as type area with subtype
stacked100. Each series' area stacks on the ones before it as its
share of the category's total. When every series on the value axis is
100% stacked and no value is negative, the axis runs from 0% to 100%.
A blank cell counts as zero, and a category whose total is zero stays
on the baseline.
An XLSX area chart with percentStacked grouping now opens as 100%
stacked and is saved back as percentStacked. It used to open as a
stacked area and was saved as stacked.
* CI: dev builds keep line tables only
* CI: one integration-test binary per crate
* CI: xtask runs tests with nextest, doctests apart, --keep-going on clippy and wasm
cargo xtask test runs the workspace tests (--lib --bins --tests) with cargo-nextest when it is installed, else cargo test, then the doctests. cargo xtask ci uses the same two steps.
* CI: docs name cargo xtask test
* CI: agent guides name the moved fuzz test
* CI: tests added on main join their crate's test binary