Skip to content

Refactor to LET — PR 1: tracer (non-LET formulas, refs + ranges + spill) #202

@jimmytacks

Description

@jimmytacks

Part of #201

Tracer-bullet slice. End-to-end loop on the simplest case: a non-LET formula with cell refs and ranges, including spill refs (A1#) distinct from their anchor (A1). Existing LETs are refused with a "coming in PR 2" message — removed in #PR2.

Scope

  • Shared-infra change: add bool IsSpilled to FormulaRef (equality + hash + DisplayAddress); CellRefExtractor.BuildFormulaRef populates it from the existing (?<spill>\#) regex group. Verify existing CellRefExtractorTests and GatherEngineTests still pass. If any /Gather test fails due to double-counting A1 vs A1#, fall back to a RefactorEngine-local key wrapper instead.
  • Register /Refactor slash command in LambdaPopup.xaml.cs. On an empty / literal active cell, popup closes silently (matches /Gather's pattern).
  • New RefactorEngine.Refactor(string formula, string activeSheet) walks via CellRefExtractor.Extract, dedupes by FormulaRef, assigns inputN auto-names, rewrites via CellRefExtractor.Rewrite, emits LET via FormulaFormatter.AppendLet.
  • New RefactorToLetWindow: original-formula header (read-only), inputs section with rename + Include checkbox + reorder (Alt+Up/Down + drag, reusing KeptRowReorderHandler), preview pane, Save/Cancel. No promotable section, no calc-binding section in this PR.
  • New Commands/RefactorCommand.cs — mirrors GatherCommand for slash-command wiring and active-cell write-back via Formula2.
  • Existing LET refused via RefactorDiagnostic of kind ExistingLet. Slash command shows the diagnostic via MessageBox.
  • External refs handled in-line as inputs in this PR (same as /Gather today). PR 3 moves them into the promotable section.

Files

New:

  • addin/lambda-boss/RefactorEngine.cs
  • addin/lambda-boss/RefactorTypes.cs
  • addin/lambda-boss/UI/RefactorToLetWindow.xaml
  • addin/lambda-boss/UI/RefactorToLetWindow.xaml.cs
  • addin/lambda-boss/Commands/RefactorCommand.cs
  • addin/lambda-boss.Tests/RefactorEngineTests.cs
  • addin/lambda-boss.Tests/CellRefExtractorSpillTests.cs

Modified:

  • addin/lambda-boss/GatherTypes.cs (add IsSpilled to FormulaRef)
  • addin/lambda-boss/CellRefExtractor.cs (populate IsSpilled)
  • addin/lambda-boss/UI/LambdaPopup.xaml.cs (register /Refactor)

Tests (RefactorEngineTests)

  • single cell ref
  • multiple refs deduped
  • range
  • spill-distinct (A1 and A1# produce two bindings)
  • sheet-qualified ref dedupe (A1 and Sheet1!A1 collapse when active sheet is Sheet1)
  • cross-sheet ref stays distinct
  • rename through body
  • round-trip via LetParser.Parse + LetToLambdaBuilder.Build

Manual Excel test

Type =IF(A1<10, IF(A1>2, SUM(B1:B5), 0), SUM(B2:B6)) into a cell. Run /Refactor. Save. Confirm the resulting LET evaluates identically.

Reference

Plan: plans/0008-refactor-to-let.md § PR 1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions