| Title: | Manage the History of Any Object with Undo/Redo Operations |
|---|---|
| Description: | Track the history of any R object and move through it with undo and redo operations. Anything can be stored, from a single number to a data frame or an entire application state. A manager can restrict its history to specific classes and cap how many items it keeps, and it can be reactive to integrate with 'Shiny'. |
| Authors: | Dean Attali [aut, cre] (ORCID: <https://orcid.org/0000-0002-5645-3493>) |
| Maintainer: | Dean Attali <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.0.9000 |
| Built: | 2026-10-13 11:35:37 UTC |
| Source: | https://github.com/daattali/undomanager |
Two managers are equal when they hold the same value, the same undo and redo
history, and the same type restriction. Internal bookkeeping, such as the
counter used to trigger shiny reactivity, is ignored, so two managers that
reached the same state by different routes compare as equal.
## S3 method for class 'UndoManager' all.equal(target, current, ...)## S3 method for class 'UndoManager' all.equal(target, current, ...)
target, current
|
The two |
... |
Passed on to |
Note that identical() cannot be used to compare managers: R6 objects are
environments, so identical() always reports two separate managers as
different regardless of their contents.
TRUE if the two managers are equal, otherwise a character vector
describing the differences.
Create a new UndoManager to track the history of an object and move
through it with undo and redo operations. The manager starts out empty; the
first call to $do() gives it a value.
undomanager(type = NULL, allow_null = FALSE, max_size = Inf)undomanager(type = NULL, allow_null = FALSE, max_size = Inf)
type |
The permitted classes of the items ( |
allow_null |
Whether |
max_size |
The maximum number of items to keep. Once the history
grows past this, the oldest items are dropped. Use |
This is the recommended way to create a manager. It is equivalent to
UndoManager$new(), which is also available for anyone who wants to work
with the R6 class directly, such as to subclass it.
A manager is an R6 object, so it has reference semantics: its methods modify the manager in place instead of returning a modified copy, and assigning a manager to a second variable does not copy it.
A new UndoManager object.
UndoManager for the full list of methods and active bindings.
nums <- undomanager() nums$do(5) nums$do(7) nums$do(10) nums$undo()$value nums$redo()$value # operations return the manager, so they can be chained undomanager()$do(1)$do(2)$do(3)$undo(2)$value undomanager(type = "numeric") undomanager(type = "numeric", allow_null = TRUE) undomanager(max_size = 10)nums <- undomanager() nums$do(5) nums$do(7) nums$do(10) nums$undo()$value nums$redo()$value # operations return the manager, so they can be chained undomanager()$do(1)$do(2)$do(3)$undo(2)$value undomanager(type = "numeric") undomanager(type = "numeric", allow_null = TRUE) undomanager(max_size = 10)
With the undo manager, you can manage the history of an object by using undo and redo operations.
Managers are usually created with undomanager() rather than by calling
UndoManager$new() directly. The class itself is exported for anyone who
wants to work with it directly, such as to subclass it.
valueGet the value
is_emptyWhether the manager holds no value at all
can_undoWhether there are any undo operations available
can_redoWhether there are any redo operations available
undo_sizeGet the number of undo operations
redo_sizeGet the number of redo operations
UndoManager$new()Create a new undo manager. The manager starts out empty; the first
call to do() gives it a value. Most users should call
undomanager() instead, which is equivalent.
UndoManager$new(type = NULL, allow_null = FALSE, max_size = Inf)
typeThe permitted classes of the items (NULL to allow any
object). An item is accepted when any of these classes appears among
the classes R would dispatch on, so "numeric" also accepts integers
and numeric matrices.
allow_nullWhether NULL values are allowed. Only used when
type is given; an untyped manager accepts any object, including NULL.
max_sizeThe maximum number of items to keep. Once the history
grows past this, the oldest items are dropped. Use Inf for no limit.
A new UndoManager object.
UndoManager$new() UndoManager$new(type = "numeric") UndoManager$new(type = "numeric", allow_null = TRUE) UndoManager$new(max_size = 10)
UndoManager$reactive()Get a shiny reactive for this manager, so that it can be used inside a reactive context. The returned reactive invalidates whenever the value changes, and calling it returns the manager itself.
UndoManager$reactive()
A shiny reactive expression that returns the manager.
if (requireNamespace("shiny", quietly = TRUE)) {
nums <- undomanager()$do(5)
rx <- nums$reactive()
shiny::isolate(rx()$value)
}
UndoManager$print()Print the manager: the classes it accepts, how many undo and redo operations are available, the current item, and the items in the undo and redo history.
UndoManager$print(...)
...Not used.
The manager, invisibly.
undomanager()$do(5)$do(7)$do(10)$undo()$print()
UndoManager$undo()Move back in the history, making the previous item current. Undoing when there is nothing left to undo does nothing.
UndoManager$undo(n = 1)
nThe number of undo operations to perform. If n is larger
than the number of available undo operations, all of them are
performed. Use Inf to undo the entire history.
The manager, invisibly.
nums <- undomanager()$do(5)$do(7)$do(10) nums$undo()$value nums$undo(Inf)$value
UndoManager$redo()Move forward in the history, reversing an undo. Any redo history is
discarded as soon as a new item is added with do(). Redoing when
there is nothing left to redo does nothing.
UndoManager$redo(n = 1)
nThe number of redo operations to perform. If n is larger
than the number of available redo operations, all of them are
performed. Use Inf to redo the entire history.
The manager, invisibly.
nums <- undomanager()$do(5)$do(7)$do(10)$undo(2) nums$redo()$value nums$redo(Inf)$value
UndoManager$do()Add an item and make it the current value. The item that was current becomes the most recent undo, and any redo history is discarded.
UndoManager$do(item)
itemThe item to add. It must satisfy the manager's type, if
one was given.
The manager, invisibly.
nums <- undomanager() nums$do(5) nums$do(7)$value nums$undo()$do(99)$redo_size
UndoManager$clear()Forget the undo and redo history, keeping the current value.
UndoManager$clear(clear_value = FALSE)
clear_valueWhether to also discard the current value, leaving the manager empty.
The manager, invisibly.
nums <- undomanager()$do(5)$do(7) nums$clear()$undo_size nums$value nums$clear(clear_value = TRUE)$is_empty
undomanager(), the recommended way to create a manager.
nums <- undomanager() nums$do(5) nums$do(7) nums$do(10) nums$undo()$value nums$redo()$value # operations return the manager, so they can be chained undomanager()$do(1)$do(2)$do(3)$undo(2)$value ## ------------------------------------------------ ## Method `UndoManager$new()` ## ------------------------------------------------ UndoManager$new() UndoManager$new(type = "numeric") UndoManager$new(type = "numeric", allow_null = TRUE) UndoManager$new(max_size = 10) ## ------------------------------------------------ ## Method `UndoManager$reactive()` ## ------------------------------------------------ if (requireNamespace("shiny", quietly = TRUE)) { nums <- undomanager()$do(5) rx <- nums$reactive() shiny::isolate(rx()$value) } ## ------------------------------------------------ ## Method `UndoManager$print()` ## ------------------------------------------------ undomanager()$do(5)$do(7)$do(10)$undo()$print() ## ------------------------------------------------ ## Method `UndoManager$undo()` ## ------------------------------------------------ nums <- undomanager()$do(5)$do(7)$do(10) nums$undo()$value nums$undo(Inf)$value ## ------------------------------------------------ ## Method `UndoManager$redo()` ## ------------------------------------------------ nums <- undomanager()$do(5)$do(7)$do(10)$undo(2) nums$redo()$value nums$redo(Inf)$value ## ------------------------------------------------ ## Method `UndoManager$do()` ## ------------------------------------------------ nums <- undomanager() nums$do(5) nums$do(7)$value nums$undo()$do(99)$redo_size ## ------------------------------------------------ ## Method `UndoManager$clear()` ## ------------------------------------------------ nums <- undomanager()$do(5)$do(7) nums$clear()$undo_size nums$value nums$clear(clear_value = TRUE)$is_emptynums <- undomanager() nums$do(5) nums$do(7) nums$do(10) nums$undo()$value nums$redo()$value # operations return the manager, so they can be chained undomanager()$do(1)$do(2)$do(3)$undo(2)$value ## ------------------------------------------------ ## Method `UndoManager$new()` ## ------------------------------------------------ UndoManager$new() UndoManager$new(type = "numeric") UndoManager$new(type = "numeric", allow_null = TRUE) UndoManager$new(max_size = 10) ## ------------------------------------------------ ## Method `UndoManager$reactive()` ## ------------------------------------------------ if (requireNamespace("shiny", quietly = TRUE)) { nums <- undomanager()$do(5) rx <- nums$reactive() shiny::isolate(rx()$value) } ## ------------------------------------------------ ## Method `UndoManager$print()` ## ------------------------------------------------ undomanager()$do(5)$do(7)$do(10)$undo()$print() ## ------------------------------------------------ ## Method `UndoManager$undo()` ## ------------------------------------------------ nums <- undomanager()$do(5)$do(7)$do(10) nums$undo()$value nums$undo(Inf)$value ## ------------------------------------------------ ## Method `UndoManager$redo()` ## ------------------------------------------------ nums <- undomanager()$do(5)$do(7)$do(10)$undo(2) nums$redo()$value nums$redo(Inf)$value ## ------------------------------------------------ ## Method `UndoManager$do()` ## ------------------------------------------------ nums <- undomanager() nums$do(5) nums$do(7)$value nums$undo()$do(99)$redo_size ## ------------------------------------------------ ## Method `UndoManager$clear()` ## ------------------------------------------------ nums <- undomanager()$do(5)$do(7) nums$clear()$undo_size nums$value nums$clear(clear_value = TRUE)$is_empty