Skip to main content

Undo and redo

Press Ctrl+Z to reverse the last operation, and Ctrl+Shift+Z (or Ctrl+Y) to re-apply it. The same commands are in the Edit menu. On macOS, use Cmd instead of Ctrl.

Undo is scoped to what you are looking at: Ctrl+Z reverses the last operation on the current table or view, never one you performed somewhere else. Switching to another view and back brings the history with you.

What can be undone

AreaOperations
Grid editingEditing a cell, clearing a cell (Del), toggling a checkbox, pasting a cell or a block
RowsRemoving selected rows, the grid's and + icons, Edit | Add Rows
ColumnsRemoving columns, changing a column's type, adding or editing a formula column, renaming a column and editing its properties
ValuesFind and Replace
MetadataColor coding and format changes from the column menu
SelectionReset Selection Filter (Esc)
LayoutClosing a viewer or a view, adding a viewer, View | Layout | Clear
AIOperations performed by the assistant (add/close viewer, change properties, filter, select)

Everything else — sorting, filtering, creating new tables, and anonymizing data — is not recorded. Operations that produce a new table are non-destructive, so nothing is lost by not undoing them.

Editors with their own undo

Sketchers, the form designer, molecule and sequence editors, and graph editors keep their own undo stacks. While the focus is inside one of them, Ctrl+Z goes to that editor; everywhere else it goes to the platform. Ctrl+Z in a text field always does what it does in any browser — it undoes typing, and it does not touch the table.

While a dialog is open, Ctrl+Z never reaches the table. A dialog is its own editing session, and undoing something underneath it while you are filling in a form is never what you meant. Close the dialog first.

For developers

Plugins can make their own operations undoable:

const before = column.get(0);
column.set(0, 42);
DG.UndoService.push('Set value', () => column.set(0, before), {
redo: () => column.set(0, 42),
context: column.dataFrame
});
  • grok.shell.undo() / grok.shell.redo() — run the commands programmatically
  • grok.shell.canUndo / canRedo — enablement
  • grok.shell.onUndo / onRedo — observables carrying {name, context}
  • DG.UndoService.ownScope(element) — claim Ctrl+Z for an embedded editor while focus is inside it, instead of installing a document-level key handler

Records hold values, not row indexes of live objects: capture what you need before the change, and pass context so the record is released with its table.

See also: Keyboard shortcuts.