Skip to content

Extract reusable automatic folding orchestration from Ted #178

@tig

Description

@tig

Problem

Editor supports folding through FoldingManager, FoldingTransformer, and folding gutter rendering, but applications still have to write too much orchestration code to get Ted-style automatic brace folding.

PR #175 exposed this: Ted had to own document-change subscriptions, structural-change detection, update-boundary scheduling, fold refresh calls, and large-document disabling. Another consumer that wants the same folding behavior would currently need to duplicate that glue.

Folding orchestration should be reusable from the editor package, not app-specific Ted code.

Goal

Add a reusable automatic folding API so consumers can configure folding behavior without duplicating Ted's change-filtering and refresh logic.

A consumer should be able to do something close to:

editor.FoldingStrategy = new BraceFoldingStrategy ();
editor.AutomaticFolding = true;

or another similarly simple API that fits the existing Editor design.

Current Ted behavior to preserve/extract

Ted currently needs these responsibilities:

  • Create and assign a FoldingManager for the editor document.
  • Run BraceFoldingStrategy.UpdateFoldings initially.
  • Subscribe to document changes and defer fold refresh until UpdateFinished.
  • Refresh foldings only when a change may affect folding structure:
    • opening brace
    • closing brace
    • newline / line structure change
  • Use OffsetChangeMap entries, not the whole replaced span, to identify the actual changed chunks for batched multi-caret edits and undo/redo.
  • Avoid rescanning foldings for plain text insert/delete/backspace when no structure changed.
  • Disable automatic folding for very large documents (Ted currently uses MaximumAutomaticFoldingDocumentLength = 1_000_000).
  • Cleanly unsubscribe/rebind when the editor document changes or folding is disabled.

Proposed implementation direction

Introduce reusable folding orchestration in src/Terminal.Gui.Editor, likely on Editor itself or a small helper owned by Editor.

Possible shape:

public IFoldingStrategy? FoldingStrategy { get; set; }
public bool AutomaticFolding { get; set; }
public int MaximumAutomaticFoldingDocumentLength { get; set; } = 1_000_000;

The exact API can differ, but it should:

  • Keep folding setup/teardown encapsulated.
  • Work when Document is assigned, replaced, or cleared.
  • Preserve existing manual FoldingManager usage for advanced callers.
  • Avoid static state on Editor.
  • Keep the document-layer package independent of Terminal.Gui UI types.

If needed, define a small strategy interface around the existing folding strategies, for example:

public interface IFoldingStrategy
{
    void UpdateFoldings (FoldingManager manager, TextDocument document);
    bool ChangeMayAffectFoldings (DocumentChangeEventArgs e);
}

BraceFoldingStrategy can implement the structural-change predicate, including the OffsetChangeMap-aware logic currently in Ted.

Acceptance criteria

  • Ted no longer owns automatic folding orchestration; it only configures the editor with brace folding and its large-document limit.
  • Another app can enable Ted-equivalent brace folding with a small public API surface, without copying Ted-specific subscriptions or change filtering.
  • Plain multi-caret typing, Backspace, and Undo in TedApp.cs remain fast after the extraction.
  • Existing folding behavior still works:
    • fold indicators render
    • collapse/expand still works
    • folded-state-aware rendering still only installs folding transforms when needed
  • Large documents still skip automatic brace folding to avoid UI-thread hangs.
  • Tests cover:
    • automatic folding setup on document assignment
    • no folding refresh for non-structural mapped edits
    • folding refresh for braces/newlines
    • document replacement/unsubscribe behavior
    • Ted integration using the new reusable API
  • Update docs or examples if a public API is added.

Relevant context

  • Follow-up to issue Vertical caret insert is painfully slow #172 and PR Fix vertical multi-caret edit performance #175.
  • examples/ted/TedApp.cs currently contains app-level folding orchestration that should be extracted.
  • src/Terminal.Gui.Editor/Folding/FoldingManager.cs has performance-sensitive offset-update behavior.
  • src/Terminal.Gui.Editor/Editor.cs owns FoldingManager, folding state caching, and FoldingTransformer wiring.
  • src/Terminal.Gui.Editor/Folding/BraceFoldingStrategy.cs is the current Ted folding strategy.
  • tests/Terminal.Gui.Editor.PerformanceTests/PerformanceSmokeTests.cs contains perf guards for the real Ted vertical multi-caret repro.

Non-goals

  • Do not add a full visual-line/folding architecture beyond the existing plan.
  • Do not require apps to use Ted-specific types.
  • Do not reformat AvaloniaEdit-lifted files unrelated to the implementation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No 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