Actions
Actions are named, imperative commands โ undo, copy, delete-selection, zoom-to-fit, switch-mode โ collected in a registry together with their hotkeys. The registry is what hotkey binding and menus dispatch against, so the same command is reachable from a keystroke, a button, or code.
The registryโ
ActionRegistry holds Action entries grouped by ActionCategory. defaultActionRegistry is a shared instance already populated with the built-ins by registerBuiltinActions. Each action carries a HotkeyMatcher and runs against an ActionContext.
import { defaultActionRegistry, type Action } from "@oh-just-another/state";
// Already populated with built-ins; dispatch against it directly.
defaultActionRegistry.dispatchHotkey(event, { editor });
Built-in actionsโ
Built-ins are exported both as bundles and individually, so hosts can replace or compose them:
- History โ
actionUndo,actionRedo(historyActions). - Selection โ
actionSelectAll,actionDeleteSelection,actionDuplicateSelection,actionToggleLock,actionEnterContainer,actionExitContainer(selectionActions). - Clipboard โ
actionCopy,actionCut,actionPaste,actionCopyStyle,actionPasteStyle(clipboardActions). - Z-order โ
actionBringToFront,actionSendToBack,actionBringForward,actionSendBackward(zOrderActions). - Grouping โ
actionGroupSelection,actionUngroupSelection(groupingActions). - Zoom โ
actionZoomIn,actionZoomOut,actionZoomReset,actionZoomToFit,actionZoomToSelection(zoomActions). - Modes โ
actionModeSelectโฆactionModeFrame,actionToggleToolLock,actionCancel(modeActions). - View โ
actionToggleGrid,actionToggleReadOnly(viewActions). - Arrange โ flips (
actionFlipHorizontal/actionFlipVertical), aligns (actionAlignLeftโฆactionAlignBottom), distributes (actionDistributeHorizontal/actionDistributeVertical) (arrangeActions). - Text โ
actionIncreaseFontSize,actionDecreaseFontSize(textActions).
registerBuiltinActions additionally registers keyboard-navigation actions (arrow-key nudge, spawn-connected, focus-next/prev, edit-or-create) and layout actions (arrange as grid/stack, auto-arrange) that are not exported individually.
Predicates hasSelection and hasSelectionOrLink gate actions that only make sense with something selected. Actions without the viewMode flag are blocked while the editor is read-only.
import { ActionRegistry, actionCopy, hasSelection } from "@oh-just-another/state";
const registry = new ActionRegistry();
registry.register(actionCopy);
Hotkeys for these actions are wired to a keydown listener via bindEditorHotkeys, which dispatches the first matching action. Besides single-key HotkeyMatchers, actions can declare multi-key sequence hotkeys (checked first, within a rolling time window) and a keyTest escape hatch for combinations the declarative matchers can't express.