undo

package
v0.1.122 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 23, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package undo provides undo/redo infrastructure for text editing.

Index

Constants

View Source
const DefaultUndoCapacity = 100

DefaultUndoCapacity is the default maximum number of undo operations to keep.

View Source
const MergeTimeWindowMs = 2000

MergeTimeWindowMs is the maximum time between edits that allows merging.

Variables

This section is empty.

Functions

This section is empty.

Types

type TextDeleteType

type TextDeleteType int

TextDeleteType identifies the direction of deletion for merge logic.

This is used to determine if consecutive deletions can be merged. For example, consecutive backspace presses can be merged, but a mix of backspace and delete cannot.

const (
	// TextDeleteTypeStart represents backspace behavior (delete toward 0).
	// "abcd|efg" → "abc|efg"
	TextDeleteTypeStart TextDeleteType = iota

	// TextDeleteTypeEnd represents delete key behavior (delete toward length).
	// "abcd|efg" → "abcd|fg"
	TextDeleteTypeEnd

	// TextDeleteTypeInner represents selection deletion (directionless).
	// "ab|cde|fg" → "ab|fg"
	TextDeleteTypeInner

	// TextDeleteTypeNotByUser represents programmatic deletion not adjacent to cursor.
	// This cannot be merged with user-initiated deletions.
	TextDeleteTypeNotByUser
)

func (TextDeleteType) String

func (t TextDeleteType) String() string

String returns a string representation of TextDeleteType.

type TextEditType

type TextEditType int

TextEditType categorizes the nature of a text change.

This is used to determine whether adjacent undo operations can be merged.

const (
	// TextEditTypeInsert indicates text was inserted (zero-length range replaced with text).
	TextEditTypeInsert TextEditType = iota

	// TextEditTypeDelete indicates text was deleted (non-zero range replaced with nothing).
	TextEditTypeDelete

	// TextEditTypeReplace indicates text was replaced (non-zero range replaced with text).
	TextEditTypeReplace
)

func (TextEditType) String

func (t TextEditType) String() string

String returns a string representation of TextEditType.

type TextFieldEditUndoBehavior

type TextFieldEditUndoBehavior int

TextFieldEditUndoBehavior controls undo stack behavior for edits.

This determines how new edits interact with the undo history.

const (
	// TextFieldEditUndoBehaviorMergeIfPossible attempts to merge with the previous undo entry.
	// This is the default behavior for normal typing.
	TextFieldEditUndoBehaviorMergeIfPossible TextFieldEditUndoBehavior = iota

	// TextFieldEditUndoBehaviorClearHistory clears all undo/redo history.
	// Used for programmatic updates that shouldn't be undoable.
	TextFieldEditUndoBehaviorClearHistory

	// TextFieldEditUndoBehaviorNeverMerge always creates a new undo entry.
	// Used for cut, paste, and other atomic operations.
	TextFieldEditUndoBehaviorNeverMerge
)

func (TextFieldEditUndoBehavior) String

func (t TextFieldEditUndoBehavior) String() string

String returns a string representation of TextFieldEditUndoBehavior.

type TextUndoOperation

type TextUndoOperation struct {
	// Index is the start position of the change.
	Index int

	// PreText is the text that was replaced (deleted text).
	PreText string

	// PostText is the text that replaced it (inserted text).
	PostText string

	// PreSelection is the selection before the change.
	PreSelection text.TextRange

	// PostSelection is the selection after the change.
	PostSelection text.TextRange

	// TimeInMillis is when the change was committed.
	TimeInMillis int64

	// CanMerge indicates whether this operation can be merged with adjacent ones.
	CanMerge bool
}

TextUndoOperation represents a single atomic text change for undo/redo.

It stores the text before and after a change, along with selection states, which allows the change to be applied or reversed.

This is a port of androidx.compose.foundation.text.input.internal.undo.TextUndoOperation.

func NewTextUndoOperation

func NewTextUndoOperation(
	index int,
	preText string,
	postText string,
	preSelection text.TextRange,
	postSelection text.TextRange,
) *TextUndoOperation

NewTextUndoOperation creates a new TextUndoOperation with the current timestamp.

func NewTextUndoOperationWithOptions

func NewTextUndoOperationWithOptions(
	index int,
	preText string,
	postText string,
	preSelection text.TextRange,
	postSelection text.TextRange,
	timeInMillis int64,
	canMerge bool,
) *TextUndoOperation

NewTextUndoOperationWithOptions creates a TextUndoOperation with explicit options.

func (*TextUndoOperation) DeleteType

func (op *TextUndoOperation) DeleteType() TextDeleteType

DeleteType returns the deletion direction (only valid for Delete type).

This is used to determine if consecutive deletions can be merged.

func (*TextUndoOperation) Merge

Merge attempts to merge this operation with the next operation.

Returns the merged operation, or nil if they cannot be merged.

Merge rules:

  1. Both must have CanMerge=true
  2. Time difference must be < 2 seconds
  3. Newline insertions never merge
  4. Only same TextEditType can merge
  5. For insertions: next must extend this (cursor moving forward)
  6. For deletions: must have same direction and share boundary

func (*TextUndoOperation) TextEditType

func (op *TextUndoOperation) TextEditType() TextEditType

TextEditType returns the type of edit (Insert, Delete, or Replace).

type UndoManager

type UndoManager[T any] struct {
	// contains filtered or unexported fields
}

UndoManager is a generic undo/redo stack manager.

It maintains two stacks: undo and redo. Recording a new action clears the redo stack. Undo moves the top of undo to redo, and redo does the reverse.

The total capacity limits the combined size of both stacks. When capacity is exceeded, the oldest undo entries are discarded.

This is a port of androidx.compose.foundation.text.input.internal.undo.UndoManager.

func NewUndoManager

func NewUndoManager[T any](capacity int) *UndoManager[T]

NewUndoManager creates a new UndoManager with the given capacity.

func NewUndoManagerWithStacks

func NewUndoManagerWithStacks[T any](undoStack, redoStack []T, capacity int) *UndoManager[T]

NewUndoManagerWithStacks creates an UndoManager with initial stacks. This is used for restoring from saved state.

func (*UndoManager[T]) CanRedo

func (u *UndoManager[T]) CanRedo() bool

CanRedo returns true if there are operations to redo.

func (*UndoManager[T]) CanUndo

func (u *UndoManager[T]) CanUndo() bool

CanUndo returns true if there are operations to undo.

func (*UndoManager[T]) Capacity

func (u *UndoManager[T]) Capacity() int

Capacity returns the maximum number of operations that can be stored.

func (*UndoManager[T]) ClearHistory

func (u *UndoManager[T]) ClearHistory()

ClearHistory removes all undo and redo operations.

func (*UndoManager[T]) GetRedoStack

func (u *UndoManager[T]) GetRedoStack() []T

GetRedoStack returns a copy of the redo stack (for serialization).

func (*UndoManager[T]) GetUndoStack

func (u *UndoManager[T]) GetUndoStack() []T

GetUndoStack returns a copy of the undo stack (for serialization).

func (*UndoManager[T]) PeekRedo

func (u *UndoManager[T]) PeekRedo() T

PeekRedo returns the top of the redo stack without removing it. Panics if the stack is empty.

func (*UndoManager[T]) PeekUndo

func (u *UndoManager[T]) PeekUndo() T

PeekUndo returns the top of the undo stack without removing it. Panics if the stack is empty.

func (*UndoManager[T]) Record

func (u *UndoManager[T]) Record(action T)

Record adds a new undoable action to the stack.

This clears the redo stack and adds the action to the undo stack. If capacity is exceeded, the oldest undo entries are discarded.

func (*UndoManager[T]) Redo

func (u *UndoManager[T]) Redo() T

Redo pops the top operation from the redo stack and moves it to undo.

Panics if CanRedo() is false.

func (*UndoManager[T]) RedoStackSize

func (u *UndoManager[T]) RedoStackSize() int

RedoStackSize returns the number of operations in the redo stack.

func (*UndoManager[T]) ReplaceTop

func (u *UndoManager[T]) ReplaceTop(action T)

ReplaceTop replaces the top of the undo stack without clearing redo. This is used for merging operations. Panics if the stack is empty.

func (*UndoManager[T]) Size

func (u *UndoManager[T]) Size() int

Size returns the total number of operations in both stacks.

func (*UndoManager[T]) Undo

func (u *UndoManager[T]) Undo() T

Undo pops the top operation from the undo stack and moves it to redo.

Panics if CanUndo() is false.

func (*UndoManager[T]) UndoStackSize

func (u *UndoManager[T]) UndoStackSize() int

UndoStackSize returns the number of operations in the undo stack.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL