Apps
Files
# 3-Pane File Manager
A three-column file manager inspired by ranger/vifm: parent directory | current directory | preview pane. Navigate with arrow keys and vim-style bindings for file operations.
The file manager roots at the directory it was launched in. The left pane is empty at the root (you can't navigate above it); bookmarks live in a dialog and offer quick jumps to other directories.
## Preview Modes — Contents / Stat
The right pane previews the selected entry: text files show their first
50 lines, images render inline, directories list their contents. The
status bar's Contents / Stat radio group (bottom right) switches the
pane to a metadata view instead — name, path, type, size, and modified
time from `fs/stat`. Click Stat or Contents to toggle, or use
View → Toggle Preview Contents/Stat.
The startup default is the `files/preview-mode` config key (`:contents`
or `:stat`); editing it live (config app) switches the pane immediately.
## Dock — Bookmarks / Mounts
View → Toggle Dock (or the status bar's `[ ] Dock` checkbox) opens a
right-edge dock with two tabs:
- Bookmarks — lists the bookmarks. Scroll it with the mouse wheel
(or `Up`/`Down`/`Page Up`/`Page Down`/`Home`/`End` while the dock has
focus; `Escape` returns focus to the panel). Clicking a bookmark
navigates the manager to that directory.
- Mounts — lists the saved mount points (see below). Mounted entries
show `[+]`, unmounted ones `[ ]`. Click a row (or move with
`Up`/`Down` and press `Enter`/`Space`) to mount/unmount it, `a` mounts
the selected directory (the current directory when a file is selected)
under its name without prompting, `Delete` removes a saved mount
(after confirmation). The bottom row is an edit field showing the
selected mount's prefix with an Update button — click the field,
edit the prefix, then press `Enter` or click Update to rename the
mount (a live mount is unmounted and remounted under the new name; a
leading `/` is accepted and ignored).
Switch tabs by clicking the tab labels or with `Left`/`Right` while the
dock has focus. The `files/bookmarks-dock` config key sets the startup
default (false) and `files/dock-tab` the startup tab
(`:bookmarks`/`:mounts`); editing either live updates the dock. Hosts
without dock support (hydra) refuse the open and keep the checkbox off.
## Mounts — Paths Under a Prefix
Every filesystem path whose leading segment(s) name a mount routes
through the VFS layer, so `projects/src/main.zig` can be a directory
anywhere on disk (or on a remote host) and is visible to every panel.
- Mount the current path: `Ctrl+Shift+M` (or Mounts → Mount
Current Path...) prompts for a prefix — the current directory's
basename by default — and mounts the current directory under it as a
local mount.
- Manage saved mounts: Mounts → Manage Mounts... opens the dock
on the Mounts tab. `a` mounts the selected directory under its
basename — no prompt; `Enter`/click toggles mount/unmount; `Delete`
removes the definition; the bottom edit field + Update button
renames the selected mount's prefix. Removing or unmounting the mount
you are browsing returns you to the panel's local root.
- Unmount the current mount: Mounts → Unmount Current (or
`Ctrl+Shift+V` → -- Disconnect --, or Mounts → Disconnect
Host for ssh).
- Saved mounts persist in `.deft/mounts.dft` as
`%{ :name :spec :mounted }` records. Entries flagged `:mounted true`
are re-registered automatically when the file manager starts — that
is what makes a mount survive a restart. Legacy
`.deft/ssh-hosts.dft` host records are migrated into this file on
first load (as unmounted entries).
Mounts are process-global: while connected, other panels (the editor,
image viewer shell-outs, ...) resolve the same paths. A mount is a
chroot — navigation never goes above its root, and `..` cannot escape
it.
## VFS Mode — Browsing Remote Hosts
`Ctrl+Shift+V` (or Mounts → Connect to Host...) opens the ssh host
picker. Hosts are saved as ssh mounts in `.deft/mounts.dft` and connect
as VFS mounts — after that the remote filesystem is browsed exactly like
a local one: navigation, preview, mark/copy/move/paste, rename, mkdir,
and delete all work through the mount. The shell prompt (`Ctrl+S`)
runs commands on the remote host via ssh.
- Add a host: pick -- Add new host -- (or press `Ctrl+Shift+V`
with none recorded) and enter a spec string:
`[user@]host[:port]:/remote/root` — e.g. `ritchie@deft-lang.org:/home/ritchie`.
Port defaults to 22, root to `/`. Auth comes from your ssh keys,
agent, and `~/.ssh/config`.
- Disconnect: pick -- Disconnect -- in the host picker (or
Mounts → Disconnect Host). The mount is process-global — other
panels (the editor, etc.) can open remote files while connected.
- A mount is a chroot: navigation never goes above the remote root,
and `..` cannot escape it. The status bar shows `[host] /remote/dir`
while browsing a mount.
Known limits while on a mount: image previews fall back to text info,
bookmarks can't target remote paths, and recursive directory delete
works but is slow (one ssh round-trip per entry).
## Editor Sync
Go → Editor Sync (`Ctrl+E`) toggles live sync with the editor; the
menu option writes the `files/editor-sync` config flag and persists the
override (`[config/set "files/editor-sync" false]` also works live). While
it is on, every file switch in the editor (tab click, next/prev buffer,
open) moves the manager to that file's directory and selects it. The
manager tracks the editor's `editor-state` pub/sub stream, so it only
moves when the editor actually changed files — browsing elsewhere in the
manager is not yanked back on every editor keystroke.
## Watching Files
`Ctrl+W` starts an `fs/watch` on the selected file or directory: files
reload the preview after an external change, directories are watched
recursively and refresh the listing. The status bar shows the number of
active watches. Watching is local only — VFS mount paths report an error.
## Pie Menu
The workspace pie hub opens the Files ring: Editor Sync, Watch/Unwatch,
Bookmark/Unbookmark, Bookmarks..., Refresh, Toggle Hidden, Copy (Yank),
and Paste.
## Key Bindings
| Key | Action |
|-----|--------|
| `Up` / `Down` | Move cursor up/down |
| `Left` | Go to parent directory |
| `Right` / `Enter` | Enter directory / open file |
| `Home` | Jump to top of list |
| `End` | Jump to bottom of list |
| `Page Up` / `Page Down` | Scroll by page |
| `Backspace` | Go to parent directory |
| `Escape` | Clear search / cancel input |
| `Delete` | Delete selected file |
### File Operations
| Key | Action |
|-----|--------|
| `Ctrl+T` / `Ctrl+Space` | Toggle mark on file |
| `Ctrl+D` | Delete selected |
| `Ctrl+Shift+D` | Delete selected directory |
| `Ctrl+C` | Copy marked files |
| `Ctrl+X` | Cut marked files |
| `Ctrl+V` | Paste files |
| `Ctrl+R` | Prompt rename |
| `Ctrl+N` | Prompt create directory |
| `Ctrl+Shift+N` | Prompt create empty text file |
| `Ctrl+S` | Prompt shell command |
| `Ctrl+H` | Toggle hidden files |
| `Ctrl+O` | Go to home directory |
| `Ctrl+E` | Toggle Editor Sync |
| `Ctrl+W` | Watch/unwatch the selected entry |
| `Ctrl+G` | Jump to top |
| `Ctrl+B` | Jump to bottom |
| `Ctrl+L` | Refresh listing |
| `Ctrl+K` | Open bookmark switcher dialog |
| `Ctrl+M` | Add bookmark |
| `Ctrl+U` | Remove bookmark |
| `Ctrl+Shift+M` | Mount the current path under a prefix |
| `Ctrl+Shift+V` | Connect to a VFS (ssh) host |
### Input Mode
When prompted (rename, mkdir, new file, shell, search):
| Key | Action |
|-----|--------|
| `Enter` | Confirm input |
| `Escape` | Cancel input |
| `Backspace` | Delete character before cursor |
| `Delete` | Delete character after cursor |
| `Left` / `Right` | Move cursor |
| `Home` / `End` | Cursor to start/end |