argv-todo 0.1.0

A Vim-style terminal todo manager with nested tasks, priorities, search, and local SQLite storage
argv-todo-0.1.0 is not a library.

argv-todo

A small terminal todo app with Vim-style keys, nested tasks, and local SQLite storage. Built with Rust, Ratatui, and Crossterm.

  • Keep parents and children together in one task tree.
  • Choose normal or split todo/completed layouts in Settings.
  • Create and edit tasks inline, with three priority levels and saved sibling order.
  • Search titles, complete subtrees, and undo deletions.
  • Use Unicode text, bracketed paste, and your terminal's color palette.

Contributing · Support · Changelog · MIT license

Install

After the first crates.io release, install with:

cargo install argv-todo --locked
argv-todo

To install before publication, or build a local checkout, use the source instructions below.

From source

A current stable Rust toolchain and a C compiler are required to build. SQLite is bundled; no SQLite server or system SQLite installation is required.

On macOS, install the Xcode Command Line Tools with xcode-select --install. On Windows, use the Rust MSVC toolchain and Visual Studio Build Tools with the Desktop development with C++ workload.

git clone https://github.com/argv-tech/argv-todo.git
cd argv-todo
cargo install --path . --locked
argv-todo

Ensure Cargo's binary directory is on your PATH (~/.cargo/bin on Linux and macOS, %USERPROFILE%\\.cargo\\bin on Windows).

Run

cargo run --locked

An interactive terminal is required. The app uses the full terminal and shows task rows at 35 columns × 12 rows or larger. Press ? for help and q to quit.

Run in Terminal or iTerm2 on macOS, or Windows Terminal with PowerShell or Command Prompt on Windows. Linux and macOS use bracketed paste; Windows uses native console text input because Crossterm 0.29 does not parse bracketed-paste events there. Paste a single line into Windows input fields; a pasted newline acts as Enter.

Storage

Changes are saved immediately. The app creates its config directory, config.toml, and database on first launch:

Platform Default database
Linux ~/.config/argv-todo/db.sql
macOS ~/Library/Application Support/argv-todo/db.sql
Windows %APPDATA%\argv-todo\db.sql

Linux honors XDG_CONFIG_HOME. Despite its .sql extension, db.sql is a binary SQLite database. SQLite may create db.sql-wal and db.sql-shm beside it while running.

For an existing database, pass its current path with --db or move it to the new default location before launching.

Close the app before moving or backing up a database. Keep any remaining db.sql-wal and db.sql-shm files together with db.sql. Task data is stored without application-level encryption.

Override the location when needed:

argv-todo --db /path/to/tasks.sql
argv-todo --help
argv-todo --version

Configuration

config.toml lives beside the default db.sql in the platform config directory. With --db, the app reads or creates config.toml beside the specified database instead, keeping development settings separate.

The generated config contains:

database_path = "db.sql"
task_view = "normal"

Set database_path to an absolute path or a path relative to the config's directory. --db takes precedence over this setting. Changing the setting selects a database; it does not move existing tasks. The config stays in its original directory even when the database path points elsewhere.

For Windows paths in TOML, use literal strings such as database_path = 'C:\Users\example\task storage\db.sql', or forward slashes such as database_path = "C:/Users/example/task storage/db.sql".

The app reads settings on startup and when opening configuration, preserving existing config files and comments. An empty config uses db.sql and the normal task view. Invalid TOML, unknown settings, invalid layout names, and invalid database paths produce an error before the terminal interface opens. --help and --version do not create files.

Press Esc from the task view to open configuration. Use j / k, arrows, or Tab to select a setting. At 74 columns or wider, the screen shows settings on the left and details for the selected setting on the right. Selecting database_path shows database and configuration-file paths; selecting task_view shows the active layout, its controls, and a small layout preview when space permits. Details update as you select or change a setting. Smaller terminals stack these sections and keep the details concise. Paths wrap in spacious panes and show an ellipsis when space is limited. The screen shows the ARGV-TODO ASCII logo when space permits. On database_path, press Enter, e, or i to edit, then Enter to save. Editing uses the same Unicode controls and paste support as task titles. Database-path changes apply on the next launch; the current database stays open, and --db retains precedence.

On task_view, press Enter, e, i, h / l, or Left / Right to switch between normal and split. The choice saves to TOML and applies immediately. Press Esc to return to tasks without restarting. Normal keeps the full task tree. Split shows unfinished todos on the left and completed tasks on the right, stacking them below 74 columns. Unfinished ancestors of completed children appear in the Completed pane as dimmed ghost rows labeled (parent). These rows provide context and are skipped by selection and task commands. An obsolete nested setting falls back to Normal.

In Split, Tab or Shift-Tab switches pane focus. Each pane keeps its own selection and scroll position; task commands operate on the focused pane. Completing or reopening a task moves it to the corresponding pane and keeps it selected. Search filters both panes. Tab leaves focus in an active editor while typing.

A database preview labeled “after restart” appears below the active database when the draft or saved setting resolves to a different path. Relative paths resolve against the config directory. The preview updates while editing; --db still takes precedence on launch.

While editing configuration, Esc discards the draft and returns to the configuration view. Press Esc again to return to tasks. In the task view, Esc first cancels active input, closes help, or clears an applied search; press it again to open configuration.

Keys

Key Action
j / k Next / previous visible row in the task tree (also Up / Down)
Tab, Shift-Tab Switch panes in Split; select a setting in configuration
l Expand and select the first child; stay selected if there are none
h Select the parent task
gg / G First / last task
3j, 2k Repeat a motion
i, a Add a child of the selected task; add a root task when the list is empty
o, O Add a sibling below or above the selected task; add a root task when the list is empty
e, cc Edit selected task
t Cycle priority: low → mid → high → low
ph, pm, pl Set priority to high, mid, or low
Ctrl-p Cycle priority, including while creating or editing inline
Enter Collapse or expand the selected task's children
Space, x Toggle the selected task and all its descendants in normal mode
dd, 3dd Delete one / three tasks and all their children starting at selection
u Restore the last deleted task tree(s) in the current session
/ Search all titles, ignoring case; keep ancestors visible for context
? Open help; press again to close
Esc Open configuration; close help or clear applied search first. In a field, return to Normal, then press again to cancel
Ctrl-r Reload tasks from disk
q, Ctrl-c Quit

Help covers task navigation, task changes, search, and settings. It uses the same full-screen branding and spacing as settings. On spacious terminals, choose a section in the guide with j / k or arrows; its shortcuts appear on the right. Tab / Shift-Tab cycles sections, and gg / G or Home / End selects the first / last section. Selection stays in the guide. Use PgUp / PgDn to scroll the selected section.

Section titles are bold, uppercase, and spaced apart. Narrow or short terminals show all shortcuts in one scrolling column: use j / k or arrows to scroll, PgUp / PgDn to move a page, and gg / G or Home / End to jump to the beginning or end. Keys and descriptions align in wider panes and stack in narrow ones. A scrollbar and row range show your position. Esc or ? closes help; the close hint stays visible.

Every input field—task titles, search, and the configuration database path—supports Insert, Normal, Visual, Visual Line, and Replace modes. Fields open in Insert, where letters are text. Esc returns to Normal without closing the field; another Esc cancels it. In Visual or Replace, Esc also returns to Normal. When a command is pending, Esc cancels the command first. Enter saves or applies search from any field mode. The footer shows the mode and pending command; Visual selections use reverse video.

Field keys Action
i, a, I, A Insert before the cursor, after it, before the first nonblank, or at the end
h, l, arrows, 0, ^, $, Home, End Move left/right or to the start, first nonblank, or end
w, b, e; W, B, E; ge, gE Move by word or space-separated WORD, including word ends
gg, G, 3|, % Field start/end, display column, or matching bracket
f, F, t, T followed by a character Find or stop just before/after a character, forward/backward
;, , Repeat the last find, or reverse it
d, c, y followed by a motion or text object Delete, change and enter Insert, or yank
dd, cc, yy Delete, change, or yank the whole field
iw, aw, iW, aW after an operator or in Visual Inner/around word or WORD; around includes adjacent whitespace
i/a followed by (, ), [, ], {, }, <, >, quotes, or backtick Inside/around matching delimiters; b aliases parentheses and B braces
v, V, o Character Visual, whole-field Visual, or swap selection ends
Visual d, c, y, r + character Delete, change, yank, or replace the selection
x, X, D, C, s, S Delete at/before the cursor, delete/change to the end, substitute characters, or change the whole field
r2, 3r2, R Replace one/three graphemes with 2, or enter Replace mode
p, P Put the session's yank buffer after/before the cursor, or replace a Visual selection
u, Ctrl-r, . Undo, redo, or repeat the last field change
gu, gU, g~ + motion/object; Visual u, U, ~ Lowercase, uppercase, or swap case

Motions and operators accept counts: 3dw deletes three words and 2d3w deletes six. Counts are capped at 9999. Nested bracket objects accept a count to choose an enclosing pair, such as d2i{. These are single-line fields: dd clears the current field while task-list dd still deletes task trees. Vertical motions stay in the field. The supported commands above cover field editing; Vim's file, window, Ex-command, macro, and block-Visual features are outside this editor.

While typing, arrow keys, Home, and End move the cursor; Ctrl-Left / Ctrl-Right move by word. Backspace, Delete, Ctrl-w, and Ctrl-u edit text. Replace-mode Backspace restores the overwritten grapheme. Insert/Replace sessions undo as one change. Ctrl-p cycles task priority in any task-field mode. Bracketed paste inserts text, puts it after the cursor in Normal, or replaces a Visual selection. Newlines and other control characters become spaces. Editing and selection respect Unicode grapheme boundaries and display widths.

Tasks can contain nested child tasks. j / k moves through visible rows at every level; use h / l to select the parent or first child. Enter hides or reveals descendants without changing task data; a + beside the child count marks a collapsed branch. Collapse state lasts for the current session and is shared across panes. Starting a search expands branches so hidden tasks can appear in the results. Existing databases are upgraded automatically, keeping existing tasks at the top level. Deleting a parent also deletes its descendants; u restores the entire tree. Completing or reopening a parent gives all its descendants the same state, including tasks hidden by search. Toggling a child affects its own subtree without changing its ancestors or siblings. Changes are saved atomically.

Tasks have high, mid, or low priority; new roots and existing tasks default to mid. New children inherit their parent's priority. Siblings created with o or O start with the selected task's priority so they appear beside it. Roots and children within each parent are sorted high first, then mid, then low. Equal priorities keep their saved sibling order, including insertion above or below. Changing a priority keeps the task selected, and children stay with their parent. Priorities and sibling order are saved in SQLite and preserved by deletion undo.

The fullscreen interface uses your terminal's background and ANSI color palette. Tasks occupy one row each, with bold parents and indented connecting branches. A small cyan caret and an underlined title mark the selection; checkmarks and tree lines use normal text color and turn cyan when selected. Focus and completion preserve title and priority colors; a checkmark and a struck-through title identify completed tasks. A done/total count beside a parent shows its direct children. Long titles show an ellipsis so the count stays visible, without splitting Unicode graphemes. The header shows the app name, version in red, and completion count. Short key hints stay at the bottom and fit the available width; input and errors appear when needed. Help keeps its scroll and close instructions visible. Layout and key hints adapt to the terminal size.

Create and edit tasks directly in the tree. A new draft appears at its sorted position among siblings or directly beneath a parent when creating its first child. Ctrl-p changes the draft priority and its position before saving. Starting a new task clears search to show its context. Enter saves the inline row; Esc enters Normal and another Esc cancels it. Search stays at the bottom and remains live in every field mode.

Check

cargo fmt --check
cargo test --locked
cargo clippy --locked --all-targets -- -D warnings
cargo build --locked

CI runs these checks on Linux, macOS, and Windows for pull requests targeting main or dev. Pushing a v* tag runs the same checks and builds release binaries before publishing platform archives named with their Cargo version, such as argv-todo-0.1.0-linux.tar.gz, to a GitHub release. The test and build workflows also support workflow_call for reuse and manual runs. The manual Publish to crates.io workflow validates the package by default and uploads it when dry-run is disabled; see the maintainer guide for setup and local publishing commands.

For a local test session, use cargo run --locked -- --db ./target/dev/db.sql to keep development tasks separate from your personal database.

Keyboard input and Unicode editing live in src/vim_motion, following the action-based structure of argvcode. See CONTRIBUTING.md and AGENTS.md for development guidance, and the maintainer guide for repository setup and releases.

Community

Use GitHub issues for reproducible bugs, focused feature proposals, and questions. Follow the Code of Conduct, and report vulnerabilities through the process in SECURITY.md.

License

argv-todo is licensed under the MIT license.