A fast, feature-rich terminal file manager written in Rust. Two-pane layout with syntax-highlighted previews, inline image display, archive browsing, SSH remote access, async file operations, OpenAI integration, and comprehensive undo. Feature clone of RTFM.
Built on crust (TUI) and glow (images). Single binary, ~3.6MB, ~50ms startup.
# Download from releases (Linux/macOS, x86_64/aarch64)
# Or build from source:
git clone https://github.com/isene/pointer
cd pointer
cargo build --release
# Run
./target/release/pointer
# Start in specific directory
pointer ~/Documents
# Use as file picker
pointer --pick=/tmp/selected.txt
# Start with a clean slate (don't restore cursor positions)
pointer --freshPress ? for built-in help. Press q to quit (saves state).
| Directory browsing | File preview with bat |
|---|---|
![]() |
![]() |
| Image preview | |
![]() |
- Two-pane layout with configurable width ratio and border styles
- LS_COLORS support for consistent terminal theming
- Syntax highlighting built-in (20+ languages, plus dedicated Markdown/LaTeX/plaintext renderers with URL/TODO detection) with 6 themes, bat as optional toggle
- Image preview via kitty/sixel/w3m protocols (using glow)
- Archive browsing and editing (zip, tar, gz, bz2, xz, rar, 7z as virtual directories — enter with ENTER/→, then
dto delete,Dto extract,pto paste in files tagged before entering) - SSH/SFTP remote browsing (Ctrl-E)
- Async file operations with progress for large copy/move
- Comprehensive undo (delete, move, rename, copy, symlink, permissions, bulk rename)
- Trash system with toggle and browser
- Tab management (create, close, switch, duplicate, rename)
- Bookmarks with instant single-key jump
- Search (filename), grep (content), filter (extension/regex)
- fzf and navi integration
- locate with jump-to-result
- Bulk rename (regex, case conversion, extension change, prefix/suffix)
- File comparison (diff between two tagged files)
- Git status display
- Directory hashing (SHA1 change detection)
- Claude integration (
I= one-shotclaude -pfile description;Ctrl+A= full Claude session, follows you to a directory you ask it to open) - Plugin system (JSON manifests, external commands)
- Script evaluator (
@mode with full context via env vars) - Top bar color matching (path-based, like RTFM's @topmatch)
- File picker mode (
--pick=/pathfor external tool integration) - Scrolloff (3-line margin) and wrap-around navigation
Deletion is a two-step flag-then-purge (same convention as kastrup, so muscle memory carries between the two): press
dto flag the current item (or all tagged items) for deletion — flagged entries render in dark red with aDprefix anddtoggles the flag off. Nothing is removed until you press<to purge every flagged item (single-key confirm by default; setconfirm_delete: falseto skip it, moving to trash when enabled). Sotto tag,dto flag,<to purge.dis now safe to press by reflex — it never deletes on its own.
| Key | Action | Key | Action |
|---|---|---|---|
| Navigation | View | ||
| j/k | Move down/up | a | Toggle hidden files |
| h/l | Go up / enter | A | Toggle long format |
| PgDn/PgUp | Page down/up | o | Cycle sort mode |
| HOME/END | First/last | i | Invert sort |
| ~ | Home directory | - | Toggle preview |
| ' | Jump to mark | _ | Toggle images |
| > | Follow symlink | b | Toggle bat/internal syntax |
| Tags | Search | ||
| t | Tag/untag | / | Search filenames |
| T | Show tagged | n/N | Next/prev match |
| u | Clear tags | \ | Clear search & filter |
| Ctrl-T | Tag by pattern | f/F | Filter ext/regex |
| g | Grep file contents | ||
| Ctrl-F | fzf fuzzy finder | ||
| File Ops | Tabs | ||
| p | Copy here | ] / [ | New / close tab |
| P | Move here | J/K | Prev/next tab |
| d | Flag for deletion | 1-9 | Switch to tab |
| < | Purge (delete flagged) | ||
| c | Rename | { / } | Rename / duplicate |
| s | Create symlink | Command | |
| = | Create directory | : | Shell command |
| E | Bulk rename | ; | Command history |
| X | Compare (2 tagged) | @ | Script evaluator |
| U | Undo | + | Add to interactive |
| Marks | UI | ||
| m | Set mark | w/W | Pane width fwd/back |
| M | Show marks | Ctrl-B | Cycle border |
| r | Recent files/dirs | C | Preferences editor |
| Clipboard | Info | ||
| y | Yank to primary | e | File properties |
| Y | Yank to clipboard | G | Git status |
| Ctrl-Y | Copy right pane | H | Hash directory |
| Ctrl-A | Claude session | S | System info |
| Ctrl-L/Ctrl-R | Redraw/Refresh | I | Describe file (claude -p) |
| Key | Action |
|---|---|
| Shift-Down/Up | Scroll line |
| TAB / Shift-TAB | Page down/up |
| ENTER | Refresh preview |
Config: ~/.pointer/conf.json (auto-created on first run)
State: ~/.pointer/state.json (marks, history, recent files)
Trash: ~/.pointer/trash/
Plugins: ~/.pointer/plugins/
{
"width": 4,
"border": 2,
"preview": true,
"trash": true,
"confirm_delete": true,
"bat": true,
"show_hidden": false,
"long_format": false,
"sort_mode": "name",
"sort_invert": false,
"interactive": ["vim", "less", "top", "htop", "fzf", "navi"],
"c_top_fg": 0, "c_top_bg": 249,
"c_status_fg": 252, "c_status_bg": 236,
"topmatch": [["Projects", 171], ["Work", 72], ["", 249]],
"ai_key": "",
"ai_model": "gpt-4o-mini",
"syntax_theme": "monokai",
"remember_positions": true
}confirm_delete (default true) asks a single-key y/n before < purges the delete-flagged items. Set it false to purge immediately — handy with trash on, where d d d < flags three files and deletes them in one keystroke, recoverable from ~/.pointer/trash/.
remember_positions (default true) persists the cursor position per directory across sessions. Toggle at runtime with r in the C config screen, or launch with pointer --fresh to bypass restoration for a single session.
Press @ to run a shell command with pointer context as environment variables:
| Variable | Content |
|---|---|
POINTER_SELECTED |
Full path of selected item |
POINTER_DIR |
Current working directory |
POINTER_TAGGED |
Newline-separated tagged paths |
POINTER_INDEX |
Selected index (0-based) |
POINTER_COUNT |
Number of files |
POINTER_CONTEXT |
JSON with all above |
Scripts can control pointer via stderr directives: cd:/path, select:filename, status:message.
Plugins live in ~/.pointer/plugins/. Each plugin is a JSON manifest (.json file) describing an external command bound to a key.
Manifest format:
{
"name": "Git",
"description": "Interactive git client",
"key": "C-G",
"command": "bash ~/.pointer/plugins/git.sh",
"interactive": true
}| Field | Description |
|---|---|
name |
Display name shown in help |
description |
Short description |
key |
Trigger key (e.g. F5, C-G for Ctrl-G) |
command |
Shell command to execute |
interactive |
If true, runs in raw terminal (full TUI). Default: false |
Non-interactive plugins run in the background; their stdout appears in the right pane. Interactive plugins take over the terminal (like vim or lazygit) and pointer restores its screen on exit.
Commands receive POINTER_CONTEXT env var with JSON state. Unmatched keys fall through to plugin dispatch, so plugins can bind any free key.
See the Fe₂O₃ suite overview and the landing page for the full list of projects.
| Tool | Clones | Type |
|---|---|---|
| rush | rsh | Shell |
| crust | rcurses | TUI library |
| glow | termpix | Image display |
| pointer | RTFM | File manager |
| kastrup | Heathrow | Messaging |
| tock | Timely | Calendar |
| scroll | brrowser | Browser |
Build: Rust toolchain (cargo)
Runtime (optional, for full features):
batorbatcatfor external syntax highlighting (optional, built-in highlighter is default)fzffor fuzzy findingImageMagick(convert,identify) for image previewpdftotextfor PDF previewgitfor git statusxclipfor clipboard (also uses OSC 52)locatefor file searchnavifor cheatsheetscurlfor AI integration
Unlicense - public domain.
Created by Geir Isene (https://isene.org) with extensive pair-programming with Claude Code.


