一个快速、基于键盘的终端用户界面,用于 todo.txt。
The screenshots in the table above are checked-in SVGs. Regenerate them with:
mise run screenshots
The hero GIF at the top is recorded with vhs from docs/demo.tape. Regenerate it with:
mise run demo## Themes `T` opens a picker over five built-in themes, including Terminal, which respects your terminal palette. | Muted Slate (default) | Dawn | | --- | --- | | | | | **Nord** | **Matrix** | | | | ### Custom themes Beyond the built-ins, tuxedo loads any `*.toml` file you drop in `${XDG_CONFIG_HOME:-$HOME/.config}/tuxedo/themes/`. Each one joins the `T` picker in sorted filename order. Ready-made themes live in [`docs/themes/`](docs/themes) — copy one in and press `T`: ```sh mkdir -p ~/.config/tuxedo/themes curl -o ~/.config/tuxedo/themes/gruvbox-dark-soft.toml \ https://raw.githubusercontent.com/webstonehq/tuxedo/main/docs/themes/gruvbox-dark-soft.toml ``` Theme file format and field reference A theme file is one `key = value` per line. `name` is the label shown in the picker; every other field is a color value. All fields are required: a file missing one, carrying an unparseable color, or whose `name` collides with another theme is skipped with a warning at startup. **Color values** accept two forms: - `#rrggbb` — a solid hex color (case-insensitive). - `reset` or `transparent` — inherits the terminal emulator's own background color. Useful for `bg`, `panel`, and `statusbar` when you want your terminal's opacity, blur, or wallpaper to show through while keeping a custom text palette. Both keywords are case-insensitive and behave identically (same effect as the built-in **Terminal** theme). | Field | Colors | | --- | --- | | `name` | label shown in the `T` picker (the only non-color field) | | `bg` | window background | | `panel` | filter and detail panel background | | `border` | panel and modal borders | | `fg` | primary text | | `dim` | secondary / muted text | | `accent` | logo, headings, hints, and selection markers | | `cursor` | current row, and the highlighted row in the `T` picker | | `selection` | set to the same value as `selected` | | `statusbar` | status bar background | | `status_fg` | status bar text | | `mode_fg` / `mode_bg` | mode chip text / background | | `pri_a` `pri_b` `pri_c` `pri_d` | priorities A through D | | `pri_other` | priorities E through Z | | `project` | `+project` tags | | `context` | `@context` tags | | `due` | `due:` date | | `overdue` | past-due date | | `today` | date due today | | `done` | completed tasks | | `selected` | selected-row background (visual mode) and the active filter | | `matched` | search-match highlight | ## Install ### Homebrew (macOS, Linux) ```sh brew install tuxedo ``` ### Prebuilt binaries Download the archive for your platform from the [latest release](https://github.com/webstonehq/tuxedo/releases/latest) and put `tuxedo` on your `PATH`. Targets: `x86_64-unknown-linux-gnu`, `aarch64-unknown-linux-gnu`, `x86_64-apple-darwin`, `aarch64-apple-darwin`, `x86_64-pc-windows-msvc`. Each archive ships with a `.sha256` checksum. ### From source ```sh cargo install --git https://github.com/webstonehq/tuxedo ``` Or clone and build: ```sh git clone https://github.com/webstonehq/tuxedo cd tuxedo cargo build --release ./target/release/tuxedo [FILE] ``` Requires the Rust 2024 edition (recent stable toolchain). ## Usage `tuxedo` is two things in one binary: an interactive TUI, and a one-shot command line. With no subcommand it launches the TUI; with a recognized subcommand it runs the [command line](#command-line-interface) and exits. ```sh tuxedo [FILE] # launch the TUI on FILE (created if missing) tuxedo # TUI on the default file (see resolution below) tuxedo --sample # open the bundled sample file in the temp dir tuxedo # run a one-shot CLI command — see "Command-line interface" tuxedo update # print upgrade instructions for your install tuxedo --help tuxedo --version ``` When a newer release is available, the status bar shows `↑ (tuxedo update)` next to the version. The check runs in the background, is cached at `$XDG_CACHE_HOME/tuxedo/latest_version.json` for 24 h, and fails silently when offline. Set `TUXEDO_NO_UPDATE_CHECK=1` to disable. ### Which file tuxedo opens Both the TUI and the CLI resolve the todo file the same way, in order: 1. An explicit `FILE` argument (TUI only). 2. `$TODO_FILE`, if set. 3. `$TODO_DIR/todo.txt`, if `$TODO_DIR` is set. 4. `./todo.txt` in the current directory, if it exists. 5. Otherwise the TUI shows a first-run prompt — press `c` to create `./todo.txt` here, or `s` to open a sample todo.txt in the system temp directory so you can poke around without committing to a path. (The one-shot CLI is non-interactive and uses the sample directly.) The archive file is `$DONE_FILE` if set, otherwise a sibling `done.txt` next to the todo file. The file (and any missing parent directories) is created on first use. These are the same `TODO_DIR` / `TODO_FILE` / `DONE_FILE` variables todo.txt-cli uses, so an existing `todo.cfg` works as-is: ```sh export TODO_DIR="$HOME/Documents/todo" export TODO_FILE="$TODO_DIR/todo.txt" export DONE_FILE="$TODO_DIR/done.txt" ``` Edits are persisted on every change via atomic write (write `.tmp`, rename). If the file changes on disk (another editor, a sync client, a script), tuxedo notices on the next keypress, or within ~250 ms while idle, and reloads. The keystroke that triggered the reload is consumed — press it again to act on the fresh state — and the status bar flashes a notice. Pressing `A` appends every completed task to a sibling `done.txt` and removes them from the working file (atomically: `done.txt` is written before the originals are dropped). `a` toggles the archive view so you can browse, un-archive, or permanently delete past tasks. ## Command-line interface When the first argument is a recognized subcommand, tuxedo runs a one-shot command instead of launching the TUI. The surface mirrors [todo.txt-cli](https://github.com/todotxt/todo.txt-cli/wiki/Usage) — same commands, aliases, task numbering, and output — so it's a drop-in for scripts and aliases. ```sh tuxedo add "Pay rent +home @bank due:2026-07-01" # or: tuxedo a "..." tuxedo ls @bank # filter by context tuxedo do 3 # mark task 3 complete tuxedo pri 3 A # set priority tuxedo archive # move done tasks to done.txt tuxedo ls --json | jq . # machine-readable output ``` | Command | Aliases | Arguments | Description | | --- | --- | --- | --- | | `add` | `a` | `TEXT...` | Add a task (natural-language dates supported, same as the `n` prompt). | | `append` | `app` | `N TEXT...` | Append text to task `N`. | | `prepend` | `prep` | `N TEXT...` | Prepend text to task `N`. | | `replace` | | `N TEXT...` | Replace task `N` entirely. | | `pri` | `p` | `N PRIORITY` | Set priority `A`–`Z` on task `N`. | | `depri` | `dp` | `N...` | Remove priority from the given tasks. | | `do` | `done`, `complete` | `N...` | Mark tasks complete (recurring tasks spawn their next instance). | | `del` | `rm` | `N [TERM]` | Delete task `N`, or remove just `TERM` from it. Prompts unless `-f`. | | `archive` | | | Move completed tasks to the done file. | | `list` | `ls` | `[TERM...]` | List tasks. `TERM` is `+project`, `@context`, or free text. | | `listall` | `lsa` | `[TERM...]` | List the todo file and the done file. | | `listpri` | `lsp` | `[PRIORITY]` | List prioritized tasks (optionally a single priority). | | `listproj` | `lsprj` | | List all `+projects`. | | `listcon` | `lsc` | | List all `@contexts`. | **Task numbers** are 1-based line numbers in the file, exactly as printed by `list` — stable regardless of how the list is filtered or sorted. `list` sorts by the full line (case-insensitive) and prints a `TODO: X of Y tasks shown` footer, matching todo.txt-cli. **Options:** - `-f`, `--force` — skip confirmation prompts (e.g. for `del`). - `--json` — emit machine-readable JSON instead of text. `list`-style commands print an array of task objects; mutating commands print a result object. No prompts or footers are written in this mode. Global flags may appear before the subcommand (`tuxedo -f del 3`). **Differences from todo.txt-cli:** `do` marks a task complete but does **not** auto-archive it — completed tasks stay in the file until you