A terminal-based file manager written in Crystal. Ported from the original Bash version for performance, safety, and maintainability.
- Fast:
LS_COLORScaching, optimized incremental render loop, no flicker - Modern Themes: Truecolor RGB central theme system with 5 built-in presets (
default,catppuccin-mocha,gruvbox-dark,nord,dracula). - Selection Indicator: Sleek vertical block (
β) selection marker keeping native file type colors bolded on selection background. - Pill-Shaped Badges: Status and top bar indicators (clipboard, marks, sorting, git, file/folder counts, and directory size) rendered in colored pill badges.
- Nerd Font Icons: Support for file and directory icons using Nerd Fonts (over 100+ extensions and 35+ special file mapping).
- Dual-Pane View (Preview Panel): Interactive directory and file content preview side panel (automatically adapts when terminal columns >= 80).
- Details Columns: Shows file size and modification time directly in the file list, including on the selected line.
- Empty Directory State: Centered placeholder display for empty folders.
- Toast Notifications: Interactive notification system (Error, Success, Warning, Info) with custom colors and icons, featuring auto-expiry.
- Navigable Search: Fuzzy filename filtering, ripgrep content search (
!prefix), and recursive directory tree search (>prefix) while keeping cursor navigation live. - Progress Bars: Interactive progress bar for bulk operations (copying/deleting 5+ files).
- Inline Prompts & Confirms: Inputs (new file, new dir, rename, go-to-dir) and confirmations (delete, executable toggle) stay inside the TUI.
- File Operations: Copy, move, delete (trash), rename, bulk rename, symlink with auto-advance navigation.
- Smart Full Preview: Full-screen preview via
batβlessβ built-in fallback chain; file attributes viaFile::Info/stat - Picker Mode:
-pflag writes selection to~/.cache/fff/opened_filefor external tool integration - Secure: All external commands via
Process.run(no shell injection), pre-operation writability checks - Customizable: Full keybinding, theme, and layout control via environment variables or
~/.config/fff/config.json
- Crystal 1.20.1+
- Windows 11, Linux, or macOS terminal (with true-color support recommended)
| Platform | Package | Notes |
|---|---|---|
| Debian/Ubuntu | libreadline-dev |
Crystal links against readline on Linux |
| Fedora/RHEL | readline-devel |
Same as above |
| Arch | readline |
Included in base |
| macOS | (built-in) | Comes with Xcode Command Line Tools |
| Windows 11 | (none) | Crystal uses Win32 console API |
make depsinstalls Crystal shards and auto-patches knowncrystal-termbugs.
On Linux/macOS:
make deps # install shards
make build # release build β bin/fff-cr
make debug # debug build (faster compile)
make run # build + run
make test # run test suite
# Optional: system-wide install (including man page)
sudo make installOn Windows 11 (PowerShell):
shards install # install shards
crystal run scripts/patch_shards.cr # patch known shard bugs
crystal build src/fff.cr -o bin/fff-cr.exe # build fff-cr.exe
crystal spec spec/fff/ # run unit tests
.\bin\fff-cr.exe # run the appfff-cr # open current directory
fff-cr /path/to/dir # open specific directory
fff-cr -p # picker mode (writes to opened_file cache)| Key | Action | Key | Action |
|---|---|---|---|
j/k |
Down/Up | l/h |
Enter/Parent |
q |
Quit | ? |
Help overlay |
/ |
Search (Navigable) | space |
Mark |
m |
Mark all | y/v |
Copy/Cut |
p |
Paste | d |
Delete (trash) |
t |
Go to trash | n |
New dir |
f |
New file | r |
Rename |
b |
Bulk rename | i |
Preview |
x |
Attributes | X |
Toggle executable |
s |
Spawn shell | g/G |
Top/Bottom |
β/β |
Cursor | PgUp/PgDn |
Page up/down |
. |
Toggle hidden | ~ |
Home |
- |
Previous dir | e |
Refresh |
= / + |
Cycle sort / Reverse | : |
Go to dir |
S |
Symlink | 1-9 |
Favorites |
In search and rename modes, β/β move within the input text, Backspace/Delete edit, Home/End jump to start/end. In normal mode, ESC clears active search filters and marks. In search mode, ESC cancels the search; if you navigated the results with arrow keys, it drops you directly onto the selected file, otherwise it reverts to your pre-search position.
All bindings are configurable via FFF_KEY_* environment variables.
When in search mode (triggered by /), you can prefix your query to activate different search modes:
| Prefix | Mode | Description |
|---|---|---|
| (none) | Fuzzy Filename | Fuzzy matches filenames within the current directory. |
! |
Content Search | Calls rg (ripgrep) to search file content (requires pressing Enter to search). |
> |
Recursive Search | Recursively fuzzy searches files in the directory tree (up to 5 levels deep, capped at 200 results) (requires pressing Enter to search). |
fff reads from environment variables first, then falls back to ~/.config/fff/config.json.
| Env Variable | Config JSON Key | Description / Values |
|---|---|---|
FFF_THEME |
theme.name |
UI Theme: default, catppuccin-mocha, gruvbox-dark, nord, dracula (Default: default) |
FFF_ICONS |
icons |
Enable Nerd Font icons: 1 or true (Default: disabled) |
FFF_COLUMNS |
columns |
Show details columns (size/date): 0 to hide (Default: enabled) |
FFF_COLUMN_MODE |
column_mode |
Column display mode: size, date, or both (Default: both) |
FFF_PREVIEW |
preview |
Enable directory/file preview side-panel when term is wide enough: 1 or true (Default: disabled) |
export FFF_OPENER="xdg-open" # file opener
export FFF_FAV1="$HOME/Documents" # favorite dirs 1-9
export FFF_CD_ON_EXIT="1" # save cwd on exit
export FFF_TRASH="$HOME/.local/share/fff/trash"
# Example UI settings:
export FFF_THEME="catppuccin-mocha"
export FFF_ICONS="1"
export FFF_PREVIEW="1"Full list of FFF_KEY_* variables: UP, DOWN, ENTER, QUIT, SEARCH, PARENT, MARK, MARK_ALL, COPY, MOVE, PASTE, DELETE, NEW_DIR, MKFILE, RENAME, BULK_RENAME, PREVIEW, SHELL, HIDDEN, HOME, PREVIOUS, REFRESH, ATTRIBUTES, EXECUTABLE, GO_DIR, GO_TRASH, SYMLINK, TOP, BOTTOM, PAGE_UP, PAGE_DOWN.
{
"editor": "vim",
"opener": "xdg-open",
"trash_dir": "/path/to/trash",
"theme": { "name": "catppuccin-mocha" },
"icons": true,
"columns": true,
"column_mode": "both",
"preview": true,
"favorites": { "1": "/home/user/Documents" },
"keys": { "up": "k", "down": "j" },
"bookmarks": { "proj": "/home/user/projects" }
}Press i to preview a file. The preview chain tries:
bat --paging=alwaysβ syntax-highlighted, scrollablelessβ paged, searchable- Built-in β plain text with full scroll support
Directories always use the built-in preview.
.
βββ bin/fff-cr # compiled binary
βββ man/fff-cr.1 # man page
βββ src/
β βββ fff.cr # entry point
β βββ fff/
β βββ config.cr
β βββ directory_manager.cr
β βββ draw_state.cr
β βββ file_manager.cr
β βββ file_op_handlers.cr
β βββ file_operations.cr
β βββ file_service.cr
β βββ format_utils.cr
β βββ icon_provider.cr
β βββ input_mode.cr
β βββ message_bus.cr
β βββ navigation_handlers.cr
β βββ preview_panel.cr
β βββ progress_bar.cr
β βββ search_engine.cr
β βββ terminal.cr
β βββ theme.cr
β βββ ui_renderer.cr
β βββ view_handlers.cr
βββ spec/ # test suite
β βββ spec_helper.cr
β βββ fff/
β βββ integration/
βββ Makefile
βββ shard.yml
βββ .ameba.yml # linter config
βββ LICENSE
- FFF::Application β CLI argument parsing, terminal setup
- FFF::Config β env var & JSON config management,
LS_COLORSparsing, layout preferences - FFF::DirectoryManager β directory reading, sorting, hidden-file filtering
- FFF::DrawState β bundles all redraw parameters into one struct
- FFF::FileManager β event loop, hash-table key dispatch, and TUI router; includes
NavigationHandlers,FileOpHandlers,ViewHandlers - FFF::FileOperations β file/directory creation, deletion, copying with callback blocks for progress tracking
- FFF::FileService β low-level
copy/move/trash/symlinkwith writability checks - FFF::FormatUtils β shared helpers (
human_size, date formatting),FFF::HOMEconstant - FFF::IconProvider β maps file extensions and special names to Nerd Font icons
- FFF::InputMode β search/rename text input with cursor control, editing, and search mode matching
- FFF::MessageBus β thread-safe TUI toast notification queue (Error/Success/Warning/Info)
- FFF::PreviewPanel β split pane displaying file previews/details and directory entries
- FFF::ProgressBar β ANSI progress bar tracking bulk operations
- FFF::SearchEngine β fuzzy filename matching, ripgrep content search, and recursive tree search
- FFF::Terminal β
crystal-termshard wrapper - FFF::Theme β truecolor RGB color palette system with pre-configured styles
- FFF::UIRenderer β incremental, flicker-free drawing, truecolor CSS/TUI styling, layout composition
make test # run all specs
make format # crystal tool format
make lint # ameba static analysismake test # all specs (205 examples)
crystal spec spec/integration/navigation_integration_spec.cr
crystal spec spec/integration/file_operations_integration_spec.cr
crystal spec spec/integration/ui_integration_spec.cr-
94 unit tests across 6 modules (config, directory_manager, file_service, input_mode, search_engine, ui_renderer)
-
111 integration tests across 3 suites (navigation, file_operations, ui) β use
MockTerminalto simulate keyboard input and prompts without a real TTY -
Both specs run headless; no terminal or display required
The project patches several crystal-term shard bugs via scripts/patch_shards.cr after shards install. make deps applies them automatically on Linux/macOS; on Windows, run crystal run scripts/patch_shards.cr manually. The script is idempotent. See AGENTS.md for details.
MIT. See LICENSE.
