10. Keyboard shortcuts
This table is generated from src/ui/shortcuts.ts — the same ALL_SHORTCUTS
table the app matches keystrokes against, and the same one the in-app Help panel
renders. tests/shortcuts.test.mjs asserts that nothing in it is left unbound
and that every chrome combo is reachable; tests/helpPanel.test.mjs asserts the
Help panel is generated from it rather than transcribed.
mod is Ctrl on Windows and Linux, ⌘ on macOS.
| Windows / Linux | macOS | Action | Bound in |
Ctrl+x | ⌘x | Cut | Shell.useChromeShortcuts |
Ctrl+c | ⌘c | Copy | Shell.useChromeShortcuts |
Ctrl+v | ⌘v | Paste | Shell.useChromeShortcuts |
Ctrl+⇧+v | ⌘⇧v | Paste in place | Shell.useChromeShortcuts |
Ctrl+] | ⌘] | Bring to front | Shell.useChromeShortcuts |
Ctrl+[ | ⌘[ | Send to back | Shell.useChromeShortcuts |
Ctrl+⇧+] | ⌘⇧] | Bring forward | Shell.useChromeShortcuts |
Ctrl+⇧+[ | ⌘⇧[ | Send backward | Shell.useChromeShortcuts |
Ctrl+⇧+e | ⌘⇧e | Export dialog | Shell.useChromeShortcuts |
Ctrl+o | ⌘o | Import diagram | Shell.useChromeShortcuts |
Ctrl+s | ⌘s | Save to My diagrams | Shell.useChromeShortcuts |
Ctrl+n | ⌘n | New diagram | Shell.useChromeShortcuts |
Ctrl+⇧+f | ⌘⇧f | Zoom to fit viewport | Shell.useChromeShortcuts |
Ctrl++ | ⌘ | Zoom in | Shell.useChromeShortcuts |
Ctrl+- | ⌘- | Zoom out | Shell.useChromeShortcuts |
Ctrl+0 | ⌘0 | Zoom to 100% | Shell.useChromeShortcuts |
⇧++ | ⇧ | Increase font size | Shell.useChromeShortcuts |
- | - | Decrease font size | Shell.useChromeShortcuts |
v | v | Select tool | Shell.useChromeShortcuts |
h | h | Pan tool | Shell.useChromeShortcuts |
c | c | Connect tool | Shell.useChromeShortcuts |
t | t | Text tool | Shell.useChromeShortcuts |
s | s | Shape tool | Shell.useChromeShortcuts |
g | g | Show grid | Shell.useChromeShortcuts |
⇧+g | ⇧g | Snap to grid | Shell.useChromeShortcuts |
r | r | Smart route | Shell.useChromeShortcuts |
j | j | Crossovers | Shell.useChromeShortcuts |
[ | [ | Toggle library panel | Shell.useChromeShortcuts |
] | ] | Toggle inspector | Shell.useChromeShortcuts |
Ctrl+k | ⌘k | Command palette | CommandPalette |
Editing the diagram#
| Windows / Linux | macOS | Action | Bound in |
Ctrl+z | ⌘z | Undo | Canvas |
Ctrl+⇧+z | ⌘⇧z | Redo | Canvas |
Ctrl+y | ⌘y | Redo | Canvas |
Ctrl+a | ⌘a | Select all | Canvas |
Ctrl+d | ⌘d | Duplicate | Canvas |
Ctrl+g | ⌘g | Group | Canvas |
Ctrl+⇧+g | ⌘⇧g | Ungroup | Canvas |
Ctrl+l | ⌘l | Lock / unlock | Canvas |
Ctrl+⇧+h | ⌘⇧h | Hide / show | Canvas |
Delete | Delete | Delete selection | Canvas |
Enter | Enter | Edit text | Canvas |
Arrow keys | Arrow keys | Nudge selection | Canvas |
View and navigation#
| Windows / Linux | macOS | Action | Bound in |
Ctrl+f | ⌘f | Find in diagram | view/index |
Ctrl+1 | ⌘1 | Zoom to fit document | view/index |
Ctrl+2 | ⌘2 | Zoom to selection | view/index |
F5 | F5 | Presentation mode | view/index |
Alt+r | ⌥r | Toggle rulers | view/index |
Alt+m | ⌥m | Toggle minimap | view/index |
Alt+d | ⌥d | Toggle dark canvas | view/index |
Style#
| Windows / Linux | macOS | Action | Bound in |
Ctrl+Alt+c | ⌘⌥c | Copy style | style/index |
Ctrl+Alt+v | ⌘⌥v | Paste style | style/index |
| Windows / Linux | macOS | Action | Bound in |
Ctrl+i | ⌘i | AI command bar | ai/CommandBar |
Notes#
Ctrl/⌘ + prints oddly on macOS. displayCombo('mod++', true) renders as
⌘ with the + lost, in this table and in the Help panel. The binding itself
is fine.
- The
Bound in column is not trivia: it says which module owns the key, so
a shortcut that stops working can be traced to one file. Shell handles the
chrome, Canvas handles everything that edits the document (so the two never
fight over a keystroke), and the view, style and AI features bind their own.
- Modifier-free keys are ignored inside text fields, the inline label editor
and the command palette, so typing
c in a search box does not switch tools.
Ctrl/⌘ V only calls preventDefault() when the in-app clipboard has
something; with it empty, the native paste event is allowed through so a
foreign diagram on the system clipboard can be imported.
? and F1 both open the Help panel. They are bound by
src/ui/helpFeature.ts and are deliberately not in ALL_SHORTCUTS, so
they do not appear in the table above or in the Help panel's own list — that
table is owned by the chrome and the help feature only reads it.
- Two toolbar tooltips advertise a key the app does not bind: the rulers button
says
⇧R when the real binding is Alt R. Use the table above.
Mouse and pointer#
| Gesture | Effect |
| Drag on empty canvas | Marquee select (Shift adds to the selection) |
Alt + drag, middle-drag, two-finger scroll | Pan |
Ctrl/⌘ + wheel | Zoom at the pointer |
| Double-click a shape | Edit its text |
| Double-click empty canvas | Create the armed shape there and edit it |
| Hover a shape | Show its eight ports |
| Drag from a port into empty space | Create a connected shape and edit it |
Alt-click a connector | Insert a waypoint there |
| Drag a connector segment | Move that straight run |
| Drag a connector end | Re-wire it |
Shift while resizing | Keep the aspect ratio |
Alt while resizing | Resize from the centre |
Ctrl/⌘ while resizing a container | Leave the children where they are |
Shift while rotating | Snap the angle |
| Right-click | The menu for whatever is under the pointer |