Keybindings
The complete built-in keymap, and how to change it. Bindings are
grouped by context: the terminal deliberately steals nothing, so
every bare key reaches your shell. The third column is the action
id you use in [keymap].
Can't remember a key? cmd-shift-p opens the command
palette: every action, fuzzy-searchable, with its current binding
shown alongside.
How contexts work
Everything terminal-scoped is either modifier-prefixed
(cmd-…) or sequence-led (ctrl-w then a key),
and bound at the root, so no bare keystroke is taken away from the
shell. The file tree, the workspaces panel, and the theme picker are
modeless lists with no text input, so bare letters are free there.
The command palette has a text input, so only arrows and
ctrl-n / ctrl-p move its selection.
Copy mode is the one place in
the terminal where bare keys are legal: nothing typed there reaches
the shell, so it has its own context, terminal_vi.
Configuring
Add a [keymap] table to
config.toml:
keystroke on the left, action id on the right. Anything you don't
mention keeps its default. Changes apply live when you save.
[keymap]
"cmd-shift-p" = "app::palette"
"ctrl-w e" = "pane::equalize"
"cmd-shift-]" = "tab::next"
# Unbind by assigning nothing.
"cmd-d" = ""
[keymap.file_tree] # context-scoped tables
"y" = "tree::refresh"
[keymap.terminal]
"cmd-shift-c" = "terminal::copy"
-
Keystrokes are
modifier-…-key, with
cmd, ctrl, alt,
shift, and fn as modifiers, in any order.
Separate the steps of a chord with a space:
"ctrl-w z". Named keys: up,
down, left, right,
enter, escape, tab,
space, backspace, f1…
-
Contexts. Pairs directly under
[keymap] bind at the root and work everywhere.
Subtables scope a binding: [keymap.terminal],
[keymap.terminal_vi] (copy mode, where bare keys
are allowed), [keymap.file_tree],
[keymap.workspaces], and
[keymap.overlay] (the theme picker and command
palette). A binding in a deeper context wins over the same key at
the root.
-
The shell comes first. A bare key — no
cmd, ctrl, or alt — at the
root or in [keymap.terminal] would hide that key from
whatever you're running, so Oxide refuses it and tells you why.
Use a modifier, or a ctrl-w chord.
-
Mistakes are reported, not ignored. An unknown
action id (with a "did you mean" suggestion), a keystroke that
doesn't parse, or a bare key in the terminal each produce a line
in the error toast in the bottom-right corner. Everything else in
the table still binds.
-
Starting from scratch.
replace_defaults = true under [keymap]
drops the built-in map entirely. Every action Oxide ships after
that is unreachable until you bind it, so prefer overriding.
Application
| cmd-, | open the config file in $EDITOR | app::settings |
| cmd-shift-p | command palette | app::palette |
| cmd-alt-t | theme picker | app::select_theme |
| cmd-q | quit | app::quit |
| cmd-h / alt-cmd-h | hide Oxide / hide others | app::hide / app::hide_others |
| cmd-m | minimize | window::minimize |
| ctrl-cmd-f | toggle full screen | window::toggle_fullscreen |
Terminal
| cmd-c / cmd-v | copy / paste (bracketed) | terminal::copy / terminal::paste |
| cmd-a | select all | terminal::select_all |
| cmd-f | search scrollback — ⏎ older, ⇧⏎ newer, esc closes | terminal::search |
| cmd-alt-r cmd-alt-c cmd-alt-w | search toggles: regex / case-sensitive / whole word (also chips in the bar) | terminal::search_regex / …search_case / …search_word |
| ctrl-w [ / cmd-shift-v | copy mode — vim keys in the scrollback | terminal::copy_mode |
| cmd-k | clear scrollback | terminal::clear_scrollback |
| cmd-↑ / cmd-↓ | jump to previous / next prompt | terminal::prompt_up / terminal::prompt_down |
| cmd-r | command history — ⏎ inserts, ⌘⏎ runs | terminal::history |
| cmd-shift-c | copy the last command's output | terminal::copy_last_output |
| click a gutter tick | scroll to that command | |
| cmd-+ cmd-- cmd-0 | font size up / down / reset | terminal::font_increase / …decrease / …reset |
| cmd-click | open the URL, or the path:line in your editor, under the pointer | |
| cmd-p | fuzzy file finder — ⏎ open, ⌘⏎ insert path, ⌥⏎ reveal | app::file_finder |
| shift + drag | select text even while a program grabs the mouse | |
Tabs & windows
| cmd-t | new tab | tab::new |
| cmd-shift-t | reopen the last closed tab (the last ten are remembered) | tab::reopen |
| ctrl-w , / double-click a tab | rename the tab; an empty name restores the automatic title | tab::rename |
| drag a tab | reorder — drop it on the tab whose place it should take | tab::move_left / tab::move_right (unbound) |
| cmd-n | new window | window::new |
| cmd-1 … cmd-9 | select tab 1–9 | tab::select_1 … tab::select_9 |
| ⌃tab / ⌃⇧tab | next / previous tab | tab::next / tab::previous |
| ⇧⌘] / ⇧⌘[ | next / previous tab | tab::next / tab::previous |
| cmd-w | close the pane; the window with the last one | window::close |
Splits & focus
| ctrl-w v / cmd-d | split right | pane::split_right |
| ctrl-w s / cmd-shift-d | split down | pane::split_down |
| ctrl-w V / ctrl-w S | split left / up | pane::split_left / pane::split_up |
| ctrl-w h j k l | focus the pane in that direction | pane::focus_left / …down / …up / …right |
| cmd-opt-←↓↑→ | focus the pane in that direction | pane::focus_left / …down / …up / …right |
| ctrl-w q | close the focused pane | pane::close |
| ctrl-w < / ctrl-w > | shrink / grow the pane horizontally (4 columns) | pane::narrower / pane::wider |
| ctrl-w - / ctrl-w + | shrink / grow the pane vertically (2 rows) | pane::shorter / pane::taller |
| ctrl-w = | equalise every split in the tab | pane::equalize |
| ctrl-w z | zoom the pane to the full tab; again to restore | pane::zoom |
| ctrl-w b | broadcast typing and pastes to every pane in the tab | pane::broadcast |
| ctrl-w o | close every other pane in the tab (asks when more than one would go) | pane::only |
| ctrl-w x | swap the pane with its neighbour in the split | pane::swap |
| ctrl-w r | set the pane's startup command — run when its pinned workspace is restored | pane::set_startup_command |
| drag a divider | resize the two panes either side of it | |
| ctrl-w w | toggle focus: drawer ↔ terminal | drawer::focus_toggle |
The drawer
| cmd-b | show / hide the drawer | drawer::toggle |
| ctrl-w t / cmd-shift-e | focus the file tree | drawer::focus_tree |
| ctrl-w p | focus the workspaces panel | drawer::focus_workspaces |
| cmd-shift-r | reveal the shell's directory in the tree | drawer::reveal |
| tab | switch between the two panels | drawer::focus_workspaces / drawer::focus_tree |
In the file tree
| j k / ↓ ↑ | move | tree::down / tree::up |
| gg / G | top / bottom | tree::top / tree::bottom |
| ctrl-d / ctrl-u | half page down / up | tree::half_page_down / tree::half_page_up |
| l / h | expand & descend / collapse & ascend | tree::expand / tree::collapse |
| p | select the parent directory | tree::parent |
| enter / o | open a directory, or a file in $EDITOR | tree::open |
| y / Y | insert the path at the prompt, relative / absolute | tree::yank_path / tree::yank_path_absolute |
| cmd-c | copy the path | tree::copy_path |
| cmd-shift-o | reveal in Finder | tree::reveal_in_finder |
| right-click | open, preview markdown (.md files), set as root, insert path, copy path, reveal in Finder | |
| — | cd the shell to the selection without re-rooting (only differs with follow_cwd = false) | tree::cd |
| drag a row onto a pane | insert the path at the prompt | |
| c / - | re-root at the selection / one level up | tree::set_root / tree::root_up |
| / | filter | tree::filter |
| a r d | add / rename / delete to Trash | tree::add / tree::rename / tree::delete |
| I / R | toggle hidden files / refresh | tree::toggle_hidden / tree::refresh |
| esc | dismiss input → clear filter → back to the terminal | tree::escape |
In the workspaces panel
| j k / ↓ ↑ | move | workspace::down / workspace::up |
| enter / o | switch to the workspace | workspace::open |
| a r d | add / rename / delete (y confirms) | workspace::add / workspace::rename / workspace::delete |
| p | pin — persist across restarts | workspace::toggle_persist |
| e | edit every pane's startup command | workspace::edit_startup_commands |
| esc | dismiss input → back to the terminal | workspace::escape |
In the palette, history, file finder, and theme picker
| ↓ ↑ / ctrl-n ctrl-p | move (the theme picker previews as you go) | overlay::next / overlay::prev |
| j k | move — theme picker only; the palette is typing | overlay::next / overlay::prev |
| enter | run the command / apply the theme / insert the history entry | overlay::confirm |
| cmd-enter | in history: run the entry; in the file finder: insert the path | overlay::confirm_alt |
| alt-enter | in the file finder: reveal in the tree | overlay::confirm_reveal |
| esc | close, restoring focus (and the previous theme) | overlay::cancel |
In copy mode
ctrl-w [ turns the scrollback into a vim buffer. These
keys are fixed — they're vim's — but anything else can be bound in
[keymap.terminal_vi], bare keys included, since
nothing typed here reaches the shell.
| h j k l / arrows | move; a count prefix repeats (5j) | |
| w b e / W B E | word motions — punctuation-aware / whitespace-delimited | |
| 0 ^ $ | line start / first non-blank / line end | |
| gg G / H M L | top / bottom of the buffer; top / middle / bottom of the screen | |
| ctrl-d ctrl-u / ctrl-f ctrl-b | half page / full page down and up | |
| % / { } | matching bracket / paragraph | |
| / ? then n N | search forward / backward from the cursor, repeat — the same bar and toggles as cmd-f; ⏎ parks the cursor on the match | |
| v V ctrl-v | character / line / block selection; motions extend it | |
| y / yy / ⏎ | yank the selection (or the line) to the clipboard and leave | |
| esc / q | clear the selection, then leave; ctrl-w [ also toggles out | terminal::copy_mode |
These have no default binding, but every one is in the command
palette and can be bound in [keymap]:
| Window → Move Tab Left / Right | reorder without the mouse | tab::move_left / tab::move_right |
| Edit → Copy Last Command | the last command line | terminal::copy_last_command |
| Edit → Copy Last Command and Output | both together, for an issue | terminal::copy_last_block |
| View → Toggle Status Bar | show or hide the bar for this window | app::toggle_status_bar |
| File → New Workspace | create an unnamed workspace | workspace::new |
| Oxide → Check for Updates… | check GitHub for a newer release | app::check_for_updates |
| Oxide → About Oxide | open the project page | app::about |
| Window → Zoom | zoom the window | window::zoom |
| Help → Oxide Help / Report an Issue | open the docs / a new issue | app::help / app::report_issue |
| Help → What's New | open the changelog in a new tab | app::changelog |