Oxide Terminal / docs
Docs / Using Oxide / Terminal & scrollback

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.

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, or V-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 — 2m14s or ✗ 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.

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.