# REX — Terminal File Manager
A fast, keyboard-driven TUI file manager written in Rust using [ratatui](https://github.com/ratatui-org/ratatui).


---
## Features
- ⚡ **Zero-lag navigation** — dirty-flag rendering, async preview loading, cached stat calls
- 🔍 **Fast search** — `/` local search, `g` global search (via `fd`), non-blocking async results
- 📋 **Selection-first workflow** — select multiple files with `Space`, then batch copy/cut/delete
- 🗂️ **Open With** — `o` opens with configured app, `O` shows a selection popup
- ⚙️ **JSON config** — map file extensions to apps in `config.json`
- 🗑️ **Trash support** — delete moves to trash with undo
- 📖 **Inline help** — press `?` for keybind reference
---
## Install
```bash
# Clone
git clone https://github.com/gaurav13407/REX-File-Manager
cd rex
## Install
cargo install rex-fm
# Install fd (optional but recommended — faster search)
sudo apt install fd-find # Ubuntu/Debian
# or: sudo pacman -S fd # Arch
# Falls back to built-in 'find' if fd is not installed
# Run
cargo run
```
> Requires Rust ≥ 1.70
---
## Keybinds
### Navigation
| `j` / `k` | Move down / up |
| `h` | Go to parent directory |
| `l` / `Enter` | Enter directory |
| `Tab` | Switch between file list and preview pane |
### File Operations
| `o` | Open file with configured app |
| `O` | Open With popup — choose app, saves as new default |
| `Space` | Toggle select file |
| `A` | Select all files |
| `y` | Copy selected / cursor file |
| `x` | Cut selected / cursor file |
| `p` | Paste |
| `d` | Delete (moves to trash), prompts confirm |
| `u` | Undo last operation |
| `Esc` | Clear selection |
### Search
| `/` | Local search (current directory, depth 5) |
| `g` | Global search (from `/`, depth 8) |
| `j` / `k` | Navigate results |
| `Enter` | Jump to result directory |
| `Esc` / `q` | Exit search |
### General
| `?` | Toggle help popup |
| `q` | Quit |
---
## Configuration
Edit `config.json` in the project root to map file extensions to apps:
```json
{
"rs": "nvim",
"md": "nvim",
"pdf": "libreoffice",
"png": "eog",
"mp4": "vlc",
"mp3": "vlc"
}
```
- **`o`** opens with the mapped app, or `xdg-open` if no mapping exists
- **`O`** lets you pick from a list and saves the choice back to `config.json`
---
## Architecture
```
src/
├── main.rs # Event loop, key handling, async search/preview
├── app.rs # App state (App struct, config, operations)
├── fs/
│ └── navigator.rs # Directory listing with cached is_dir flags
└── ui/
└── layout.rs # Rendering (ratatui widgets, popups)
```
**Performance design:**
- Preview loaded in background thread via `mpsc::channel` — never blocks the event loop
- Search runs `fd` in a background thread with `AtomicBool` cancellation — each keystroke cancels the previous search
- Rendering uses a `needs_draw` dirty flag — no redundant redraws
- Zero `stat()` syscalls during render — `is_dir` cached in `Navigator`
---
## Dependencies
| `ratatui` | TUI rendering |
| `crossterm` | Terminal backend |
| `notify` | Filesystem watcher |
| `walkdir` | Directory traversal |
| `serde` + `serde_json` | Config file (de)serialization |
| `dirs` | Home directory resolution |
---
## License
MIT