Documentation
¶
Overview ¶
Package undo provides undo/redo infrastructure for text editing.
Index ¶
- Constants
- type TextDeleteType
- type TextEditType
- type TextFieldEditUndoBehavior
- type TextUndoOperation
- type UndoManager
- func (u *UndoManager[T]) CanRedo() bool
- func (u *UndoManager[T]) CanUndo() bool
- func (u *UndoManager[T]) Capacity() int
- func (u *UndoManager[T]) ClearHistory()
- func (u *UndoManager[T]) GetRedoStack() []T
- func (u *UndoManager[T]) GetUndoStack() []T
- func (u *UndoManager[T]) PeekRedo() T
- func (u *UndoManager[T]) PeekUndo() T
- func (u *UndoManager[T]) Record(action T)
- func (u *UndoManager[T]) Redo() T
- func (u *UndoManager[T]) RedoStackSize() int
- func (u *UndoManager[T]) ReplaceTop(action T)
- func (u *UndoManager[T]) Size() int
- func (u *UndoManager[T]) Undo() T
- func (u *UndoManager[T]) UndoStackSize() int
Constants ¶
const DefaultUndoCapacity = 100
DefaultUndoCapacity is the default maximum number of undo operations to keep.
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 ¶
func (op *TextUndoOperation) Merge(next *TextUndoOperation) *TextUndoOperation
Merge attempts to merge this operation with the next operation.
Returns the merged operation, or nil if they cannot be merged.
Merge rules:
- Both must have CanMerge=true
- Time difference must be < 2 seconds
- Newline insertions never merge
- Only same TextEditType can merge
- For insertions: next must extend this (cursor moving forward)
- 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.