Skip to content

About

Keyboard-driven dual-panel terminal file manager (Rust / ratatui). Norton Commander–style UI for Windows.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

FileCommand

A keyboard-driven, dual-panel file manager for the terminal, written in Rust (ratatui + crossterm). It recreates the look, layout, and workflow of Norton Commander 5.5 (1998) — blue/cyan panels, double-line frames, a function-key command bar, and an always-available command line — with a small set of modern extras layered on top: quick filter, fuzzy directory jump, panel tabs, git-aware panel info, mouse support, and switchable themes.

Platform: Windows-first (Windows Terminal / PowerShell console / conhost). The codebase stays cross-platform via crossterm, but only Windows is tested and supported.

FileCommand screenshot

Contents

Installing

The easiest way to get FileCommand on Windows is the bundled installer:

  1. Build (or download) FileCommandSetup.exe — see installer/README.md for build instructions, prerequisites (Rust, .NET SDK, WiX v4/v5 CLI), and a winget manifest.

  2. Run it. By default it installs per-user, with no elevation, to %LocalAppData%\Programs\BigHatGroup\FileCommand, adds itself to your user PATH, and creates a Start Menu shortcut.

  3. Open a new terminal window (existing ones won't see the updated PATH) and run:

    filecommand

For an elevated, machine-wide install instead:

FileCommandSetup.exe /quiet InstallScope=perMachine

Silent uninstall:

FileCommandSetup.exe /uninstall /quiet

See installer/README.md for the full scope semantics (per-user vs. per-machine, upgrade behavior, production code signing) and the winget package template.

Building from source

Requires the Rust toolchain (stable).

git clone https://github.com/kkaminsk/FileCommand.git
cd FileCommand
cargo build --release

The binary is produced at target\release\filecommand.exe. Run it directly, or via Cargo:

cargo run --release

The workspace has two crates:

  • filecommand-core — state, the reducer (core::update), file operations, listing/sorting/filtering, git info, config/theme loading. No terminal dependencies; fully unit-testable.
  • filecommand-tui — the filecommand binary: the event loop, rendering, input mapping, and terminal ownership.

Command-line options

Flag Effect
--theme <name> or --theme=<name> Launch with a specific theme for this session, overriding the saved theme = in config.toml. Built-in names: nc-classic, nc-mono, terminal-green, purple-lights, yellow-storm, inverted.
--nosplash Skip the startup splash screen, overriding splash = true in config.toml.
--nomouse Disable mouse capture for this session, overriding [mouse] enabled in config.toml.

Flags can be combined in any order, e.g. filecommand --nosplash --theme=purple-lights.

Configuration

FileCommand reads and writes its files in the current working directory (the directory it's launched from), not a fixed profile directory. Missing files are created with defaults on first run; a malformed file produces a startup warning and falls back to defaults rather than being silently overwritten.

config.toml

Flat key = value lines (not a full TOML parser, aside from the [mouse] table below), one setting per line:

splash = true
theme = "nc-classic"
shell = "cmd.exe /C"
editor = "code -w"
panel_split = 50

[mouse]
enabled = true

key.paste_name = "ctrl+enter"
key.paste_path = "ctrl+]"
key.quick_filter = "ctrl+p"
key.fuzzy_jump = "ctrl+j"
key.split_left = "ctrl+left"
key.split_right = "ctrl+right"
key.split_reset = "ctrl+="
key.clipboard_files = "ctrl+c"
key.clipboard_paths = "ctrl+shift+insert"
Key Meaning Default
splash Show the startup splash screen. true
theme Active theme name (built-in or a file in themes/). nc-classic
shell Shell command line used by the file-action menu's Run entry and the F2 user menu. cmd.exe /C on Windows, /bin/sh -c elsewhere
editor External editor command for F4; unset means "use the built-in editor". unset
panel_split Left-panel width as a percentage. 50
[mouse] enabled Whether mouse capture is enabled at all. true
key.* Overridable key bindings (see table below). see below

Only the bindings listed above are configurable; the rest of the key map (F-keys, Tab, arrows, Ctrl+T/W, etc.) is fixed. Unknown keys are ignored rather than rejected, and the schema tolerates missing/malformed lines.

themes/*.toml

User-defined themes. Each theme maps the role names documented in the design spec (panel.frame, panel.cursor, dialog.primary, ...) to ANSI-16 color names (black, red, green, yellow, blue, magenta, cyan, white, and bright- variants), with an optional per-role #RRGGBB truecolor override. Switch themes at runtime via Options → Themes, or pin one at launch with --theme.

usermenu.toml

F2 user-menu entries — a real TOML array of tables:

[[entry]]
label = "Open command prompt here"
command = "cmd.exe"

[[entry]]
label = "Directory listing"
command = "dir"

Unlike config.toml, a malformed usermenu.toml is treated as an error: it falls back to a default menu and shows a warning rather than being silently overwritten.

history.json

Command-line history and fuzzy-jump directory frecency data, written atomically so a crash mid-write never corrupts it. Not meant to be hand-edited.

Using FileCommand

Screen layout

FileCommand screen layout

  1. Left navigation pane — its own directory, cursor, selection, sort mode, filter, and display mode; the path renders inverse in the top border when this panel is active.
  2. Right navigation pane — independent of the left: its own mode, sort, filter, and tabs, so the two panels can browse entirely different locations at once.
  3. F-key menu — the function-key command bar (1Help 2Menu 3View 4Edit 5Copy 6RenMov 7Mkdir 8Delete 9PullDn 10Quit); clickable with the mouse, and relabels under Ctrl/Alt for their key-bar variants.
  • Two independent panels, each with its own directory, cursor, selection, sort mode, filter, and display mode.
  • Tab switches which panel is active (the active panel's path renders inverse in its top border).
  • The command line sits below the panels and always shows the active panel's path as its prompt. It understands three built-in verbs (cd, del, rmdir) and nothing else — see Command line.
  • Terminal is usable down to a minimum size; below that, panels are replaced with a "terminal too small" placeholder and the F-key bar degrades through progressively shorter forms as width shrinks.
  • The startup splash (product name/version banner) is the very first frame unless --nosplash/splash = false; any key dismisses it early.

Command line

The line just above the F-key bar is an NC-style command line. Its prompt is the active panel's current directory (e.g. C:\Projects\app>), and it follows the active panel: press Tab or change directory and the prompt updates.

The command line is a quick way to navigate and to delete a single item by name. It is not a shell: it never passes text to cmd.exe/PowerShell, and anything other than the three built-in verbs below is rejected. To run programs, see Running programs.

Typing

You don't need to focus the command line. While the panels have the keyboard (no dialog, menu, type-ahead jump, or Ctrl+P quick filter open), every plain printable key is added to the command line and the panel cursor stays put. Text is only ever added at the end; there is no cursor to move within the line.

Some keys mean different things depending on whether the line is empty:

Key Line empty Line has text
Printable character Starts the line Added to the end
+ / - / * Select / deselect by wildcard, invert selection Typed as text
Backspace Go to the parent directory Delete the last character
↑ / ↓ Move the panel cursor Recall older / newer history
Enter Act on the cursor entry (open a directory, file-action menu for a file) Run the line
Ctrl+Enter / Ctrl+] Paste the cursor entry's name / full path Same, after a separating space
Esc Ask to quit Ask to quit (cancelling keeps your text)

All other keys keep their panel meaning while you type. Home/End and PgUp/PgDn move the panel cursor, and Tab switches panels without clearing the line. Delete opens the delete confirmation for the cursor entry; it does not delete a character. To clear the line, backspace it until it's empty.

Built-in commands

Command What it does
cd <path> Navigates the active panel to <path>. If the target doesn't exist or isn't a directory, the command is rejected and the panel stays where it is.
del <file> Opens the normal F8 delete confirmation for that one file. Rejected if the target is a directory.
rmdir <dir> Opens the normal F8 delete confirmation for that one directory, including the second confirmation if it isn't empty. Rejected if the target is a file.

Rules that apply to all three:

  • Verbs ignore case. CD, Cd, and cd are the same command.

  • Everything after the verb is one argument, so a name with spaces doesn't need quotes. Surrounding double quotes are removed, so cd Program Files and cd "Program Files" both work.

  • Paths resolve against the active panel's directory. These forms are accepted:

    Form Example Resolves to
    Relative cd src\core, cd ..\other Below or beside the current directory
    Current / parent cd ., cd .. Current directory / its parent (cd .. at a drive root is rejected)
    Drive-rooted cd \Temp \Temp on the current drive
    Absolute cd C:\Windows\System32 That exact path
    Bare drive letter cd D: The root of D: (cmd would use D:'s last directory)
    UNC cd \\server\share\dir The network path (this is how you enter a UNC location by hand)
  • One target, no wildcards. del *.tmp looks for a file literally named *.tmp. To delete several items, select them with Ins or + (select by wildcard), then press F8.

  • del/rmdir never delete on their own. They only open the same confirmation dialog as F8, and nothing is removed until you accept it. Deletes are permanent (there's no recycle bin). . and .. are always rejected as targets, so the dialog can never offer to delete the panel's own directory or its parent.

  • A verb needs an argument. A bare cd (no "print current directory" form) is rejected as unrecognized.

Errors

Pressing Enter always clears the line. A rejected command shows its reason in the active panel's bottom-border status line, where it stays until the panel next lists a directory successfully:

Message Cause
'dir' is not a recognized command Anything other than cd / del / rmdir with an argument
C:\Projects\nosuch not found The target doesn't exist
C:\Projects\readme.txt is not a directory cd or rmdir on a file
C:\Projects\docs is a directory del on a directory
rmdir: invalid target .. . or .. given to del / rmdir

History

Each cd that succeeds is saved to the command history in history.json, which keeps the most recent 200 entries. Running a command that's already saved moves it to the newest position. Rejected lines and del/rmdir aren't saved.

Up/Down only recall history while the line has text (on an empty line they move the panel cursor). To browse history from an empty line, type a space and press ↑:

  • Each ↑ steps to an older entry, and each ↓ steps to a newer one.
  • A recalled entry replaces the whole line. History isn't filtered by what you've typed.
  • Pressing ↓ past the newest entry stops recalling and leaves the text as it is.
  • Press Enter to run the recalled entry, or Backspace to edit it.

Pasting names and paths

To fill in a command from the panel instead of typing names:

  • Ctrl+Enter adds the cursor entry's file name to the end of the line.
  • Ctrl+] adds the cursor entry's full path.

If the line doesn't already end in a space, one is added first. For example, to delete the file under the cursor in the other panel's directory:

  1. Type del.
  2. Press Tab, then Ctrl+] to paste the file's full path.
  3. Press Enter.

Ctrl+] works in every terminal. Ctrl+Enter works on Windows, and elsewhere only when the terminal supports the kitty keyboard protocol. You can rebind both with key.paste_name and key.paste_path in config.toml.

Running programs

The command line can't run programs, so dir, notepad notes.txt, and git status are all rejected. There are two ways to launch something:

  • The file-action menu. Press Enter (or right-click) on an executable (any PATHEXT extension, or a .lnk) and choose Run. Enter never starts an executable directly.

  • The F2 user menu. Add an entry to usermenu.toml:

    [[entry]]
    label = "git status"
    command = "git status"

    The command string goes to the configured shell exactly as written, with no placeholder substitution.

Either way, FileCommand suspends its screen and runs the command in the active panel's directory using the shell from config.toml (cmd.exe /C by default; PowerShell adds about 200 ms or more of startup per command). When the command finishes, press a key to return. Afterwards, Ctrl+O hides the panels so you can read the output in your terminal's scrollback, and any key brings the panels back. FileCommand doesn't keep its own copy of command output; only your terminal's scrollback does.

Keyboard reference

Navigation & panels

Key Action
↑ / ↓ / PgUp / PgDn / Home / End Move cursor (page size follows panel height)
Tab Switch active panel
Enter Directory: enter it. ..: go to parent. File: opens the file-action menu (Run/View/Edit/Send to clipboard/Copy/Rename/Move/Delete). Command line non-empty: dispatches the built-in verbs — cd navigates, del/rmdir open delete-confirmation, anything else is rejected. Tree mode: navigate/expand.
Backspace (empty command line) Parent directory
Ctrl+PgUp Parent directory
Ins Toggle selection at cursor, cursor advances
+ / - / * Select by wildcard / deselect by wildcard / invert selection
Alt+letter Start type-ahead jump to the first matching entry
Ctrl+P Toggle the inline quick filter (narrows the panel to a substring match as you type)
Ctrl+J Fuzzy directory-jump dialog (frecency-ranked, persists across sessions)
Alt+F7 Find file
Ctrl+R Re-read (refresh) the active panel
Ctrl+L Toggle Info display mode on the active panel
Ctrl+O Show terminal scrollback (leaves the alternate screen; any key returns)
Ctrl+T / Ctrl+W New tab / close tab on the active panel
Alt+1..9 Switch to tab n on the active panel
Ctrl+←/→ Shrink / grow the left panel (adjust the split)
Ctrl+= Reset the split to 50/50
Alt+F1 / Alt+F2 Drive select for the left / right panel
Ctrl+F3..F6 Sort active panel by Name / Extension / Time / Size
Ctrl+F7 Unsorted (raw enumeration order)

File operations

Key Action
F3 View file under cursor
F4 Edit file under cursor (external editor if configured, else the built-in editor; large files open in the viewer instead)
F5 Copy
F6 Rename/Move
F7 Make directory
F8 Delete (confirmation; a second confirmation for non-empty directories)
Ctrl+C or Ctrl+Ins Copy the cursor entry (or selection) to the Windows clipboard as file objects, pasteable into Explorer
Ctrl+Shift+Ins Copy the cursor entry's (or selection's) absolute path(s) to the clipboard as text
Ctrl+Enter Paste the cursor entry's file name onto the command line
Ctrl+] Paste the cursor entry's full path onto the command line

General

Key Action
F1 Help
F2 User menu (from usermenu.toml)
F9 Open the pull-down menu bar
F10 or Esc Request quit (Y/N confirmation)
Esc (in a dialog/menu/overlay) Cancel or close it
Up / Down (command line non-empty) Recall previous/next command-line history

All of the bindings marked overridable in Configuration (paste_name, paste_path, quick_filter, fuzzy_jump, split_left, split_right, split_reset, clipboard_files, clipboard_paths) can be remapped in config.toml; the rest of the table above is fixed.

Mouse reference

Enabled by default; disable with [mouse] enabled = false or --nomouse. Mouse is only honored in contexts a key press would also reach (panels, the key bar, menu titles/items, and dialog buttons) — it does nothing in the viewer/editor beyond wheel scrolling, and nothing at all while an unsupported overlay (drive select, fuzzy jump, find file, user menu, theme picker, help, startup warning) is open.

Gesture Action
Left click on an entry Focus that panel and move the cursor to the entry
Ctrl+left click on an entry Toggle that entry's selection in place
Double left click on an entry Same as Enter
Left click on empty panel area / title Focus that panel
Right click on an entry Open the file-action menu for it
Left-drag from an entry onto a target Propose a Copy
Right-drag, or Shift+drag, from an entry Propose a Move
Esc during a drag Cancel the drag
Scroll wheel over a panel Scroll 3 lines
Click a key-bar slot Activate that F-key
Click a menu-bar title / pull-down item Open / activate it; clicking outside an open pull-down closes it
Click a dialog button Activate it

Pull-down menus (F9)

Five menus, navigated with ←/→ (between menus), ↑/↓ (within one), Enter, Esc, or a hotkey letter:

  • Left / Right (mirror each other, acting on their own panel): display mode (Brief/Full/Tree/Quick view/Info), sort mode, re-read, drive select, new/close tab.
  • Files: View, Edit, Copy, Rename/Move, Make directory, Delete, copy to clipboard (files/paths/names), Select/Deselect/Invert group, Quit.
  • Commands: Find file, Fuzzy jump, Panels on/off. (History, Swap panels, Compare directories, and Menu file edit are listed but not yet implemented — greyed out.)
  • Options: Themes (opens the live theme picker). (Configuration, Editor selection, and Save setup are listed but not yet implemented.)

Panel display modes

Mode Description
Full (default) Name | Size | Date | Time columns
Brief Three columns of names only
Info (Ctrl+L) Drive/system/directory info instead of a listing
Tree Lazily-expanded directory tree of the current drive; moving the cursor updates the opposite panel's listing
Quick view Live preview (text head) of the file under the opposite panel's cursor

File operations

Copy (F5), Move/Rename (F6), Mkdir (F7), and Delete (F8) run as cancellable background jobs with a progress dialog (file/byte counts, a cancel button). Overwrite conflicts prompt Overwrite/Skip/Rename/Overwrite All/Skip All; errors (permission denied, path too long, disk full, sharing violation) pause the job for Retry/Skip/Skip All/Abort, and skipped files are listed in a summary at the end. Same-volume moves are instant renames; cross-volume moves copy then delete only after the copy verifies. There is no recycle bin — deletes are permanent, and the confirmation dialog says so.

Viewer (F3) and editor (F4)

  • Viewer — read-only, opens instantly at any file size (streams/memory-maps rather than indexing). F2 toggles wrap, F4 toggles text/hex mode, F7 searches, F10/Esc closes.
  • Editor — F4 opens your configured external editor if editor = is set in config.toml; otherwise the built-in editor (files under 10 MB; larger files open in the viewer instead). F2 saves, F3 marks a line-selection anchor, F4 opens search-and-replace, F7 searches, Ctrl+X/C/V cut/copy/paste, Ctrl+Z undoes, F10 quits (prompting to save if modified).

Themes

Six built-in themes: nc-classic (default, the authentic NC palette), nc-mono (black/white), terminal-green, purple-lights, yellow-storm, and inverted. Switch live via Options → Themes (arrow keys preview each theme before you commit) or the F2 user menu; the choice persists to config.toml. Pin a theme for a single session with --theme <name> without touching the saved default.

Project layout

FileCommand/
├── crates/
│   ├── filecommand-core/   # state, reducer, fs ops, git info — no UI deps
│   └── filecommand-tui/    # ratatui + crossterm binary (the `filecommand` exe)
├── installer/              # WiX (v4/v5) MSI + Burn bootstrapper packaging
├── openspec/                # OpenSpec proposals and per-capability specs
│   └── specs/                # source of truth for current behavior
├── docs/superpowers/specs/  # original full design document
└── Screen/                  # screenshots used in this README

Testing

cargo test --workspace

Covers filecommand-core unit and property-based tests (file ops against temp directories, sorting/filtering, selection semantics, config/theme parsing, git info against fixture repos) and filecommand-tui ratatui TestBackend snapshot tests (panels, dialogs, viewer/editor, splash, help, menus) via insta.

Contributing

This project develops behind an OpenSpec-driven, branch-per-change workflow: research and proposals happen on Spec, get merged to main, then each approved proposal is implemented on its own build/<name> branch off main. Nothing lands on main without an explicit human go-ahead. See CLAUDE.md for the full rules.

Reporting issues

Found a bug or want to request a feature? File it on GitHub: https://github.com/kkaminsk/FileCommand/issues

A good report includes:

  • What you did — the keys pressed or command typed, step by step.
  • What happened versus what you expected.
  • Environment — Windows version, terminal (Windows Terminal, conhost, PowerShell), and the FileCommand version shown on the startup splash.
  • Error text — anything shown on the panel's status line or in a job dialog, copied verbatim. The UI is plain text, so pasting the screen works as well as a screenshot.

License

Dual-licensed under MIT or Apache-2.0, at your option.

About

Keyboard-driven dual-panel terminal file manager (Rust / ratatui). Norton Commander–style UI for Windows.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages