Skip to content

Undo for every code-changing action, not just refactorings #452

Description

@ericwinger

Summary

Nothing in Jasper is undoable today. Any action that changes code — saving a method, deleting a
class, renaming a dictionary, applying a refactoring — takes effect immediately, and the only way
back is aborting the transaction, which discards every other uncommitted change you have made too.

#434 is work in progress to make the refactorings
reversible. This issue is everything else.

Together they are the engineering slice of #174: #174
states the goal ("every user action should be undoable"), these are about what it costs to get there.

Status of #434, which this builds on

In progress. Not merged, not reviewed, not manually verified. Nothing here should be started on
the assumption that it works. This issue is filed now to capture the design questions while they are
fresh, not to queue work behind something finished.

Why it may be worth building on rather than beside

The recording being built in #434 is not refactoring-shaped: it snapshots the state of the method
slots a change touches, before and after, and diffs them. If that generalises, any action that
compiles or removes methods could record an undo the same way, and reuse the preview UI rather than
growing a second mechanism that would later have to be reconciled with the first.

That is an expectation, not a result. If it does not hold, better to find out before adding callers.

The actions this issue covers

  • Methods — save, revert, add, delete, delete a category's methods, rename a method category
  • Classes — create, delete, save a definition, save a comment
  • Variables — add a class variable, add accessors
  • Dictionaries — create, rename, remove, move a class between dictionaries
  • Class history — restore a version

Save a method is the one users would feel first, and is among the cheapest.

The parts that are not cheap

  • Deleting a class needs the whole definition plus every method captured up front — once it is
    gone there is no earlier version to fall back to.
  • Anything reversed by restoring a class version discards work written since, because a restore
    brings that version's methods with it. Whatever RB: Undo a refactoring — at minimum the last one, ideally a buffer of recent ones #434 settles on for naming what would be lost, the
    same obligation applies here.
  • Removing a version from the class history is irreversible — it destroys what any undo would
    need, so it belongs on a refuse-to-record list rather than being attempted.

Open questions

  • One undo, or a buffer? Ordinary editing would generate records constantly, which probably forces a
    buffer and a depth policy.
  • What clears it? An abort invalidates every uncommitted record, and nothing would notice.
  • Does ctrl+z bind to this? It cannot ride VS Code's own undo stack — that is per-document, and
    these changes are in the stone — so it would need its own keybinding, scoped so it never shadows
    buffer undo in an editor.

Part of #297.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestideIDE componentnot readyBeing discussed/designed.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions