Terminal & scrollback
The emulation itself is Alacritty's — Oxide adds selection, search, prompt jumping, and the surrounding chrome.
What's emulated
VT parsing and the terminal grid come from
alacritty_terminal, so compatibility is Alacritty's:
- 24-bit truecolor, plus the 256-color and 16-color palettes
- Wide glyphs (CJK, emoji) and combining marks
- Alternate screen, with scrollback preserved underneath
- Bracketed paste
- SGR mouse reporting, including drag and motion modes
- OSC 8 hyperlinks and OSC 52 clipboard access
- OSC 7 working-directory reports and OSC 133 semantic prompts
vim, htop, tmux, fzf, and full-screen TUIs behave normally.
Selection and clipboard
| click and drag | select a range |
| double-click | select the word under the cursor (semantic) |
| triple-click | select the whole line |
| cmd-c | copy the selection |
| cmd-v | paste, bracketed when the program asks for it |
| cmd-a | select the whole buffer |
Set copy_on_select = true to copy to the system
clipboard the moment you release the mouse, X11-style.
Scrollback
Scroll with the wheel or trackpad. The buffer holds
shell.scrollback lines — 10,000 by default. While a
program has the alternate screen (vim, less), scrolling is forwarded
to it instead.
While you're scrolled up, a small ▲ 2,340 lines above
pill in the pane's corner says how far back you are; it goes away
at the bottom. cmd-k (View → Clear
Scrollback) empties the history for the focused pane.
Searching the scrollback
cmd-f opens a search bar in the focused pane. Search is live: results update as you type, and the view jumps to the nearest match behind you. Three chips on the right of the bar change what a query means; click one, or use its key while the bar is open. They stay set for the pane until you change them.
.* / cmd-alt-r |
treat the query as a regular expression (Rust regex syntax) instead of literal text |
Aa / cmd-alt-c |
case-sensitive; off, error also finds Error |
ab| / cmd-alt-w |
whole words only, so err skips stderr |
| ⏎ | next match, further back in history |
| ⇧⏎ | previous match, back toward the bottom |
| backspace | edit the query; on an empty query, closes search |
| esc / cmd-f | close |
The bar itself tells you where you stand: it reads
type to search on an empty query,
⏎ older ⇧⏎ newer esc once there's a hit, and outlines
itself in red with no match when there isn't one — or
invalid pattern when the regex toggle is on and the
query doesn't compile yet (an unclosed (, say).
Copy mode
ctrl-w [ (or cmd-shift-v,
Edit → Copy Mode) turns the scrollback into a
vim buffer: a yellow block cursor appears, a
-- COPY -- badge sits in the pane's corner, and
nothing you type reaches the shell until you leave. It's the last
reason a vim user keeps tmux around, so the vocabulary is tmux's
copy mode and vim's normal mode:
- h j k l and the arrows move; w b e by word (W B E by whitespace), 0 ^ $ within the line, gg and G to either end of the buffer, H M L on the screen, % to the matching bracket, { } by paragraph, ctrl-d / ctrl-u half a page and ctrl-f / ctrl-b a full one. A count prefix repeats: 5j, 3w. The badge shows the pending count.
- / searches forward from the cursor and ? backward, in the same bar — with the same chips — as cmd-f. ⏎ parks the cursor on the match and closes the bar; n and N repeat, forward and back.
-
v starts a character selection, V a
line-wise one, ctrl-v a block; motions extend it and
the badge switches to
VISUAL,V-LINE, orV-BLOCK. Pressing the same key again, or esc, drops it. A click moves the cursor too. - y (or ⏎) yanks the selection to the clipboard and leaves; yy yanks the cursor's line. esc with nothing selected, q, or ctrl-w [ again leave without copying. Leaving snaps back to the live screen.
Copy mode is refused while a full-screen program has the terminal
(vim, less, htop): there's no scrollback there, and those programs
have their own idea of what j means. The status bar
shows the mode as well, so it's visible even with a small pane. To
add bindings of your own inside the mode, use
[keymap.terminal_vi] — bare keys are allowed there.
Commands: what ran, and how it went
With shell integration on (zsh or bash), Oxide's prompt hooks emit OSC 133 markers around every command, and Oxide reads them straight off the PTY — so it knows when a command starts, when it finishes, its exit status, how long it took, and exactly which rows of scrollback it wrote. Everything below follows from that.
-
Status bar. While a command runs the focused
pane shows
⟳ cargo build 1m02s, ticking. Once it's done, a failure stays up as✗ 1 · 4.2s; success is silent, like the prompt's exit segment. - Tab dots. A tab gets an accent dot while any of its panes is running something, a red dot when the last command in it failed, and a dim dot when a background tab has produced output you haven't looked at.
- Focus ring. When a command fails in a pane you aren't focused on, that pane's ring flashes red for a moment so the eye lands on the right split.
-
Notifications. A command that ran longer than
notifications.min_duration(30 seconds by default) and finished while its pane wasn't focused, or the window wasn't active, posts a desktop notification:✓ cargo build — 2m14sor✗ npm test — exit 1 · 4.2s. Clicking it brings that pane to the front. See [notifications]. - The gutter. A tick per command down the right edge of the pane, placed by where it sits in the scrollback: dim for success, red for failure, accent while running. Click a tick to jump there — scroll past an error in a long build, glance at the gutter, click the red one.
- Copy actions. cmd-shift-c copies the last command's output. The Edit menu (and the palette) also offer the last command itself, and command plus output together for pasting into an issue.
Programs that post their own notifications with OSC 9 or OSC 777
(ntfy-style tools) work too, rate-limited to one every
few seconds per pane; notifications.passthrough_osc9
turns that off.
Command history
cmd-r opens a history search over every command Oxide
has seen run, across all panes and tabs — newest first, fuzzy
filtered as you type, each with the directory it ran in and
whether it failed. Commands from your current directory rank
first. enter inserts the command at the prompt;
cmd-enter runs it straight away through the silent-run
channel, so it lands in shell history once. The log lives in
memory only and is never written to disk; turn
commands.emit_cmdline off if you'd rather the shell
didn't send the text at all.
Rows are tracked in absolute scrollback coordinates, so once the scrollback fills and old lines fall off, or the grid reflows on a resize, older ticks and copy ranges drift. The log itself keeps working.
Prompt jumping
cmd-↑ and cmd-↓ scroll to the previous and next shell prompt in the scrollback, so you can walk back over long build output a command at a time. cmd-↓ past the last mark returns you to the bottom.
The marks are recorded locally: every time you press enter outside the alternate screen, Oxide notes that row as a completed prompt line, keeping the most recent 500. That means jumping works in any shell, with or without shell integration, and needs nothing from your prompt.
File links
Hold cmd and the token under the pointer underlines if
it's something Oxide can open; click to open it.
src/main.rs:42:8 from cargo,
path:42: from grep -n, or
at foo.rs:88 in a stack trace all open the file in
$EDITOR at that line. A directory points the tree
there instead.
Relative paths are tried against the pane's directory, then the
repository root (tools print repo-relative paths from
subdirectories), then the tree's root; absolute and
~ paths are taken as they are. Nothing searches the
tree for a bare file name — opening the wrong mod.rs
is worse than opening nothing.
The line-number flag isn't universal, so the shell picks the form
from $EDITOR's name: +42 for vim and
nvim, --goto path:42:8 for VS Code, Cursor, and Zed,
+42:8 for emacs, path:42:8 for Sublime
and Helix. Anything else gets the file without a line, unless
[editor]
says how.
URLs
cmd-click opens a URL in your browser. An explicit OSC 8 hyperlink wins; failing that, Oxide takes the whitespace-delimited token under the pointer and opens it if it looks like a URL.
SSH awareness
Oxide watches each pane's foreground process (the same
tcgetpgrp lookup that follows cd). When it
is ssh, the destination host — parsed from the command
line, so it works with no cooperation from the remote side — shows
as ssh: prod-web-01 in the status bar, and the tab is
titled ssh prod-web-01. "Am I on prod?" is a question
people answer wrong; to make the answer unmissable, give a host
pattern an accent and the pane's border takes that colour for as
long as the connection lasts:
[[ssh.hosts]] match = "*.prod.example.com" # glob: * and ?, case-insensitive accent = "#f38ba8" [[ssh.hosts]] match = "bastion-*" accent = "#f9e2af"
The first matching pattern wins. The match is against the host as
you typed it, after any user@, so alias names from
~/.ssh/config match as aliases. The same lookup names
the tab after whatever is running (vim,
cargo, psql) rather than the directory,
which is usually the more useful label.
The cursor
The [cursor] section picks the shape
(block, bar, or underline),
whether it blinks and how fast, how thick a bar or underline is,
and what an unfocused pane's cursor looks like
(hollow, solid, or hidden).
Blinking pauses while you type. Programs that set their own shape
with DECSCUSR — vim's block in normal mode and bar in insert mode —
are honoured until they reset it. See
[cursor].
Mouse reporting
When a program turns on mouse reporting, clicks, drags, and scrolls are forwarded to it as SGR events rather than starting a selection. Hold shift to bypass that and select text anyway.
Font size
cmd-+ and cmd-- step the font one point at a
time; cmd-0 resets to the size in your config. The change
applies to every pane in the window and is not written back to disk —
edit font.size to make it permanent.
The status bar
The bar along the bottom shows the active workspace, the focused
pane's working directory, and — computed natively, not by shelling
out each prompt — the git branch, whether the tree is dirty, and how
far ahead or behind the upstream you are. Modes that are easy to
forget get a chip there too: a red ⇶ BROADCAST pill,
⤢ zoom, the copy-mode badge, and
ssh: host.
Move it with status_bar.position = "top", turn it off
permanently with status_bar.enabled = false, or toggle it
for the current window from View → Toggle Status Bar.
The bell
bell is "none" by default. Set it to
"sound" for the system alert or "visual" for
a brief flash of the window.