dunders — Norton Commander–style terminal file manager, text editor, and LLM-agent CLI built on Textual.
Project description
dunders
Terminal · Your · Universal · Intelligence
A Norton Commander–style terminal file manager, text editor, and LLM-agent CLI for the modern shell — built on Textual.
The name dunders is the four QWERTY keys right after qwery — picked in the
same spirit as vim's hjkl. The CLI command is dunders.
dunders brings back the dual-pane workflow of mc / Far Manager — but with a
real windowing layer (Turbo Vision–inspired), code folding, recordable
macros, a command palette, and an embedded LLM/agent CLI mode.
Status: alpha. Core file-manager and editor are usable; agent/CLI mode is a stub.
Quick install (any OS — one line)
Installs uv if you don't have it, then installs
dunders (plus the __ / __w launchers) into an isolated environment — no
system Python needed.
Linux / macOS / WSL (bash/zsh):
curl -LsSf https://astral.sh/uv/install.sh | sh && export PATH="$HOME/.local/bin:$PATH" && uv tool install --force git+https://github.com/tumikosha/dunders.git
Windows (PowerShell):
irm https://astral.sh/uv/install.ps1 | iex; $env:Path = "$env:USERPROFILE\.local\bin;$env:Path"; uv tool install --force git+https://github.com/tumikosha/dunders.git
Then run dunders. (Already have uv? Just uv tool install git+https://github.com/tumikosha/dunders.git.)
Features
- Dual-pane file manager with sort, multi-select, quick-search, and the classic NC F-key bar (F3 view, F4 edit, F5 copy, F6 move, F7 mkdir, F8 delete, F9 menu, F10 quit).
- Embedded text editor with split view, search & replace, fold-by-indent, and bracket/region folding rules.
- Recordable macros with persistent storage.
- Hex viewer for binary or large files (mmap-backed, switches in automatically above 4 MiB).
- Turbo Vision–style windowing layer (
dunders.windowing) — reusable in other Textual apps. Tile, cascade, maximize, modal dialogs, command palette, themable via YAML. - Mouse support everywhere, including the menu bar and status bar.
- LLM agent / CLI mode (in progress) — bring your own model.
Install
Zero-Python install via uv (recommended)
uv is a single static binary. It installs Python for you, then installs
dunders into an isolated environment and puts the dunders command on your
PATH. No system Python required.
# 1. Install uv (one-liner, no Python needed)
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS / Linux
# Windows PowerShell:
# powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# Or via package manager: brew install uv / pipx install uv / scoop install uv
# 2. Install dunders (uv fetches Python 3.12+ automatically if missing)
uv tool install dunders
# 3. Run
dunders
Try it once without installing:
uvx --from dunders dunders # downloads, runs in a temp env, then forgets
Upgrade / uninstall:
uv tool upgrade dunders
uv tool uninstall dunders
If you already have Python 3.12+
pipx install dunders # preferred — isolated, on $PATH
# or, inside an active venv:
pip install dunders
Requires Python 3.12+ in any path above.
Usage
dunders # two-panel file manager (default)
dunders path/to/dir # file manager seeded at a directory
dunders path/to/file # open a file in the editor
dunders --cli # agent / CLI mode (stub)
Short launchers
Two extra console scripts are installed alongside dunders, differing only in
how embedded shell commands hand off the terminal:
| Command | Terminal mode | Platform |
|---|---|---|
__ |
relay — persistent relay subshell | Linux / macOS |
__w |
suspend — suspend + subprocess, no persistent session | cross-platform (use this on Windows) |
Both take the same arguments (files open in cascaded editor windows; a lone
directory or no args open the mc-style file manager) and accept --suspend
explicitly; __w is just __ --suspend.
Inside the app:
| Key | Action |
|---|---|
F3 |
View file (hex if binary/large) |
F4 |
Edit file |
F5 / F6 |
Copy / Move selected items |
F7 / F8 |
Mkdir / Delete |
F9 / F10 |
Menu / Quit |
Tab |
Switch panel |
Shift+Tab |
Cycle desktop windows |
Alt+L / Alt+R |
Focus left / right panel |
Ctrl+K |
Command palette |
Editor-scoped keys (Save, Find/Replace, Split, Fold, Record macro) appear in the status bar when an editor window has focus.
Development
git clone https://github.com/tumikosha/dunders dunders
cd dunders
uv sync --extra dev # or: pip install -e '.[dev]'
pytest # full suite
pytest -k fold_engine # by keyword
ruff check
The repository ships a standalone windowing demo to exercise the framework without the file-manager layer:
python -m dunders.windowing.demo
Project layout
The PyPI distribution is named dunders; the importable Python package and
the CLI command are both dunders.
dunders/
├── app.py # DundersApp shell — wires menus, panels, dispatcher
├── main.py # entry point (argparse)
├── fm/ # file-manager domain (panels, dialogs, file ops)
├── windowing/ # Turbo Vision–style framework on Textual
│ ├── core/ # buffer, fold engine, macros, search
│ ├── editor/ # embeddable editor widget + content
│ ├── themes/ # palette loader + modern_dark default
│ └── demo/ # standalone framework demo
├── themes/ # dark.yaml / light.yaml palettes
└── config/defaults.py
See CLAUDE.md for an architecture deep-dive aimed at
contributors and AI coding assistants.
Terminal limitations on macOS
macOS Terminal.app does not report several modifier+key combinations to
the application, so some editor shortcuts can't reach dunders there:
Shift+↑/Shift+↓/Shift+Home/Shift+End— selection by line / to start/end of line. Terminal.app sends the same sequence as the unmodified key, so the selection variant never arrives.Cmd+C,Cmd+↑/Cmd+↓— the terminal interceptsCmdshortcuts itself and never forwards them.
You can confirm what your terminal sends with cat -v (press the combo, then
Ctrl+C to quit): if Shift+↑ prints ^[[A (same as plain ↑) the modifier
is being dropped.
Two fixes:
-
Use a terminal that supports the kitty keyboard protocol — iTerm2, Ghostty, Kitty, WezTerm. These deliver
Shift+arrowsandCmd+arrows/Cmd+Cout of the box, no configuration needed. (Recommended.) -
Remap the keys in Terminal.app — Settings → Profiles → your profile → Keyboard → +, with Action Send Text (
\033is the Esc character):
| Key | Modifier | Send Text |
|---|---|---|
↑ |
Shift | \033[1;2A |
↓ |
Shift | \033[1;2B |
Home |
Shift | \033[1;2H |
End |
Shift | \033[1;2F |
Cmd+C can't be remapped this way (Terminal.app keeps it for its own Copy). In
the editor and command line use Ctrl+C to copy instead — in the command line
Ctrl+C copies the current selection and otherwise cancels/clears, like a
shell.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dunders-0.1.0.tar.gz.
File metadata
- Download URL: dunders-0.1.0.tar.gz
- Upload date:
- Size: 183.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f46b995d1ff9c0c035b64315fc93ad969b489322ae824d02271ad8a6dff6930e
|
|
| MD5 |
e437df2d9d25ddcff9f465315cdaa10f
|
|
| BLAKE2b-256 |
89aeca1705c24f8e99ea295ab63ba9c328fec1a6464ca3d9e00755ba632ef21f
|
File details
Details for the file dunders-0.1.0-py3-none-any.whl.
File metadata
- Download URL: dunders-0.1.0-py3-none-any.whl
- Upload date:
- Size: 228.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8be685512af2a7a9fba77956f49794b53edac393867fdb6103461c63151d8c2c
|
|
| MD5 |
c959a28d440a6a467d3fc6fc818357cd
|
|
| BLAKE2b-256 |
ae8a80e8a20438769774a85b1628a9d97a2ccdc0166741432a4c54099cf2da08
|