Dual-pane terminal file manager built on the SugarCraft stack β port of yorukot/superfile, with the Midnight Commander look.
ββββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββ
β /home/alice [name-asc] β β /var/log [mtime-desc] β
β ββββββββββββββββββ β β ββββββββββββββββββ β
β βΈ ../ DIR β β ../ DIR β
β Documents/ DIR β β βΈβ syslog 240KB β
β Downloads/ DIR β β auth.log 12KB β
β .config/ DIR β β Xorg.0.log 4.0KB β
β notes.md 12KB β β β
β todo.txt 512B β β β
ββββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββ
Tab swap Β· ββ jk move Β· Enter open Β· β h up Β· space select Β· s sort Β· . hidden Β· d delete Β· r refresh Β· q quit
composer install
./bin/supercandy [LEFT_DIR] [RIGHT_DIR]Default: left pane = current directory, right pane = $HOME.
| Key | Action |
|---|---|
Tab |
Swap focus between panes |
β / k |
Move cursor up |
β / j |
Move cursor down |
Home / g |
Top of listing |
End / G |
Bottom of listing |
Enter / β |
Open directory (or no-op on a file) |
β / h |
Go up one directory |
Space |
Toggle selection on the entry under cursor + advance |
s |
Cycle sort order (name β mtime β size, asc / desc) |
. |
Toggle hidden-file visibility |
d |
Delete (selection or cursor); requires y confirm |
r |
Refresh active pane |
q |
Quit |
The whole transition layer is pure β filesystem I/O is injected as a Closure(string $path): list<Entry> so every transition is unit-testable without tmp dirs or stat fixtures.
| File | Role |
|---|---|
Entry |
Value object: name, isDir, size, mtime, isLink, isHidden |
Sort |
Enum (NameAsc/NameDesc/MtimeAsc/MtimeDesc/SizeAsc/SizeDesc) + comparator |
Pane |
One pane: cwd, entries, cursor, selection set, sort, showHidden |
ConfirmState |
Pending-confirmation enum (None / DeleteSelected) |
Manager |
CandyCore Model β orchestrates two panes, handles all keys + confirm gate |
FsLister |
Default lister: scandir + lstat against the live filesystem |
Renderer |
Pure view function β two pane boxes side-by-side + status line |
- 36 tests / 65 assertions
- Pure-state coverage:
Entry(size formatting, parent sentinel),Sort(every order Γ dirs-first Γ cycle),Pane(open / navigate / move / select / sort / hidden toggle / parent-path / join) Managerintegration: Tab swap, key dispatch per pane, confirm gate (darms,yconfirms, anything else cancels), refresh status
Phase 9+ entry #20 β first cut. Read + delete are wired; copy / move / rename / new-dir are obvious next steps. Everything underneath them (the pure-state transition layer) is already in place.
