The file tree drawer
A drawer down the left side of the window: a file tree on top, the workspaces panel below it. The tree is modeless — there is no text input to collide with, so bare vim keys are free.
Showing and focusing it
| cmd-b | toggle the drawer |
| ctrl-w t/cmd-shift-e | focus the tree from anywhere |
| ctrl-w h | move a pane left — from the leftmost pane, that lands on the tree |
| ctrl-w w | toggle focus between the drawer and the terminal |
| tab | hop between the tree and the workspaces panel |
| esc | dismiss an input line, then clear the filter, then hand focus back to the terminal |
Hiding the drawer while the tree has focus moves focus to the terminal, so you never end up typing into an invisible panel.
Navigating
| j k / ↓ ↑ | move the selection |
| gg / G | first / last row |
| ctrl-d / ctrl-u | half a page down / up |
| l / → | expand a directory, descend into it if it's already open, or open a file |
| h / ← | collapse a directory, or jump up to the parent — nvim-tree semantics |
| p | select the parent directory |
| enter / o | open — a directory expands, a file opens in your editor |
| y / Y | insert the selection's path at the prompt — relative to the shell's directory, or absolute |
| cmd-c | copy the path |
| cmd-shift-o | reveal in Finder |
| I | toggle hidden files for this session |
| R | rescan every directory that's currently loaded |
Directories are scanned on the background pool, lazily, as you expand them, and a filesystem watcher keeps what's on screen honest without you pressing R.
Opening files
enter on a file opens it in the focused pane and moves
focus there. It runs $EDITOR if you have one, and falls
back to open -t — a fresh Mac has no nvim, and a
"command not found" is a worse first impression than TextEdit.
The editor is launched through the same widget the silent
cd uses, so no command line is echoed at the prompt and
nothing lands in your shell history — you just get the editor. Only
the shell knows what $EDITOR is, which is why this goes
through the shell at all. Without
shell integration there's
no silent channel to the shell, so Oxide reveals the file in the
tree instead and says why in a toast.
The other direction works too: cmd-click a
path:line:col in terminal output — a compiler error, a
grep -n hit, a stack frame — and the file opens at
that line. See
file links.
The tree as an input device
The tree isn't only a viewer. y types the selected path
at the prompt, single-quoted so a space in a name stays one
argument, and relative to the shell's directory when the file is
beneath it (src/main.rs, not the full path).
Y always inserts the absolute path. Nothing is submitted:
you decide what command wraps it. Dragging a row onto a pane does
the same, and so does dropping files from Finder.
Right-click any row for the same things as a menu: open a file, set a directory as the tree root, insert the path, copy it, or reveal it in Finder.
Markdown files (.md, .markdown) get one
more item, Preview markdown. It renders the file
the way Help → What's New renders the changelog —
headings, lists, task boxes, quotes, boxed code blocks, tables
laid out to the tab's width, and inline styles — and pages
it with less in a new tab that closes on
q and puts you back on the tab you opened it from.
The HTML that READMEs lean on is understood too:
<h1>, <p align="center">,
<a>, <img> (shown as its
alt text), <kbd>, <br>,
comments, and entities. Link URLs are printed after their
text, so cmd-click opens them; the tab starts in the
file's directory, so relative links resolve too. The preview is
a snapshot laid out for the tab's width when it opened: reopen it
to pick up edits or a resized window.
Code blocks are syntax-highlighted by the language on their fence
(```toml, ```rust, ```sh,
and a couple of hundred more), using your theme's own ANSI colors
rather than a fixed palette, so they sit right in any preset.
Each block's top edge has a ⧉ copy link: click
it to put the block on the clipboard, exactly as written. It's
copied without a trailing newline, so pasting a command at a
prompt doesn't run it until you press ⏎.
Git state
Inside a repository, rows are coloured by their git status:
modified in yellow, added in green, untracked in dim green,
renamed in cyan, deleted in red, conflicted in bright red. A
collapsed directory takes the most urgent state of anything
beneath it, so a folded src/ still shows something
changed inside. Colours come from the theme's ANSI palette.
The status refreshes when the tree's watcher sees a change, when
the root moves, and on a slow heartbeat for things the watcher
can't see (commits and checkouts). Repositories with more than
twenty thousand changed paths get no decorations rather than a
stall. tree.git_status = false turns it off.
Finding your place
cmd-shift-r expands and scrolls the tree to the focused shell's directory, re-rooting first if it lies outside the tree. cmd-p opens a fuzzy file finder over everything under the root (respecting the same gitignore and hidden-file rules as the drawer): enter opens the file in your editor, cmd-enter inserts its path at the prompt, and opt-enter reveals it in the tree. Matches in the file name rank above matches in its directories, shallow paths rank above deep ones, and recently opened files float up.
Filtering
/ starts a filter. Type to narrow: rows whose name matches are kept, case-insensitively, along with the directories that lead to them, so matches stay in context. enter leaves input mode with the filter still applied; esc clears it.
File operations
| a |
add. Type a name and press enter; a trailing
/ makes a directory instead of a file. Nested
paths like src/util/new.rs create their parents.
|
| r | rename, prefilled with the current name (renaming into another directory is not allowed) |
| d | delete — y confirms, anything else cancels |
New entries are created relative to the selected directory, or to the
selected file's parent. Deletes move to ~/.Trash so
they're recoverable in Finder; a hard delete only happens as a
fallback when the target is on another volume. The tree re-scans and
selects what you just created or renamed.
Where the tree is rooted
| c |
re-root at the selection (or its parent, for a file) —
and cd the shell there too
|
| - | re-root one level up, keeping the old root expanded so it feels like zooming out |
The cd is silent: Oxide writes the target to
~/.cache/oxide/cd_target and triggers a zle widget in the
shell, so nothing is echoed and the existing prompt is just redrawn in
the new directory. That needs
shell integration — without
it, c still re-roots the tree, it just leaves the shell
where it was.
Following the shell
The other direction works with zero shell cooperation. With
tree.follow_cwd = true (the default), Oxide polls the
PTY's foreground process group for its working directory, so the tree
re-roots when you cd — in any shell, with or without
integration. It also follows focus: switching panes re-roots the tree
to that shell's directory.
Configuration
[tree] width = 280 show_hidden = false respect_gitignore = true indent = 16 icons = true follow_cwd = true
respect_gitignore hides anything your
.gitignore covers — usually the difference between a
useful tree and a wall of target/.
icons turns off the Nerd Font glyphs if you'd rather have
plain names. Full details in the
configuration reference.