tui-file-explorer 0.4.3

A self-contained, keyboard-driven file-browser widget for Ratatui
Documentation

tui-file-explorer

Crates.io Documentation License: MIT Release CI Downloads

A keyboard-driven, two-pane file manager widget for Ratatui.
Use it as an embeddable library widget or run it as the standalone tfe CLI tool.


Preview

Navigation · Search · Sortcargo run --example basic

Navigation, search and sort

File Operations — copy, cut, paste, delete across two panes · cargo run --bin tfe

Copy, Cut, Paste, Delete

27 Live Themescargo run --example theme_switcher

27 live themes

DualPane Library Widget — Tab focus, w toggle, independent panes · cargo run --example dual_pane

DualPane library widget


Features

  • 🗂️ Two-pane layout — independent left and right explorer panes, Tab to switch focus
  • 📋 File operations — copy (y), cut (x), paste (p), and delete (d) between panes
  • 🔍 Incremental search — press / to filter entries live as you type
  • 🔃 Sort modes — cycle Name → Size ↓ → Extension with s
  • 🎛️ Extension filter — only matching files are selectable; dirs are always navigable
  • 👁️ Toggle hidden dot-file visibility with .
  • ⌨️ Full keyboard navigation: Miller-columns / (ascend/descend), vim keys (h/j/k/l), //j/k, PgUp/PgDn, g/G on a file moves down, never exits the TUI
  • 🎨 27 named themes — Catppuccin, Dracula, Nord, Tokyo Night, Kanagawa, Gruvbox, and more
  • 🎛️ Live theme panel — press t to open a side panel, [/] to cycle themes
  • 🔧 Fluent builder API for ergonomic embedding — both FileExplorer and DualPane
  • 📦 DualPane library widget — drop a full two-pane explorer into any Ratatui app with one struct
  • 🖥️ cd on exit — dismiss with Esc/q and your terminal jumps to the directory you were browsing; one-time setup with tfe --init <shell> (bash, zsh, fish, powershell)
  • ✅ Lean library — only ratatui + crossterm required (clap is opt-out)

Stats

Metric Value
Library dependencies 2 (ratatui, crossterm)
Named colour themes 27
Sort modes 3 (Name, Size ↓, Extension)
File operations 4 (copy, cut, paste, delete)
Key bindings 20+
File-type icons 50+ extensions mapped
Public API surface 10 types, 6 free functions
Unit tests 475

Installation

As a library

[dependencies]
tui-file-explorer = "0.3"
ratatui = "0.30"

Library-only (no clap-powered CLI binary):

[dependencies]
tui-file-explorer = { version = "0.3", default-features = false }

As a CLI tool

cargo install tui-file-explorer

Installs the tfe binary onto your PATH.


Quick Start

Single-pane

use tui_file_explorer::{FileExplorer, ExplorerOutcome, SortMode, render};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};

// 1. Create once — e.g. in your App::new
let mut explorer = FileExplorer::builder(std::env::current_dir().unwrap())
    .allow_extension("iso")
    .allow_extension("img")
    .sort_mode(SortMode::SizeDesc)   // largest files first
    .show_hidden(false)
    .build();

// 2. Inside Terminal::draw:
// render(&mut explorer, frame, frame.area());

// 3. Inside your key-handler — ↑/↓/←/→ scroll the list, Enter confirms:
let key = KeyEvent::new(KeyCode::Esc, KeyModifiers::NONE);
match explorer.handle_key(key) {
    ExplorerOutcome::Selected(path) => println!("chosen: {}", path.display()),
    ExplorerOutcome::Dismissed      => { /* close the overlay */ }
    _                               => {}
}

Dual-pane

use tui_file_explorer::{DualPane, DualPaneOutcome, render_dual_pane_themed, Theme};
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use std::path::PathBuf;

// 1. Create once — left pane defaults to cwd; right pane can differ.
let mut dual = DualPane::builder(std::env::current_dir().unwrap())
    .right_dir(PathBuf::from("/tmp"))
    .show_hidden(false)
    .build();

let theme = Theme::default();

// 2. Inside Terminal::draw:
// render_dual_pane_themed(&mut dual, frame, frame.area(), &theme);

// 3. Inside your key-handler:
let key = KeyEvent::new(KeyCode::Esc, KeyModifiers::NONE);
match dual.handle_key(key) {
    DualPaneOutcome::Selected(path) => println!("chosen: {}", path.display()),
    DualPaneOutcome::Dismissed      => { /* close the overlay */ }
    _                               => {}
}

Key Bindings

Navigation

Key Action
/ k Move cursor up
/ j Move cursor down
PgUp Jump up 10 rows
PgDn Jump down 10 rows
g / Home Jump to top
G / End Jump to bottom
/ l / Enter Descend into directory; on a file moves cursor down, l/Enter confirm (exits TUI)
/ h / Backspace Ascend to parent directory
Tab Switch active pane (left ↔ right)
w Toggle two-pane ↔ single-pane layout

Explorer actions

Key Action
/ Activate incremental search
s Cycle sort mode (Name → Size ↓ → Extension)
. Toggle hidden (dot-file) entries
Esc Clear search (if active), then dismiss
q Dismiss when search is not active

File operations

Key Action
y Yank — mark highlighted entry for copy
x Cut — mark highlighted entry for move
p Paste — copy/move clipboard into the other pane's directory
d Delete — remove highlighted entry (asks for confirmation)

Layout & theme controls

Key Action
w Toggle two-pane ↔ single-pane layout
t Next theme
T Toggle theme panel (right sidebar)
[ Previous theme

Search mode (after pressing /)

Key Action
Any character Append to query — list filters live
Backspace Remove last character; empty query exits search
Esc Clear query and exit search
/ / j / k Scroll the filtered results
/ Enter / l Descend into directory or confirm/navigate entry
/ Backspace / h Ascend to parent directory

Two-Pane File Manager

The tfe binary opens a split-screen file manager with a left and right pane.

┌─── Left Pane (active) ──────────┬─── Right Pane ───────────────────┐
│ 📁 ~/projects/tui-file-explorer │ 📁 ~/projects/tui-file-explorer  │
├─────────────────────────────────┤──────────────────────────────────┤
│ ▶ 📁 src/                       │   📁 src/                        │
│   📁 examples/                  │   📁 examples/                   │
│   📄 Cargo.toml                 │   📄 Cargo.toml                  │
│   📄 README.md                  │   📄 README.md                   │
├─────────────────────────────────┴──────────────────────────────────┤
│ 📋 Copy: main.rs          Tab pane  y copy  x cut  p paste  d del  │
└────────────────────────────────────────────────────────────────────┘
  • The active pane renders with your full theme accent; the inactive pane dims its borders so focus is always clear at a glance
  • Press Tab to switch which pane has keyboard focus
  • Arrow keys (/) scroll the cursor up/down without entering or exiting a directory — use Enter / l to descend and Backspace / h to ascend
  • Press w to collapse to a single pane — the hidden pane keeps its state and reappears when you press w again
  • Press t / [ to cycle themes forward / backward; press T to open the theme panel
  • Each pane navigates independently — scroll to different directories and use one as source, one as destination

File Operations (Copy / Cut / Paste / Delete)

The classic Midnight Commander source-to-destination workflow:

  1. Navigate to the file you want in the active pane
  2. y to yank (copy) or x to cut it — the status bar confirms what is in the clipboard
  3. Tab to switch to the other pane and navigate to the destination directory
  4. p to paste — the file is copied (or moved for cut) into that pane's directory
Active pane: ~/projects/src/     Other pane: ~/backup/
  ▶ main.rs   ← press y                      ← press p here → main.rs appears

If the destination file already exists a confirmation modal appears asking whether to overwrite. Delete (d) also shows a modal before any data is removed.

All file operations support directories — copy and delete both recurse automatically.


Incremental Search

Press / to activate search mode. The footer transforms into a live input bar showing your query. Entries are filtered in real-time using a case-insensitive substring match on the file name.

// Inspect search state programmatically:
println!("searching: {}", explorer.is_searching());
println!("query    : {}", explorer.search_query());

Behaviour details:

  • Backspace on a non-empty query pops the last character
  • Backspace on an empty query deactivates search without dismissing
  • Esc clears the query and deactivates search — a second Esc (when search is already inactive) dismisses the explorer entirely
  • Search is automatically cleared when navigating into a subdirectory or ascending to a parent

Sort Modes

Press s to cycle through three sort modes, or set one directly:

use tui_file_explorer::{FileExplorer, SortMode};

let mut explorer = FileExplorer::new(std::env::current_dir().unwrap(), vec![]);

explorer.set_sort_mode(SortMode::SizeDesc);   // largest files first
println!("{}", explorer.sort_mode().label()); // "size ↓"
Mode Trigger Description
SortMode::Name s (1st press) Alphabetical A → Z — the default
SortMode::SizeDesc s (2nd press) Largest files first
SortMode::Extension s (3rd press) Grouped by extension, then by name

Directories always sort alphabetically among themselves regardless of the active mode. The current sort mode is shown in the footer status panel at all times.


Extension Filtering

Only files whose extension matches the filter are selectable. Directories are always shown and always navigable, regardless of the filter.

use tui_file_explorer::FileExplorer;

// Builder API (preferred)
let explorer = FileExplorer::builder(std::env::current_dir().unwrap())
    .allow_extension("iso")
    .allow_extension("img")
    .build();

// Or replace the filter at runtime — reloads the listing immediately
explorer.set_extension_filter(["rs", "toml"]);

// Pass an empty filter to allow all files
explorer.set_extension_filter([] as [&str; 0]);

Non-matching files are shown dimmed so the directory structure remains visible. Attempting to confirm a non-matching file shows a status message in the footer.


Builder API

FileExplorer::builder

FileExplorer::builder gives a fluent, chainable construction API:

use tui_file_explorer::{FileExplorer, SortMode};

let explorer = FileExplorer::builder(std::env::current_dir().unwrap())
    .allow_extension("rs")          // add one extension at a time
    .allow_extension("toml")
    .show_hidden(true)              // show dot-files on startup
    .sort_mode(SortMode::Extension) // initial sort order
    .build();

Or pass the full filter list at once:

let explorer = FileExplorer::builder(std::env::current_dir().unwrap())
    .extension_filter(vec!["iso".into(), "img".into()])
    .build();

The classic FileExplorer::new(dir, filter) constructor is still available and fully backwards-compatible.


DualPane::builder

DualPane::builder mirrors the single-pane builder and adds dual-pane-specific options:

use tui_file_explorer::{DualPane, SortMode};
use std::path::PathBuf;

let dual = DualPane::builder(std::env::current_dir().unwrap())
    .right_dir(PathBuf::from("/tmp")) // independent right-pane directory
    .allow_extension("rs")            // applied to both panes
    .allow_extension("toml")
    .show_hidden(false)               // both panes
    .sort_mode(SortMode::Name)        // both panes
    .single_pane(false)               // start in dual-pane mode (default)
    .build();

Once built, pane directories, sort mode, and hidden-file visibility can still be changed independently on dual.left and dual.right at runtime.

Builder method Effect
.right_dir(path) Independent starting directory for the right pane
.allow_extension(ext) Append one extension to the shared filter
.extension_filter(vec) Replace the shared filter entirely
.show_hidden(bool) Hidden-file visibility for both panes
.sort_mode(mode) Initial sort order for both panes
.single_pane(bool) Start in single-pane mode (default false)

Theming

Every colour used by the widget is overridable through the Theme struct. Pass a Theme to render_themed instead of render:

use tui_file_explorer::{FileExplorer, Theme, render_themed};
use ratatui::style::Color;

let theme = Theme::default()
    .brand(Color::Magenta)               // widget title
    .accent(Color::Cyan)                 // borders & current path
    .dir(Color::LightYellow)             // directory names & icons
    .sel_bg(Color::Rgb(50, 40, 80))      // highlighted-row background
    .success(Color::Rgb(100, 230, 140))  // status bar & selectable files
    .match_file(Color::Rgb(100, 230, 140));

terminal.draw(|frame| {
    render_themed(&mut explorer, frame, frame.area(), &theme);
})?;

Named presets (27 included)

All presets are available as associated constructors on Theme:

use tui_file_explorer::Theme;

let t = Theme::dracula();
let t = Theme::nord();
let t = Theme::catppuccin_mocha();
let t = Theme::catppuccin_latte();
let t = Theme::tokyo_night();
let t = Theme::tokyo_night_storm();
let t = Theme::gruvbox_dark();
let t = Theme::kanagawa_wave();
let t = Theme::kanagawa_dragon();
let t = Theme::moonfly();
let t = Theme::oxocarbon();
let t = Theme::grape();
let t = Theme::ocean();
let t = Theme::neon();

// Iterate the full catalogue (name, description, theme):
for (name, desc, _theme) in Theme::all_presets() {
    println!("{name}{desc}");
}

Full preset list:
Default · Dracula · Nord · Solarized Dark · Solarized Light · Gruvbox Dark · Gruvbox Light · Catppuccin Latte · Catppuccin Frappé · Catppuccin Macchiato · Catppuccin Mocha · Tokyo Night · Tokyo Night Storm · Tokyo Night Light · Kanagawa Wave · Kanagawa Dragon · Kanagawa Lotus · Moonfly · Nightfly · Oxocarbon · Grape · Ocean · Sunset · Forest · Rose · Mono · Neon

Palette constants

The default colours are exported as pub const values for use alongside complementary widgets:

Constant Default Used for
C_BRAND Rgb(255, 100, 30) Widget title
C_ACCENT Rgb(80, 200, 255) Borders, current-path text
C_SUCCESS Rgb(80, 220, 120) Selectable files, status bar
C_DIM Rgb(120, 120, 130) Hints, non-matching files
C_FG White Default foreground
C_SEL_BG Rgb(40, 60, 80) Selected-row background
C_DIR Rgb(255, 210, 80) Directory names & icons
C_MATCH Rgb(80, 220, 120) Extension-matched file names

Examples

basic

examples/basic.rs — a fully self-contained Ratatui app demonstrating:

  • Builder API and full event loop
  • All ExplorerOutcome variants
  • Custom Theme
  • Optional CLI extension-filter arguments
# Browse everything
cargo run --example basic

# Only .rs and .toml files are selectable
cargo run --example basic -- rs toml md

dual_pane

examples/dual_pane.rs — a fully self-contained dual-pane Ratatui app built entirely on the library API (no binary code):

  • DualPane::builder with an optional independent right-pane directory
  • render_dual_pane_themed for rendering both panes in one call
  • All DualPaneOutcome variants
  • Status bar showing active pane and current layout mode
Key Action
Tab Switch focus left ↔ right
w Toggle single-pane / dual-pane mode
/ / j / k Move cursor up / down
/ Scroll cursor up / down (no navigation side-effects)
Enter / l Descend into directory or confirm file
Backspace / h Ascend to parent directory
. Toggle hidden files
/ Incremental search
s Cycle sort mode
Esc / q Quit
# Both panes start in the current directory
cargo run --example dual_pane

# Left pane starts in cwd, right pane starts in /tmp
cargo run --example dual_pane -- /tmp

theme_switcher

examples/theme_switcher.rs — live theme switching without restarting, with a sidebar showing the full theme catalogue.

Key Action
Tab Next theme
Shift+Tab Previous theme
/ / j / k Move cursor up / down
/ Scroll cursor up / down (no navigation side-effects)
Enter / l Descend into directory or confirm file
Backspace / h Ascend to parent directory
. Toggle hidden files
/ Search
s Cycle sort mode
Esc / q Quit
cargo run --example theme_switcher

Example Demos

Navigation & Search

Run: cargo run --example basic

Navigation and search

Demonstrates directory navigation, incremental search (/), sort mode cycling (s), hidden-file toggle (.), directory descent and ascent, and file selection.


Incremental Search

Run: cargo run --example basic then press /

Incremental search

Shows the full search lifecycle: activate with /, type to filter live, use Backspace to narrow or clear, and Esc to cancel without dismissing the explorer.


Sort Modes

Run: cargo run --example basic then press s

Sort modes

Demonstrates Name → Size ↓ → Extension → Name cycling, combined with search, and sort persistence across directory navigation.


Extension Filter

Run: cargo run --example basic -- rs toml

Extension filter

Only .rs and .toml files are selectable; all other files appear dimmed. The footer reflects the active filter at all times.


File Operations

Run: cargo run --bin tfe

Copy, Cut, Paste, Delete

Demonstrates the full copy then paste and cut (move) then paste workflows across both panes, followed by a delete with confirmation modal. The clipboard status bar updates live after each y / x / p keystroke, and an overwrite-prompt appears when the destination file already exists.


Theme Switcher

Run: cargo run --example theme_switcher

Theme switcher

Live theme cycling through all 27 named palettes with a real-time sidebar showing the catalogue and the active theme's description.


Pane Toggle

Run: cargo run --bin tfe

Pane toggle

Demonstrates the three layout controls in sequence:

  • Tab — switch keyboard focus between the left and right pane; each pane navigates independently so you can be in different directories at the same time
  • w — collapse to single-pane (the active pane expands to full width) and back to two-pane (the hidden pane reappears with its cursor position preserved)
  • T — open and close the theme-picker sidebar; use t / [ to cycle themes while the panel is open; both panes remain fully navigable with the panel visible

DualPane Library Widget

Run: cargo run --example dual_pane

DualPane library widget

A complete two-pane file manager built entirely on the library API — no binary code. Demonstrates:

  • DualPane::builder constructing two independent panes
  • render_dual_pane_themed rendering both panes in a single call
  • Tab switching keyboard focus; each pane tracks its own cursor and directory
  • w collapsing to single-pane mode (active pane fills the full width) and back
  • Incremental search (/) and sort cycling (s) inside the active pane
  • A live status bar showing the active pane label and current layout mode
  • DualPaneOutcome::Selected — selecting a file prints its path to stdout and exits

Demo Quick Reference

Demo Command Highlights
Navigation + Search cargo run --example basic All key bindings, search, sort, selection
Extension filter cargo run --example basic -- rs toml Dimmed non-matching files, footer status
Incremental search cargo run --example basic/ Live filtering, backspace, Esc behaviour
Sort modes cargo run --example basics Three modes, combined with search
Dual-pane (library) cargo run --example dual_pane DualPane widget, Tab focus, w toggle, status bar
Dual-pane (right dir) cargo run --example dual_pane -- /tmp Independent left/right starting directories
File operations cargo run --bin tfe Copy, cut, paste, delete, overwrite modal
Theme switcher cargo run --example theme_switcher 27 live themes, sidebar catalogue
Pane toggle cargo run --bin tfe Tab focus-switch, w single/two-pane, T theme panel
Dual-pane GIF vhs examples/vhs/dual_pane.tape Full dual_pane example recorded end-to-end

CLI Usage

tfe [OPTIONS] [PATH]
Flag Description
[PATH] Starting directory (default: current directory)
-e, --ext <EXT> Only select files with this extension (repeatable)
-H, --hidden Show hidden dot-files on startup
-t, --theme <THEME> Colour theme — see --list-themes
--list-themes Print all 27 available themes and exit
--show-themes Open the theme panel on startup (T toggles it at runtime)
--single-pane Start in single-pane mode (default is two-pane; toggle at runtime with w)
--print-dir Print the parent directory of the selected file instead of the full path
-0, --null Terminate output with a NUL byte (for xargs -0)
--cd Enable cd-on-exit: on dismiss, print the active pane's directory to stdout (persisted)
--no-cd Disable cd-on-exit (persisted)
--init <SHELL> Install the shell wrapper for cd-on-exit and exit. Shells: bash, zsh, fish, powershell
-h, --help Show help
-V, --version Show version

Exit codes

Code Meaning
0 File selected — path printed to stdout
0 Dismissed with --cd enabled — active pane's directory printed to stdout
1 Dismissed without --cd — nothing printed
2 Bad arguments or I/O error

Shell integration (cd on exit)

The killer feature: press Esc or q to dismiss tfe and your terminal automatically cds to whichever directory you were browsing. Works on macOS, Linux, and Windows.

This is opt-in — two one-time steps to enable:

Step 1 — enable the feature (persisted across sessions):

tfe --cd

Run tfe --no-cd at any time to turn it off again.

Step 2 — install the shell wrapper (once per shell):

tfe --init bash        # writes to ~/.bashrc
tfe --init zsh         # writes to ~/.zshrc
tfe --init fish        # writes to ~/.config/fish/functions/tfe.fish
tfe --init powershell  # writes to $PROFILE  (Windows / cross-platform pwsh)

--init appends the wrapper to your rc file (creating it and any missing parent directories if needed), is idempotent — running it twice will not duplicate the snippet — and tells you where it wrote. Then restart your shell or source the rc file as instructed.

How it works:

Situation stdout exit code
File selected (Enter / l) selected file path 0
Dismissed (Esc / q) + --cd enabled active pane's directory 0
Dismissed + --cd disabled (default) (nothing) 1

The TUI renders on stderr so it is never swallowed by the shell's $() capture — the path on stdout is all the wrapper ever sees.

The installed wrapper captures whichever path was printed and calls cd on it.

# Open the selected file in $EDITOR (bypasses the wrapper)
command tfe | xargs -r $EDITOR

# Select a Rust source file and edit it
command tfe -e rs | xargs -r nvim

# Start with the Catppuccin Mocha theme and the theme panel open
tfe --theme catppuccin-mocha --show-themes

# Start in single-pane mode (useful for narrow terminals)
tfe --single-pane

# List all available themes
tfe --list-themes

# NUL-delimited output (safe for filenames with spaces or newlines)
command tfe -0 | xargs -0 wc -l

Theme names are case-insensitive and hyphens/spaces are interchangeable:
catppuccin-mocha, Catppuccin Mocha, and catppuccin mocha all resolve to the same preset.


Public API

The public surface is intentionally narrow for stability:

Single-pane

Item Kind Description
FileExplorer struct Core state machine — cursor, entries, search, sort state
FileExplorerBuilder struct Fluent builder for FileExplorer
ExplorerOutcome enum Result of handle_keySelected, Dismissed, Pending, Unhandled
FsEntry struct A single directory entry (name, path, size, extension, is_dir)
SortMode enum Name | SizeDesc | Extension
Theme struct Colour palette with builder methods and 27 named presets
render fn Render one pane using the default theme
render_themed fn Render one pane with a custom Theme
entry_icon fn Map an FsEntry to its Unicode icon
fmt_size fn Format a byte count as a human-readable string (1.5 KB)

Dual-pane

Item Kind Description
DualPane struct Owns left + right: FileExplorer; routes keys; manages focus and single-pane mode
DualPaneBuilder struct Fluent builder for DualPane — independent dirs, shared filter/sort/hidden
DualPaneActive enum Left | Right — which pane has focus; .other() flips it
DualPaneOutcome enum Result of DualPane::handle_keySelected, Dismissed, Pending, Unhandled
render_dual_pane fn Render both panes using the default theme
render_dual_pane_themed fn Render both panes with a custom Theme

Module Layout

Library (src/lib.rs re-exports)

Module Contents
types FsEntry, ExplorerOutcome, SortMode — data types only, no I/O
palette Palette constants + Theme builder + 27 named presets
explorer FileExplorer, FileExplorerBuilder, entry_icon, fmt_size
dual_pane DualPane, DualPaneBuilder, DualPaneActive, DualPaneOutcome
render render, render_themed, render_dual_pane, render_dual_pane_themed — pure rendering, no state

Because rendering is fully decoupled from state, you can slot either widget into any Ratatui layout, render it conditionally as an overlay, or build a completely custom renderer by reading FileExplorer's public fields directly.

Binary (tfe CLI, not part of the public library API)

Module Contents
main Cli struct (argument parsing), run(), run_loop() — thin entry-point only
app App state, Pane, ClipOp, ClipboardItem, Modal, handle_event
ui draw(), render_theme_panel(), render_options_panel(), render_nav_hints(), render_nav_hints_spans(), render_action_bar(), render_action_bar_spans(), render_modal()
fs copy_dir_all(), resolve_output_path()
persistence AppState, load_state(), save_state(), resolve_theme_idx()
shell_init Shell, detect_shell(), snippet(), rc_path_with(), is_installed(), install(), install_or_print()

Generating Demo GIFs

Install VHS then run:

# Generate all GIFs at once (requires just)
just vhs-all

# Or individually
vhs examples/vhs/basic.tape
vhs examples/vhs/search.tape
vhs examples/vhs/sort.tape
vhs examples/vhs/filter.tape
vhs examples/vhs/file_ops.tape
vhs examples/vhs/theme_switcher.tape
vhs examples/vhs/pane_toggle.tape
vhs examples/vhs/dual_pane.tape

GIFs are written to examples/vhs/generated/ and tracked with Git LFS.

Tape Demo Command
basic.tape Navigation, search, sort, hidden-file toggle, selection cargo run --example basic
search.tape Full incremental search lifecycle cargo run --example basic
sort.tape Name → Size ↓ → Extension cycling cargo run --example basic
filter.tape Extension filter — selectable vs dimmed files cargo run --example basic -- rs toml
file_ops.tape Copy, cut, paste, delete, overwrite modal cargo run --bin tfe
theme_switcher.tape Live cycling of all 27 themes with sidebar cargo run --example theme_switcher
pane_toggle.tape Tab focus-switch, w single/dual, T theme panel cargo run --bin tfe
dual_pane.tape DualPane library widget — Tab, w, status bar cargo run --example dual_pane

Development

Prerequisites

  • Rust 1.75.0 or later (MSRV)
  • just — task runner
  • git-cliff — changelog generator
  • vhs — GIF recorder (optional, for demos)
just install-tools

Common tasks

just fmt          # format code
just clippy       # run linter (zero warnings enforced)
just test         # run tests
just check-all    # fmt + clippy + test in one shot
just doc          # build and open docs

just bump 0.3.6   # interactive version bump + tag
just release 0.3.6 # non-interactive: bump + commit + tag + push (triggers CI release)

just vhs basic           # record a single demo GIF
just vhs-all             # record all demo GIFs

just --list       # see all available commands

License

MIT — see LICENSE for details.


Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.


Acknowledgments

Built for the Ratatui ecosystem.
Special thanks to the Ratatui team for an outstanding TUI framework.