Reference

Keyboard shortcuts

Every default key in Tooee, with its command id and its mode.

This page lists every default key in Tooee with the id of its command. Keyboard basics teaches the common keys. To give a command another key, put its id in keys, as Configuration shows.

Each key is written in the hotkey grammar that keys accepts. Letter case does not matter, so escape and Escape are the same key. shift+g is G, and g g is a sequence: press g twice. A command with the key "none" has no default key. Run it from the : palette, or give it a key in keys.

Every app

TooeeProvider registers these commands, so every app started with launchCli or runCliSession has them.

KeyIdModeAction
:command-palettecursor, selectOpen the command palette
ctrl+shift+jtoggle-debug-consolecursorToggle the OpenTUI debug console
escapeoverlay.close-topanyClose the top overlay. A modal overlay with commands of its own gets overlay.close-self instead.
ctrl+cno idanyEnd the process. exitOnCtrlC: false on the session turns it off.

The apps add two more. View, Ask, Choose, and DocumentScreen register both through useThemeCommands and useQuitCommand.

KeyIdModeAction
tcycle-themecursorOpen the theme picker
qquitcursorQuit. In Ask and Choose, cancel the prompt.

Documents

Every document from useDocumentController has these keys, and View is one. copy: false on the controller drops the two copy commands.

KeyIdModeAction
jcursor-downcursorCursor down
kcursor-upcursorCursor up
ctrl+dcursor-half-downcursorHalf a page down
ctrl+ucursor-half-upcursorHalf a page up
g gcursor-topcursorFirst row
shift+gcursor-bottomcursorLast row
venter-selectcursorStart a selection and switch to select mode
jselect-downselectExtend the selection down
kselect-upselectExtend the selection up
escapeselect-cancelselectCancel the selection and return to cursor mode
y ycopy-linecursor, selectCopy the cursor row
y vcopy-selectioncursor, selectCopy the selection or the toggled rows, then return to cursor mode

With multiSelect on, a document also toggles rows:

KeyIdModeAction
tabcursor-togglecursorToggle the cursor row
shift+tabcursor-toggle-upcursorToggle the cursor row and move up
tabselect-toggleselectToggle the cursor row

Every document has these keys unless its controller has search: false. enter in the search bar runs the search. That key belongs to the input and has no id.

KeyIdModeAction
/cursor-search-startcursorOpen the search bar and switch to insert mode
ncursor-search-nextcursorNext match
shift+ncursor-search-prevcursorPrevious match
escapesearch-cancelany, while the search bar is openClose the search bar, clear the query, and return to the previous mode

View and Markdown

View adds these keys to the document keys. The fold.*, outline.toggle, and block-scroll-* commands exist only while View shows Markdown.

KeyIdModeAction
y gcopycursor, selectCopy the whole document
shift+ltoggle-line-numberscursorShow or hide line numbers
enterview.follow-linkcursorFollow the Markdown link on the cursor line. Several links open a chooser.
backspacerouter.backcursorReturn to the previous file after a link
g ooutline.togglecursorOpen the heading outline and move into it, or close it from inside
z afold.togglecursorOpen or close the fold at the cursor
z cfold.closecursorClose the fold at the cursor
z ofold.opencursorOpen the fold at the cursor
z zfold.toggle-blockcursorOpen the fold at the cursor when it is closed, else close it
z shift+mfold.close-allcursorClose all folds
z shift+rfold.open-allcursorOpen all folds
hblock-scroll-leftcursor, on a wide code blockScroll the code block left
lblock-scroll-rightcursor, on a wide code blockScroll the code block right

view.follow-link and router.back come from launch() in @tooee/view and from tooee view with a file or stdin. A View that you mount yourself does not register them. View describes links, folds, and the outline.

Outline

These keys work while the outline panel has the focus.

KeyIdModeAction
j, downoutline.down, outline.down-arrowcursorNext heading
k, upoutline.up, outline.up-arrowcursorPrevious heading
g goutline.firstcursorFirst heading
shift+goutline.lastcursorLast heading
enteroutline.jumpcursorMove the document cursor to the heading and return to the document
escapeoutline.focus-contentcursorReturn to the document and keep the outline open
g ooutline.closecursorClose the outline
z a, z c, z o, z z, z shift+m, z shift+routline.fold.toggle, outline.fold.close, outline.fold.open, outline.fold.toggle-block, outline.fold.close-all, outline.fold.open-allcursorThe fold commands, for the selected heading

The outline is a panel with switchKeys={null}, so panels.next and panels.previous do not apply to it.

Diffs

KeyIdModeAction
sdiff.toggle-layoutcursor, selectSwitch between split and unified layout
wdiff.toggle-wrapcursor, selectToggle line wrapping
]diff.next-filecursor, selectNext file
[diff.prev-filecursor, selectPrevious file
fdiff.file-pickercursor, selectOpen the file picker
hdiff.scroll-leftcursor, wrapping offPan left
ldiff.scroll-rightcursor, wrapping offPan right

View: diffs explains layout and wrapping.

Directory view

tooee view <directory> and launch() with dirPath add these keys.

KeyIdModeAction
g ndir.next-filecursorNext file
g pdir.prev-filecursorPrevious file

Each file opens in View, so h and l scroll a wide code block or an unwrapped diff. To move between files with l and h and give up those scroll keys, set "dir.next-file": "l" and "dir.prev-file": "h" in keys.

Ask

The Ask app starts in insert mode. Its editor ids start with ask:. An Ask dialog from useAskDialog has the same keys, with ids that start with ask-overlay:.

KeyIdModeAction
escapeask:leave-insert-modeinsertSwitch to cursor mode
enterask:submit-insertinsertSubmit. Single-line editor only.
shift+enterask:submit-multilineinsert, cursorSubmit
enterask:submit-cursorcursorSubmit
iask:insert-mode-icursorInsert at the text cursor
aask:insert-mode-acursorInsert after the text cursor
oask:open-line-belowcursorOpen a line below. Multiline editor only.
shift+oask:open-line-abovecursorOpen a line above. Multiline editor only.
h, leftask:move-left, ask:move-left-arrowcursorMove left
l, rightask:move-right, ask:move-right-arrowcursorMove right
j, downask:move-down, ask:move-down-arrowcursorMove down
k, upask:move-up, ask:move-up-arrowcursorMove up
0, homeask:line-home, ask:line-home-keycursorStart of the line
shift+4 ($), endask:line-end, ask:line-end-keycursorEnd of the line
wask:word-forwardcursorNext word
bask:word-backwardcursorPrevious word
g gask:buffer-homecursorStart of the text
shift+gask:buffer-endcursorEnd of the text
y yask:copy-linecursorCopy the line at the text cursor
y gask:copy-documentcursorCopy the whole text
y vask:copy-selectioncursorCopy the text selected with the mouse
qask:cancelcursorCancel. Only when the editor has an onCancel, as the dialog does.
ppaste-clipboardcursorPaste from the clipboard
nonepaste-primarycursorPaste from the primary selection. The palette lists it as "Paste from selection".

paste-clipboard and paste-primary belong to the Ask app. The dialog does not have them. The Ask app cancels with q through quit, from the table in Every app. submitKey: "none" on useAskEditor turns off the three submit commands.

Choose

The Choose app starts in insert mode with the filter focused. Its ids start with choose:. A Choose dialog from useChooseDialog has the same keys, with ids that start with choose-overlay:.

KeyIdModeAction
escapechoose:escapeinsert, cursorIn insert mode, switch to cursor mode. In cursor mode, cancel.
enterchoose:confirminsert, cursorConfirm
up, ctrl+pchoose:move-up, choose:move-up-ctrl-pinsert, cursorMove up
down, ctrl+nchoose:move-down, choose:move-down-ctrl-ninsert, cursorMove down
tabchoose:toggle-nextinsert, cursorToggle the item and move down. Multi-select only.
shift+tabchoose:toggle-previousinsert, cursorToggle the item and move up. Multi-select only.
jchoose:move-down-vimcursorMove down
kchoose:move-up-vimcursorMove up
ichoose:insert-mode-icursorReturn to the filter
achoose:insert-mode-acursorReturn to the filter
qchoose:cancelcursorCancel

In the Choose app, quit also has q and also cancels. Give both ids a new key to move cancel off q.

Command palette

: opens the palette. It lists the visible commands of the current mode with the keys that run them, so a remap from keys shows. It leaves out a command whose when returns false when the palette opens. Hidden commands do not show, and every id with a colon on this page is hidden. The palette opens in insert mode with the filter focused, and its ids start with command-palette:.

KeyIdAction
entercommand-palette:confirmRun the highlighted command
escapecommand-palette:escapeClose the palette
up, ctrl+pcommand-palette:move-up, command-palette:move-up-ctrl-pMove up
down, ctrl+ncommand-palette:move-down, command-palette:move-down-ctrl-nMove down

The palette and the pickers below use the Choose commands with escape set to close. The other chooser commands need cursor mode or multi-select. The palette has neither, because escape closes it before it can reach cursor mode.

Pickers

PickerOpened byId prefix
Theme pickert (cycle-theme)theme-picker:
Diff file pickerf (diff.file-picker)command-palette:
Link chooserenter (view.follow-link) on a line with several linkschoose-overlay:

The theme picker and the diff file picker have the palette keys: enter, escape, up, down, ctrl+p, and ctrl+n. In the theme picker the ids are theme-picker:confirm, theme-picker:escape, and so on. The link chooser is a Choose dialog and has the keys from Choose.

Overlays

overlay.close-top closes the top overlay on escape, as Every app lists. It works for overlays opened without ownCommands and for passive ones. It skips an overlay opened with dismissOnEscape: false. A modal overlay with ownCommands takes every key, so the shell registers the hidden overlay.close-self command on the overlay's own surface. It binds escape in insert, cursor, and select mode, unless the overlay sets dismissOnEscape: false. An escape command that the overlay registers itself runs first. The palette, the pickers, and the dialogs on this page register their own. Overlays, dialogs, and toasts explains the two kinds.

Context menus

A context menu from useContextMenu switches the app to insert mode while it is open. Its commands register on the app surface.

KeyIdModeAction
upcontext-menu:move-upinsert, cursorMove up
kcontext-menu:move-up-viminsert, cursorMove up
downcontext-menu:move-downinsert, cursorMove down
jcontext-menu:move-down-viminsert, cursorMove down
entercontext-menu:selectinsert, cursorRun the highlighted entry
escapeoverlay.close-topinsert, cursorClose the menu

Panels

Each panel in a PanelGroup registers these commands on its own surface. They run while that panel is active.

KeyIdModeAction
tabpanels.nextcursor, selectActivate the next panel
shift+tabpanels.previouscursor, selectActivate the previous panel

switchKeys on the group sets other keys, and switchKeys={null} removes both commands. switchModes sets the modes. Panels lists the group props.

Router

KeyIdModeAction
backspacerouter.backcursorGo back one screen, while canGoBack() is true

useRouterCommands() registers it on the current surface. Routing covers the router.

Next

On this page