Skip to content

Keybindings and contextual help ​

The focused pane's border shows useful actions with their loaded shortcuts. Help and keyboard dispatch use the same action catalog and context checks.

  • Ctrl+? (⌘/ on macOS — the bare Cmd+/, not Cmd+Shift+/) shows the current pane's actions for five seconds, followed by a short fade.

  • Press it again while it is visible to open the same context in the Help drawer.

  • F1 opens or closes Help directly. Both shortcuts are rebindable.

  • Escape dismisses the temporary overlay. Any ordinary command dismisses it and still performs its normal action.

  • If the action list cannot fit legibly inside the pane, Help opens in the drawer directly.

Help is a fourth view of the existing drawer, alongside Julia, Terminal and Monitor. Switching to Help leaves Julia running. Escape returns to the previous drawer and focus; choosing Julia, Terminal or Monitor switches to that view. Help remembers which pane you asked about while you browse or search it.

In the Help drawer, type to search action names, descriptions or shortcuts; use arrows to select, Tab to switch between this pane and all panes, and Enter to open the selected action's manual section. A shadowed shortcut is identified instead of being advertised as working. Embedded terminal applications own their own shortcuts; the catalog describes SoT controls around them. Primary+p (Ctrl+p on Windows/Linux, ⌘P on macOS) in the Help drawer writes a printable cheat sheet of the loaded bindings and opens it in the browser; print it or save it as PDF there.

Configuration ​

Each action maps to one chord or a list of chords in a [keys] table:

toml
[keys]
help.toggle = "Primary+?"
drawer.help = "F1"
files.run_current = "F8"
preview.png.zoom_in = ["Shift+ArrowUp", "+", "="]

The first existing configuration file is selected, in this order. Its listed actions override the defaults; unlisted actions keep their defaults:

  1. $SOT_KEYBINDINGS.

  2. .sot/keybindings.toml, found by walking upward from the frontend's working directory.

  3. $HOME/.config/sot/keybindings.toml.

  4. Built-in defaults.

Bindings load on frontend startup and again on a reload_keybindings command. Invalid entries log a warning and retain the previous binding. The active Help drawer and pane borders reflect that resolved result. When two actions share a chord in the same context, catalog order defines dispatch precedence; Help identifies a shadowed binding.

Where a pane takes typed text (agent, terminal, Julia input, the editor, prompts, Help's search), a binding with no Ctrl, Alt or Super never fires: the character is typed. Bind such actions with a modifier if they must work there; Help shows them as unavailable in those panes.

Modifiers and keyboard layouts ​

On Windows the operating system hands the frontend the unshifted key while Ctrl, Alt or Win is held (Ctrl+Shift+/ arrives as /). A chord written with the shifted symbol, such as the default Ctrl+?, is therefore matched through the US layout's shifted pairs when Shift is held; Ctrl+/ and Ctrl+? stay distinct. Other layouts see the symbol they actually deliver.

Supported modifier names are Ctrl/Control, Alt/Option, Shift, and Super/Cmd/Command/Win. The legacy Meta alias continues to mean Alt. Primary means Command on macOS and Control on Windows/Linux; most defaults that are app-level chords (not terminal control codes) are spelled with it. Help and the printable cheat sheet always show the resolved form for the frontend's own OS (Ctrl+? on Windows/Linux, ⌘? on macOS), never the word Primary itself.

The frontend OS determines shortcut notation, including when a Mac frontend connects to a Linux backend: Control is ⌃, Command is ⌘, Option is ⌥, and Shift is ⇧. Explicit Control bindings remain Control; they do not silently become Command bindings. A Command binding must match the Command modifier.

Letter and named-key bindings match Shift explicitly: r and Shift+r are different actions, and Shift+ArrowUp does not also pan an image. A bare uppercase letter is shorthand for its shifted binding. Modified letter spelling is case insensitive (Ctrl+s and Ctrl+S mean the same chord).

Character shortcuts use the active keyboard layout. Ctrl+? means Control plus the question-mark character, without assuming its physical key position. Ctrl+Shift+/ explicitly binds the shifted slash key in the active layout. Option-modified keys match the layout's unmodified key on macOS (Option+= delivers ≠ on a US layout; the chord still reads as =). All shortcuts can be reassigned for layouts or OS shortcuts that conflict.

macOS reserves some chords at the system level regardless of what SoT binds: Control+Arrow switches Spaces or opens Mission Control, and F11 shows the desktop, which is why pane focus is ⌘Arrow there and fullscreen also accepts Ctrl+Cmd+F (F11 still works if that system shortcut is off). ⌘Q and ⌘H are handled by the OS-level application menu, not by SoT's own key dispatch. ⇧⌘/ is the system Help-menu shortcut, on by default, and never reaches the app at all — that is why help.toggle's macOS default is the bare ⌘/ instead of the cross-platform Primary+? pattern. On Mac laptop keyboards F1/F5/F11 need the fn key unless "Use F1, F2, etc. keys as standard function keys" is on in System Settings.

Default actions ​

These are built-in defaults. In-app Help displays the bindings actually loaded. Normal text entry and terminal-application controls retain their own input handling.

ActionDefault shortcut(s)Description
help.toggleCtrl+? (⌘/ on macOS)Show actions here for five seconds; press again to browse them in the Help drawer.
drawer.helpF1Browse and search actions for the pane you were using. Escape restores the previous drawer.
transport.reconnectF5Retry backend connections immediately.
view.fullscreenF11 (+ Ctrl+Super+f on macOS)Toggle borderless fullscreen.
font.scale_upPrimary+= / Primary++Increase the frontend font size.
font.scale_downPrimary+- / Primary+_Decrease the frontend font size.
font.scale_resetPrimary+0Restore the default frontend font size.
focus.pane_leftPrimary+ArrowLeftMove keyboard focus to the pane on the left.
focus.pane_rightPrimary+ArrowRightMove keyboard focus to the pane on the right.
focus.pane_upPrimary+ArrowUpMove keyboard focus to the pane above.
focus.pane_downPrimary+ArrowDownMove keyboard focus to the drawer or pane below.
workspace.cycle_nextShift+ArrowRightSwitch to the next workspace.
workspace.cycle_prevShift+ArrowLeftSwitch to the previous workspace.
pane.maximizeAlt+=Fill the window with the focused pane.
pane.restoreEscapeUndo maximization, then wide preview, one layer at a time.
layout.wide_previewAlt++Hide or show the agent column to give the preview more room.
view.selfiePrimary+Shift+SSave a PNG of the whole frontend window.
drawer.replPrimary+jShow or hide the Julia REPL. Changing drawer views keeps Julia running.
drawer.terminalPrimary+tShow or hide the frontend-local terminal.
drawer.monitorPrimary+mShow or hide host resource charts.
view.scroll_line_upAlt+ArrowUpScroll without moving the input cursor.
view.scroll_line_downAlt+ArrowDownScroll without moving the input cursor.
preview.table_lefth / ArrowLeftMove horizontally through a wide text table.
preview.table_rightl / ArrowRightMove horizontally through a wide text table.
preview.table_reset0Return to the left edge of a wide table.
session.create_codexPrimary+EnterCreate a workspace in the selected folder with a Codex agent.
session.create_bareShift+EnterCreate a workspace in the selected folder with a shell and no agent.
session.createEnterCreate a workspace in the selected folder with a Claude Code agent.
session.account_nextTabCycle which login account the new session will use. Hidden when only one account is discovered.
quitPrimary+qClose the window from any pane but the agent and the Terminal drawer, whose programs keep Ctrl+Q, asking whether to keep the daemon and sessions running.
files.copy_pathPrimary+c / cCopy the selected file's backend path to the clipboard.
files.newPrimary+nCreate a file, or a folder when the name ends with /, in the selected directory.
files.deletePrimary+dDelete the selected file after confirmation. Directories are refused.
nav.downArrowDownSelect the next row.
nav.upArrowUpSelect the previous row.
nav.expandArrowRightExpand the selected node or descend into a folder.
nav.openEnterOpen the selected node; in Sessions or Hosts, select that target.
nav.collapseArrowLeftCollapse the node or go to its parent.
mode.filesfBrowse project files.
mode.modulesmBrowse Julia modules and methods.
mode.sessionssBrowse workspaces and agent sessions.
files.pinpKeep the selected file in preview while browsing. Unpin returns to the pinned file.
mode.hostshBrowse backend hosts.
files.toggle_hidden.Show or hide dotfiles.
session.destroyShift+dPress twice to destroy the selected session. Any other command cancels confirmation.
file.openoOpen HTML, video or an interactive document in the browser; Julia files open in Pluto.
file.docsShift+wOpen the built documentation site for this file in the browser.
file.executeShift+oRender a Quarto document and execute its code chunks.
files.downloaddDownload the selected file to the frontend machine.
files.uploaduChoose local files to upload into the selected directory.
files.run_freshrRestart Julia in this project and run the selected Julia file. Existing REPL variables are cleared.
files.run_currentShift+rRun the selected Julia file using the current Julia session and its variables.
repl.clearCtrl+lClear the displayed REPL output; Julia's variables remain.
input.pasteCtrl+v / Super+v / Shift+InsertPaste the clipboard into this pane.
agent.copyPrimary+Shift+cCopy selected agent output to the clipboard.
preview.page_nextn / PageDownShow the next page of the displayed document.
preview.page_prevp / PageUpShow the previous page of the displayed document.
preview.png.resetr / 0Reset zoom and pan to fit the image in the pane.
preview.png.zoom_inShift+ArrowUp / + / =Enlarge the displayed image. Fit image restores the overview.
preview.png.zoom_outShift+ArrowDown / -Reduce image zoom down to fit-to-pane.
preview.png.pan_leftArrowLeftMove across the zoomed image.
preview.png.pan_rightArrowRightMove across the zoomed image.
preview.png.pan_upArrowUpMove across the zoomed image.
preview.png.pan_downArrowDownMove across the zoomed image.
preview.scalebar.togglePrimary+sToggle the physical scalebar, or enter the pixel size when scale is unknown.
view.return_navEscapeMove focus back to the navigation tree.
preview.capturec / Primary+cCrop the visible image region and attach it to the agent input.
preview.copy_codeyCopy the displayed markdown code blocks to the clipboard.
preview.editeEdit the displayed file or its concept annotation.
view.page_upPageUpScroll back through this pane.
view.page_downPageDownScroll forward through this pane.
preview.upArrowUpMove up through the displayed text.
preview.downArrowDownMove down through the displayed text.
preview.startHomeScroll to the beginning of the displayed text.
preview.endEndScroll to the end of the displayed text.
preview.half_upCtrl+uScroll up half a pane.
preview.half_downCtrl+dScroll down half a pane.
help.upArrowUpPrevious action in the Help drawer.
help.downArrowDownNext action in the Help drawer.
help.page_upPageUpPrevious actions in the Help drawer.
help.page_downPageDownNext actions in the Help drawer.
help.scopeTabThis pane or all panes in the Help drawer.
help.manualEnterOpen manual in the Help drawer.
help.cheatsheetPrimary+pWrite a printable page of every listed action and its loaded shortcuts, and open it in the browser (print or save as PDF there).
help.closeEscapeReturn to work in the Help drawer.
files.confirm_deletey / Shift+yDelete the file named in the confirmation prompt. Any other key cancels.
edit.confirm_discardy / Shift+y / EscapeDiscard unsaved edits and close the editor. Another key returns to editing.
edit.reloadr / Shift+rDiscard this edit buffer and reload the externally changed file.
edit.keepk / Shift+kDismiss the external-change warning and continue editing.
edit.undoCtrl+z / Super+zUndo in the editor.
edit.redoCtrl+y / Super+Shift+zRedo in the editor.
edit.copyCtrl+c / Super+cCopy selection in the editor.
edit.cutCtrl+x / Super+xCut selection in the editor.
edit.pasteCtrl+v / Super+v / Shift+InsertPaste in the editor.
edit.newlineEnterInsert newline in the editor.
edit.backspaceBackspaceDelete previous character in the editor.
edit.deleteDeleteDelete next character in the editor.
edit.leftArrowLeft / Shift+ArrowLeftMove the editor cursor. Hold Shift to extend the selection.
edit.rightArrowRight / Shift+ArrowRightMove the editor cursor. Hold Shift to extend the selection.
edit.upArrowUp / Shift+ArrowUpMove the editor cursor. Hold Shift to extend the selection.
edit.downArrowDown / Shift+ArrowDownMove the editor cursor. Hold Shift to extend the selection.
edit.homeHome / Shift+HomeMove the editor cursor. Hold Shift to extend the selection.
edit.endEnd / Shift+EndMove the editor cursor. Hold Shift to extend the selection.
edit.page_upPageUp / Shift+PageUpMove the editor cursor. Hold Shift to extend the selection.
edit.page_downPageDown / Shift+PageDownMove the editor cursor. Hold Shift to extend the selection.
edit.startCtrl+Home / Shift+Ctrl+HomeMove the editor cursor. Hold Shift to extend the selection.
edit.finishCtrl+End / Shift+Ctrl+EndMove the editor cursor. Hold Shift to extend the selection.
edit.saveCtrl+s / Super+sSave the current file or concept annotation.
input.cancelEscapeCancel the current input. Unsaved edits require confirmation.
input.confirmEnterSubmit the entered filename or value.
repl.interruptCtrl+cInterrupt the evaluation the drawer shows running (again while the same evaluations still run: force it, which can crash the REPL inside C code; starting another evaluation in between makes it an ordinary interrupt again), or clear the input when Julia is idle.
repl.history_prevArrowUpRecall the previous Julia input.
repl.history_nextArrowDownRecall the next Julia input.
picker.parentBackspaceGo to the parent folder in the new-session picker.
repl.submitEnterEvaluate the current Julia input.
repl.newlineShift+EnterContinue the Julia input on another line.

An agentic development environment for Julia. Released under the AGPL-3.0-or-later, with a commercial license on request.