mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-03 00:41:56 -06:00
Engine: the macro recorder keeps a step's own sheet, stays bounded, and can be cancelled
Six fixes from a review of the recorder, each with a regression test (four
fail against the old recorder; the other two bound work that grew with the
input):
- A step that names another sheet with its sheet parameter (cell.set and
about fifty other commands) was tokenized as if on the input's sheet, so a
recorded cell.set {sheet: Two, cell: C4} ran on Two at the input's
relative place. Such a step keeps its references, like a sheet-qualified
one.
- Inlining recorded runs of other macros and scripts stops at the macro's
step limit and counts the rest in dropped, instead of expanding every run
first (a thousand runs of a long macro made millions of steps).
- macro.record {cancel: true} ends a recording without saving it: the way
out of a recording whose macro is too large for the workbook, which could
neither be saved nor ended.
- Formula tokenization reads each reference in the formula and matches it,
instead of listing every column and row of the example (an example as
large as a sheet made a million candidates per formula).
- A selection of several areas keeps its active cell as it is; a token for
the active cell alone put it outside the areas on playback.
- Steps recorded in another workbook are counted in dropped.
This commit is contained in:
@@ -45,7 +45,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Record Macro",
|
||||
["View", "Macros"],
|
||||
None,
|
||||
"{stop?: bool, relative?: bool (default true; when starting), name?, description? (when stopping; a taken name gets a suffix)} toggles recording; with relative references the selection when it starts is the example input → {recording, relative?, input?} or {recording: false, saved, steps, dropped, skipped, inputs}",
|
||||
"{stop?: bool, cancel?: bool (ends a recording without saving it), relative?: bool (default true; when starting), name?, description? (when stopping; a taken name gets a suffix)} toggles recording; with relative references the selection when it starts is the example input → {recording, relative?, input?} or {recording: false, saved, steps, dropped, skipped, inputs}",
|
||||
has_doc,
|
||||
record
|
||||
),
|
||||
@@ -163,6 +163,13 @@ fn check(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
}
|
||||
|
||||
fn record(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
// `cancel` ends a recording without saving it: the way out of a recording whose macro
|
||||
// cannot be saved (too large for the workbook, for one).
|
||||
if bool_param(p, "cancel").unwrap_or(false) {
|
||||
let was = s.stop_recording().is_some();
|
||||
s.macro_recording = None;
|
||||
return Ok(json!({"recording": false, "cancelled": was}));
|
||||
}
|
||||
if bool_param(p, "stop").unwrap_or(false) || s.is_recording() {
|
||||
return stop_recording(s, p);
|
||||
}
|
||||
@@ -228,8 +235,9 @@ fn save_recording(s: &mut Session, p: &Json, rec: &crate::record::Recorder, star
|
||||
None => crate::macros::next_name(&wb),
|
||||
};
|
||||
let mut converted = crate::macros::recorder::convert(&name, &start, &rec.steps, &wb);
|
||||
// Steps past the macro limit are left out and counted with the ones the recorder dropped.
|
||||
let cut = converted.mac.steps.len().saturating_sub(gridcraft_model::MAX_MACRO_STEPS);
|
||||
// Steps past the macro limit, and ones recorded in another workbook, are left out and counted
|
||||
// with the ones the recorder dropped.
|
||||
let cut = converted.cut.saturating_add(converted.mac.steps.len().saturating_sub(gridcraft_model::MAX_MACRO_STEPS));
|
||||
converted.mac.steps.truncate(gridcraft_model::MAX_MACRO_STEPS);
|
||||
if let Some(desc) = str_param(p, "description") {
|
||||
converted.mac.description = desc.chars().take(gridcraft_model::MAX_MACRO_TEXT).collect();
|
||||
|
||||
Reference in New Issue
Block a user