Skip to main content

UndoStack

Struct UndoStack 

Source
pub struct UndoStack<C> { /* private fields */ }
Expand description

The bounded undo/redo history for a single document (TR-010..014).

Newest reversible boundary is at the back/top of undo. Generic over the cursor/metadata type C carried in each UndoEntry. See the module docs for the WASM-clean, structural-sharing, current/ring state model, and the caller-side coalesce decision.

§Downstream reuse (E005 / E008 — TR-013)

This is the reusable undo/redo model the downstream editing epics edit against: E005 (smart authoring) and E008 (structural / table editing). It lives in ronin-core precisely so any surface can own a per-document handle, while the editor-specific glue (cursor type, coalesce timing, dirty tracking) stays in the host. The key reuse contract:

  • Construct per document via with_config (host’s NEW-CONFIG cap + coalesce window) or new for the defaults.
  • After each edit, record an UndoEntry snapshot (CST, exact bytes, cursor) with the caller-measured coalesce flag — this module reads no clock, so the host decides run boundaries.
  • On undo/redo, apply the returned entry’s source_text to the buffer verbatim for an exact-prior-byte restore (no reflow / normalization, TR-010 / SC-005); redo is invalidated automatically by the next record.

Choose C to match the surface (the native editor uses its CursorState; a headless consumer can use ()). The history is always bounded (count + bytes) and adds no filesystem / native dependency, so it is WASM-clean for every downstream surface.

Implementations§

Source§

impl<C> UndoStack<C>

Source

pub fn new() -> Self

Create an empty stack with the default cap and coalesce window.

Source

pub fn with_config(cap: UndoCap, coalesce_window: Duration) -> Self

Create an empty stack with an explicit history cap and coalesce window.

Use this to apply the editor’s NEW-CONFIG values (ronin-app AppSettings). The cap is taken as-is; build it through UndoCap::new first so a zero/misconfigured field reverts to default (never unbounded).

Source

pub fn cap(&self) -> UndoCap

The current history bound (count + byte-size cap).

Source

pub fn coalesce_window(&self) -> Duration

The coalesce window: reference metadata for the caller’s timing decision.

This module never measures elapsed time against it (it stays WASM-clean); the caller compares its own Instant elapsed against this and passes the result as the coalesce flag to record.

Source

pub fn current(&self) -> Option<&UndoEntry<C>>

The current committed document state, or None before the first record.

Source

pub fn len(&self) -> usize

Number of committed undo boundaries currently retained (the steps undo can take back from the current state).

Source

pub fn is_empty(&self) -> bool

Whether there are no committed undo boundaries to step back to.

Source

pub fn has_pending(&self) -> bool

Whether a coalescing keystroke run is currently open. The document seam (T036) closes it implicitly on the next non-coalescing record or on undo/redo; exposed for tests and host wiring.

Source

pub fn can_undo(&self) -> bool

Whether an undo step is currently available.

Source

pub fn can_redo(&self) -> bool

Whether a redo step is currently available.

Source

pub fn redo_len(&self) -> usize

Number of states currently replay-able by redo (cleared on a new edit).

Source

pub fn retained_bytes(&self) -> usize

Total retained snapshot byte-size across the committed undo boundaries (compared against the byte-size cap, TR-024).

Counts the undo ring only — the boundaries the cap drops oldest-first. The live current is the caller’s buffer (not history) and redo is cleared by any new edit, so the ring is the bounded retained history.

Source

pub fn total_bytes(&self) -> usize

Total retained snapshot byte-size across both the undo ring and the redo stack plus the current state (the full in-memory history footprint).

Used by SC-009 to assert the whole undo/redo memory stays bounded by the configured cap independent of file size; the per-cap drop is enforced against retained_bytes (the bounded ring).

Source

pub fn record(&mut self, entry: UndoEntry<C>, coalesce: bool)

Record a new committed document state (T031/T032/T033/T034).

entry is a snapshot of the document after the edit just applied (its source_text is the new exact buffer bytes, its cst_snapshot the matching CST, and cursor the post-edit caret). coalesce is the caller-supplied timing decision (this module measures no clock, TR-014):

  • coalesce == false — start a new undo unit: the previous current boundary is pushed onto the bounded undo ring and entry becomes the new current (TR-010). The first record on an empty stack just seeds current with no boundary to keep. This is the first edit of a run (the caller measured a pause, or a restore reset the timing anchor), so it is its own discrete undo step that a following within-window edit may then extend.
  • coalesce == truecontinue the current run: entry replaces current in place without pushing a boundary, so the whole keystroke run collapses to the single boundary captured before the run began (TR-027, one unit per run — SC-006/SC-010).

In both forms entry becomes the live current and the run stays open, so the next within-window edit folds in. Either form clears the redo stack — a new edit after an undo invalidates redo (TR-012). After pushing a boundary the bounded ring is trimmed oldest-first by BOTH the count and byte-size cap (TR-011/TR-024).

Source

pub fn undo(&mut self) -> Option<UndoEntry<C>>
where C: Clone,

Undo one step: restore the most recent prior boundary (T031).

Pops the newest boundary off the undo ring, pushes the current state onto redo, makes the popped boundary the new current, and returns it so the caller can apply its exact-prior source_text/cst/cursor to the buffer byte-for-byte (no reflow — TR-010/SC-005). Closes any open coalesce run. Returns None when there is nothing to undo.

Requires C: Clone so the restored boundary can become the new current and also be returned to the caller (CursorState is Clone).

Source

pub fn redo(&mut self) -> Option<UndoEntry<C>>
where C: Clone,

Redo one step: replay the most recently undone state (T031).

Pops the newest state off redo, pushes the current state back onto the undo ring, makes the popped state the new current, and returns it for the caller to apply exactly (TR-010/SC-005). Closes any open coalesce run. Returns None when there is nothing to redo.

Requires C: Clone so the replayed state can become the new current and also be returned to the caller (CursorState is Clone).

Trait Implementations§

Source§

impl<C: Clone> Clone for UndoStack<C>

Source§

fn clone(&self) -> UndoStack<C>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<C: Debug> Debug for UndoStack<C>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<C> Default for UndoStack<C>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.