TUI
The TUI module provides an interactive terminal interface for browsing, filtering, and acting on TODO comments. Built on ratatui and crossterm.
run
#![allow(unused)]
fn main() {
pub fn run(
todos: Vec<TodoComment>,
github_config: &GitHubConfig,
repo_root: &Path,
) -> Result<(), TowlTuiError>
}
Launches the interactive TUI. Takes ownership of the terminal (raw mode, alternate screen). Terminal state is always restored on exit, even on error.
Errors:
TowlTuiError::Io– Terminal I/O failure
App
#![allow(unused)]
fn main() {
pub struct App {
// private fields
}
}
Core TUI application state. Manages the TODO list, selection set, cursor position, filtering, sorting, and mode transitions.
Constructor
#![allow(unused)]
fn main() {
pub fn new(todos: Vec<TodoComment>) -> Self
}
Creates a new app with all TODOs visible, no selection, sorted by file path.
State Accessors
| Method | Returns | Description |
|---|---|---|
todos() | &[TodoComment] | Full TODO list |
filtered_indices() | &[usize] | Indices into todos() after filtering/sorting |
cursor() | usize | Current cursor position in filtered list |
filter_type() | Option<TodoType> | Active type filter (None = show all) |
sort_field() | SortField | Current sort field |
sort_ascending() | bool | Sort direction |
is_selected(idx) | bool | Whether a TODO index is selected |
selected_count() | usize | Number of selected TODOs |
selected_todos() | Vec<TodoComment> | Cloned copies of selected TODOs |
mode() | &AppMode | Current UI mode |
Navigation
| Method | Effect |
|---|---|
move_up() | Move cursor up (clamped to 0) |
move_down() | Move cursor down (clamped to list end) |
Selection
| Method | Effect |
|---|---|
toggle_select() | Toggle selection on cursor item |
select_all_visible() | Select all items in filtered view |
deselect_all() | Clear all selections |
Filtering and Sorting
| Method | Effect |
|---|---|
cycle_filter() | Cycle: All -> TODO -> FIXME -> HACK -> NOTE -> BUG -> All |
cycle_sort() | Cycle: File -> Line -> Priority -> Type -> File |
reverse_sort() | Toggle ascending/descending |
Mode Transitions
| Method | Transition |
|---|---|
enter_confirm() | Browse -> Confirm (requires selection) |
cancel_confirm() | Confirm -> Browse |
start_creating() | Confirm -> Creating |
finish_creating() | Creating -> Done |
enter_peek() | Browse -> Peek (loads source context) |
exit_peek() | Peek -> Browse |
AppMode
#![allow(unused)]
fn main() {
pub enum AppMode {
Browse,
Peek(PeekState),
Confirm,
Creating(CreatingState),
Done(DoneState),
DeleteConfirm(Vec<TodoComment>),
}
}
The current UI mode determines which view is rendered and which keys are active.
| Mode | View | Input |
|---|---|---|
Browse | Scrollable TODO list | Navigate, select, filter, sort, peek |
Peek | Source code overlay around a TODO | Scroll, dismiss |
Confirm | Summary of selected TODOs | Confirm or cancel |
Creating | Progress indicator during issue creation | None (Ctrl+C to abort) |
Done | Results summary (issues created, errors) | Dismiss to exit |
DeleteConfirm | Confirmation dialog for deleting invalid TODOs | Confirm or cancel |
SortField
#![allow(unused)]
fn main() {
pub enum SortField {
File,
Line,
Priority,
Type,
}
}
Field used to sort the TODO list. Cycle with the s key in Browse mode.
- File – Sort by file path, then by line number within each file
- Line – Sort by line number globally
- Priority – Sort by TODO type priority (Bug=1, Fixme=2, Hack=3, Todo=4, Note=5)
- Type – Sort alphabetically by type name
Supporting Types
PeekState
#![allow(unused)]
fn main() {
pub struct PeekState {
pub lines: Vec<(usize, String)>,
pub file: String,
pub todo_line: usize,
pub scroll: usize,
pub analysis: Option<AnalysisResult>,
}
}
State for the source-code peek overlay. Contains numbered source lines around the TODO, with scroll position. When --ai is active, analysis holds the LLM result – the reasoning text is word-wrapped to the popup width during rendering.
CreatingState
#![allow(unused)]
fn main() {
pub struct CreatingState {
pub phase: String,
pub progress: usize,
pub total: usize,
pub errors: Vec<String>,
pub created_issues: Vec<CreatedIssue>,
}
}
State tracked during background GitHub issue creation. Updated via channel messages from the spawned task.
DoneState
#![allow(unused)]
fn main() {
pub struct DoneState {
pub created_issues: Vec<CreatedIssue>,
pub errors: Vec<String>,
}
}
Final state after issue creation completes, showing results and any errors.
Action
#![allow(unused)]
fn main() {
pub enum Action {
Continue,
Quit,
}
}
Result of processing a keyboard event. Continue keeps the event loop running; Quit exits the TUI.
handle_input
#![allow(unused)]
fn main() {
pub fn handle_input(
app: &mut App,
timeout: std::time::Duration,
) -> std::io::Result<Action>
}
Polls for keyboard input and dispatches to mode-specific handlers. Returns Action::Quit on q, Esc (in appropriate modes), or Ctrl+C.
Errors
#![allow(unused)]
fn main() {
pub enum TowlTuiError {
Io(std::io::Error),
}
}
Terminal I/O errors from crossterm or ratatui operations.