Configuration
One TOML file at ~/.config/oxide/config.toml. Every key
has a default, so a three-line config is a perfectly good config.
The file
A fully commented default is written on first run. Open it from
inside Oxide with cmd-,
(Oxide → Settings…), which opens it with your
$EDITOR in the focused pane — without echoing a command
line at the prompt.
Set the OXIDE_CONFIG environment variable to point
somewhere else — useful for keeping the file in a dotfiles repo:
OXIDE_CONFIG=~/dotfiles/oxide.toml open -a Oxide
Reloading
Oxide watches the file's directory (editors write-and-rename, so watching the file alone misses saves) and reloads on change.
-
Live:
[font],[colors],[window],[cursor],[tree],[status_bar],[keymap],[notifications],[ssh],[workspaces],shell.scrollback,bell,copy_on_select. Save the file and the window repaints. -
New sessions only: the rest of
[shell],[prompt], andcommands.emit_cmdline— they're baked into a shell's environment and init script when it starts. Open a new tab to pick them up.
When it doesn't parse
A malformed file never takes the app down. Oxide keeps running with the configuration it already had and shows the first line of the parse error as a red toast in the bottom-right corner. Fix the file, save, and the toast clears. Click it to hide it early; it comes back on the next reload if the file is still broken.
Unknown keys are an error rather than a shrug — a typo'd
show_hiden tells you so instead of silently doing
nothing. An unrecognised color preset is reported the same way, with
the list of valid names. Bad [keymap] entries are
listed in the toast too, one per line, while the rest of the map
still binds.
Top level
| Key | Type | Default | Description |
|---|---|---|---|
| bell | string | "none" |
"none", "sound" (the system beep),
or "visual" (a brief flash of the pane).
|
| copy_on_select | bool | false | Copy to the system clipboard as soon as a mouse selection ends. |
[font]
| Key | Type | Default | Description |
|---|---|---|---|
| family | string or array | "JetBrainsMono Nerd Font Mono" |
Any installed monospace family. The default is bundled into
the binary, so it works with nothing installed. A list
names fallbacks: the first entry is the terminal font, the
rest are tried in order for glyphs it lacks —
["JetBrainsMono Nerd Font Mono", "Apple Color Emoji", "PingFang SC"]
avoids tofu for emoji and CJK.
|
| size | float | 14.0 | Points. cmd-+/cmd-- adjust at runtime without writing back here. |
| line_height | float | 1.25 | Multiple of the font size. |
| weight | string | "normal" | "normal", "medium", or "bold". |
| ligatures | bool | false | Enable programming ligatures, if the family has them. |
[window]
| Key | Type | Default | Description |
|---|---|---|---|
| padding | table | { x = 12, y = 8 } | Pixels between the terminal grid and the window edge. |
| opacity | float | 1.0 | 0.0–1.0; below 1.0 makes the background translucent. |
| blur | bool | false | Blur what's behind a translucent window. |
| titlebar | string | "hidden" |
"hidden" gives the tab bar the whole top edge;
"native" keeps the standard macOS title bar.
|
| new_tab_directory | string | "pwd" |
Where cmd-t starts — "pwd" inherits
the current pane's directory, "home" always
opens at ~/.
|
| inactive_pane_opacity | float | 1.0 | Fade every pane except the active one to this (0.05–1.0; 0.7 or so is typical). Only applies when the tab has more than one pane, and never while zoomed. See dimming. |
| inactive_window_opacity | float | 1.0 | Fade the whole window while another app is frontmost. |
[cursor]
The shape the shell starts with. Programs that set their own with
DECSCUSR (\e[<n> q — vim per mode, for one) win
until they reset it. Blinking pauses while you type.
| Key | Type | Default | Description |
|---|---|---|---|
| style | string | "block" | "block", "bar", or "underline". |
| blink | bool | true | Blink in the focused pane. |
| blink_interval | integer | 530 | Milliseconds per half-cycle (100–5000). |
| unfocused | string | "hollow" |
The cursor in a pane that isn't focused:
"hollow" (an outline), "solid"
(the same shape, not blinking), or "hidden".
|
| thickness | float | 0.15 | Width of a bar and height of an underline, as a fraction of a cell. |
[shell]
| Key | Type | Default | Description |
|---|---|---|---|
| program | string | unset |
The shell to launch. Unset means $SHELL, falling
back to /bin/zsh.
|
| args | array | ["-l"] |
Arguments for the shell. Under bash with integration on,
-l is replaced by --init-file, which
emulates the login chain itself.
|
| scrollback | integer | 10000 | Lines of history kept per pane. Applies live, to every pane. |
| option_as_meta | string | "none" |
Send Option as Meta (ESC-prefixed).
"none", "left",
"right", or "both" — macOS can't
distinguish the two Option keys, so
"left" and "right" currently behave
like "both".
|
| integration | bool | true |
Install the OSC 133 hooks and the silent-cd
widget. Independent of
prompt styling.
|
[tree]
| Key | Type | Default | Description |
|---|---|---|---|
| width | float | 280 | Drawer width in pixels. |
| show_hidden | bool | false | Show dotfiles. I toggles this for the running session. |
| respect_gitignore | bool | true | Hide anything the repo's ignore rules cover. |
| indent | float | 16 | Pixels of indent per nesting level. |
| icons | bool | true | Nerd Font file-type icons in the drawer. |
| follow_cwd | bool | true | Re-root the tree when the focused shell changes directory. |
| git_status | bool | true | Colour rows by git state, rolled up onto collapsed directories. |
[editor]
How cmd-click on a path:line opens your
editor. Oxide maps the line-number flag for vim/nvim, VS Code and
friends, emacs, Sublime, and Helix on its own; set this for
anything else.
| Key | Type | Default | Description |
|---|---|---|---|
| open_at_line | string | — |
A shell command with {path},
{line}, and {col} substituted
(the path arrives quoted; a missing column is 1), e.g.
"myeditor --line {line} {path}". Overrides the
built-in mapping.
|
[status_bar]
| Key | Type | Default | Description |
|---|---|---|---|
| enabled | bool | true | The native bar with workspace, directory, and git state. View → Toggle Status Bar overrides it for the current window. |
| position | string | "bottom" | "top" or "bottom". |
[colors]
A preset supplies all twenty colors; any individual key you set
overrides the preset. Values are #rgb or
#rrggbb hex.
[colors] preset = "oxide" background = "#0d0b0a" # override just this one # ...or let macOS pick between two: follow_system = true preset_dark = "catppuccin-mocha" preset_light = "catppuccin-latte"
| Key | Description |
|---|---|
| preset |
One of the eight built-in
themes. Unset means
catppuccin-mocha.
|
| follow_system |
Switch with the macOS appearance: dark uses
preset_dark, light uses
preset_light, each falling back to
preset (and with nothing else set, light falls
back to catppuccin-latte). Overrides below
apply on top of whichever is active. Off by default.
|
| preset_dark, preset_light | The two variants follow_system chooses between. |
| background, foreground, cursor, selection_bg | The four UI colors. |
| selection_fg |
Text inside a selection. Unset keeps each cell's own
colour over selection_bg.
|
| black, red, green, yellow, blue, magenta, cyan, white | ANSI 0–7. |
| bright_black … bright_white | ANSI 8–15. |
Picking a theme with cmd-alt-t rewrites the
whole [colors] block to just
preset = "…", dropping individual overrides — they'd
defeat the theme you just chose. Keep hand-tuned colors out of the
picker's way, or re-add them after switching. With
follow_system on, the picker only sets the variant
for the current appearance and keeps the rest.
[ssh]
Accents for panes whose foreground process is ssh:
the pane's border and the status bar's ssh: host chip
take the colour while the connection lasts. An array of tables;
the first pattern that matches wins. See
SSH awareness.
[[ssh.hosts]] match = "*.prod.example.com" accent = "#f38ba8"
| Key | Type | Default | Description |
|---|---|---|---|
| hosts[].match | string | required |
A glob over the host as typed on the command line, after
any user@: * matches any run,
? one character; case-insensitive.
|
| hosts[].accent | string | required | A hex colour. |
[prompt]
Covered in full on Prompt & shell integration. In short:
| Key | Type | Default | Description |
|---|---|---|---|
| enabled | bool | true | Build and set the prompt. False keeps your own. |
| separator | string | "\ue0b0" | Drawn between segments (the powerline right arrow). |
| end | string | "\ue0b0" | Drawn after the last segment; empty falls back to separator. |
| newline_before_input | bool | false | Put the cursor on its own line below the segments. |
| segments | array of tables | cwd, git, exit_status | The segments, in render order. |
[[prompt.segments]]
| Key | Type | Default | Description |
|---|---|---|---|
| kind | string | "text" |
cwd, git,
exit_status, time,
user, host,
duration, text, or
env.
|
| fg / bg | string | unset | Hex colors for this segment. |
| bold | bool | false | Bold the segment's text. |
| options | table | {} |
Per-kind settings: style,
max_len, show_dirty,
dirty_bg, ahead_behind,
hide_on_success, format,
text, var. See
segment kinds.
|
[notifications]
Desktop notifications when a command finishes in a pane you aren't
watching. From the installed app these are real macOS
notifications (you'll be asked to allow them once), and clicking
one focuses the pane; a cargo run build has no bundle
to attach them to and falls back to osascript, which
can't route a click.
| Key | Type | Default | Description |
|---|---|---|---|
| enabled | bool | true | Master switch. |
| min_duration | string | "30s" | Commands shorter than this never notify. "2m", "1.5s", "250ms", or a bare number of seconds. |
| only_when_unfocused | bool | true | Stay quiet when the pane is focused and the window is active — you saw it finish. |
| on_failure_always | bool | false | A non-zero exit notifies however short the command was. |
| passthrough_osc9 | bool | true | Let programs post notifications themselves with OSC 9 / OSC 777, rate-limited per pane. |
[commands]
The per-pane command log built from the shell integration's OSC 133
markers — what feeds the status bar, tab dots,
history search,
and the gutter. Needs shell.integration = true and zsh
or bash.
| Key | Type | Default | Description |
|---|---|---|---|
| track | bool | true | Keep the log at all. Off means no history, no indicators, no gutter. |
| emit_cmdline | bool | true | The shell sends each command line to Oxide alongside the start marker, so history and notifications can name the command. Kept in memory only, never written to disk. Applies to new sessions. |
| max_entries | int | 500 | Commands remembered per pane. |
[workspaces]
How pinned workspaces restore their startup commands.
| Key | Type | Default | Description |
|---|---|---|---|
| run_startup_commands | bool | true | Re-run each pane's saved startup command when a pinned workspace is restored, and when a closed tab is reopened. Off restores the layout only. For a single launch, --no-startup-commands or shift held at launch does the same. |
| startup_timeout | string | "5s" | How long to wait for a pane's shell to show its first prompt before giving up on that pane's command. Same duration syntax as notifications.min_duration. |
[keymap]
Keystroke on the left, action id on the right. Pairs directly under
[keymap] bind everywhere; the subtables scope a binding
to one context. An empty string unbinds a default. The full list of
action ids and the rules for what's allowed where are on the
keybindings page.
[keymap] "cmd-shift-p" = "app::palette" "cmd-d" = "" # unbind [keymap.file_tree] "y" = "tree::refresh"
| Key | Type | Default | Description |
|---|---|---|---|
| replace_defaults | bool | false | Start from an empty map instead of merging over the built-in one. Rarely what you want: every action that has no entry becomes unreachable. |
| root / terminal / terminal_vi / file_tree / workspaces / overlay | table | {} |
Context-scoped bindings. [keymap.root] is the
same as writing the pairs directly under
[keymap]. A bare key (no cmd,
ctrl, or alt) is rejected in
root and terminal — it would be
stolen from your shell. terminal_vi is copy
mode, where bare keys are fine.
|
The generated default
This is what lands in config.toml on first run.
# Oxide configuration. # This file was generated on first run; every value shown is the default. # Font and color changes apply live; [shell] and [prompt] changes apply to # newly started sessions. [font] family = "JetBrainsMono Nerd Font Mono" # or a list: the rest are fallbacks for CJK/emoji, # e.g. ["JetBrainsMono Nerd Font Mono", "Apple Color Emoji"] size = 14.0 line_height = 1.25 weight = "normal" # normal | medium | bold ligatures = false [window] padding = { x = 12, y = 8 } opacity = 1.0 # 0.0 - 1.0; < 1.0 makes the background translucent blur = false # blur what's behind a translucent window titlebar = "hidden" # native | hidden new_tab_directory = "pwd" # pwd | home — where cmd-t starts inactive_pane_opacity = 1.0 # dim the panes you aren't in (0.5–0.9 typical) inactive_window_opacity = 1.0 # dim the whole window when another app is active [cursor] style = "block" # block | bar | underline (programs can override via DECSCUSR) blink = true blink_interval = 530 # ms per half-cycle unfocused = "hollow" # hollow | solid | hidden — the cursor in an unfocused pane thickness = 0.15 # bar width / underline height, as a fraction of a cell [shell] # program = "/bin/zsh" # default: $SHELL args = ["-l"] scrollback = 10000 option_as_meta = "none" # none | left | right | both # (left/right currently behave like "both") integration = true # OSC 133 markers + silent cd from the file tree. # Independent of [prompt]: keep your own prompt # (starship, p10k) and still get integration. [tree] width = 280 show_hidden = false respect_gitignore = true indent = 16 icons = true # nerd-font icons in the drawer follow_cwd = true # re-root the tree when the shell cd's git_status = true # colour rows by git state (modified, added, untracked…) # [editor] # open_at_line = "myeditor --line {line} {path}" # for editors Oxide doesn't know # bell = "none" # none | sound | visual # copy_on_select = false # mouse selection copies to clipboard on release [status_bar] enabled = true # native bar showing cwd + git branch/dirty position = "bottom" # top | bottom [notifications] enabled = true # notify when a command finishes in a pane you aren't watching min_duration = "30s" # ...if it ran at least this long ("2m", "1.5s", or seconds) only_when_unfocused = true # stay quiet when the pane is focused and the window active on_failure_always = false # a non-zero exit notifies regardless of duration passthrough_osc9 = true # let programs post notifications (OSC 9 / OSC 777) [commands] track = true # the command log: status bar, tab dots, cmd-r history, gutter emit_cmdline = true # the shell sends each command line to Oxide (memory only) max_entries = 500 [workspaces] run_startup_commands = true # re-run each pane's saved startup command when a pinned # workspace is restored (skip once: --no-startup-commands, # or hold shift while Oxide launches) startup_timeout = "5s" # give up on a pane's command if its shell isn't ready by then # [keymap] # keystroke = "action id"; see the keybindings page # "cmd-shift-p" = "app::palette" # "cmd-d" = "" # unbind a default # [[ssh.hosts]] # colour a pane's border while ssh'd into a matching host # match = "*.prod.example.com" # accent = "#f38ba8" [colors] # Presets: catppuccin-mocha | catppuccin-latte | gruvbox-dark | tokyonight # | dracula | nord | solarized-dark | oxide # | ethereal | everforest | flexoki-light | hackerman | kanagawa # | last-horizon | lumon | lupine | matte-black | miasma | osaka-jade # | retro-82 | ristretto | rose-pine-dawn | solitude | vantablack | white preset = "catppuccin-mocha" # Follow the macOS appearance instead, switching between two presets: # follow_system = true # preset_dark = "catppuccin-mocha" # preset_light = "catppuccin-latte" # Any color can override the preset individually: # background = "#11111b" # foreground = "#cdd6f4" # cursor = "#f5e0dc" # selection_bg = "#414458" # selection_fg = "#cdd6f4" # text inside a selection; unset keeps each cell's colour # black / red / green / yellow / blue / magenta / cyan / white # bright_black / bright_red / ... / bright_white # The prompt is compiled into a zsh init script and injected via ZDOTDIR. # Your own ~/.zshrc is sourced first; only PROMPT is overridden. # Requires zsh (the macOS default shell); other shells keep their own prompt. [prompt] enabled = true separator = "\ue0b0" # powerline right arrow end = "\ue0b0" newline_before_input = false # Segment kinds: cwd | git | exit_status | time | user | host | duration # | text (options.text) | env (options.var) [[prompt.segments]] kind = "cwd" fg = "#11111b" bg = "#89b4fa" bold = true options = { style = "truncate_to_repo", max_len = 40 } # full | truncate_to_repo | basename [[prompt.segments]] kind = "git" fg = "#11111b" bg = "#a6e3a1" options = { show_dirty = true, dirty_bg = "#f9e2af", ahead_behind = true } [[prompt.segments]] kind = "exit_status" fg = "#11111b" bg = "#f38ba8" options = { hide_on_success = true } # [[prompt.segments]] # kind = "time" # options = { format = "%H:%M" } # [[prompt.segments]] # kind = "duration"
The separator and end values in the real
file are literal powerline glyphs (U+E0B0), written here as the
equivalent TOML escape so they stay readable without a Nerd Font
installed.