Skip to main content

MAX_UNDO_STEPS

Constant MAX_UNDO_STEPS 

Source
pub const MAX_UNDO_STEPS: usize = 1000;
Expand description

Whole-content undo history, stored as rope snapshots.

A snapshot is a Rope rather than a String because ropey clones are O(1) and copy-on-write: two snapshots share every node they have in common, so a deep undo stack over a large file costs the edits, not one full copy of the text per step. to_string() would allocate and copy the whole buffer on every keystroke.

Whole-content snapshots stay the right call at this size — they are correct for any edit shape, and with structural sharing they are no longer expensive enough to justify per-edit deltas.

Runs have no clock. VS Code and Zed break undo groups on an idle timer. A timer means the buffer needs a clock, which means tests need to inject one, which means the rule is only ever exercised through a fake. The rule here is structural instead: consecutive edits of the same EditKind coalesce, and anything that is not an edit — a motion, a click, a save — calls boundary. That is deterministic and it matches what a user means by “undo what I just typed”: the run ends when they moved.

ponytail: pausing mid-word for ten minutes without moving still coalesces. If that ever bites, a timer goes beside this rule, not instead of it. How many undo steps are kept.

vim’s undolevels default, and there is no reason to be cleverer until someone measures a session where it bites. Structural sharing makes each snapshot cheap but not free — every one pins the rope nodes it replaced, so an uncapped stack is an uncapped retention of every version of the file for as long as the editor is open.