# Copilot instructions for rmptui ## Build, test, and lint - `cargo build` — compile the application. - `cargo run` — run against MPD at `127.0.0.1:6600` by default. - `cargo fmt --check` — check Rust formatting; use `cargo fmt` to format. - `cargo test` — run all unit tests. - `cargo test connection::tests::parses_quoted_mpd_values_and_escapes` — run one named test. Replace the filter with a test name or module path to target another test. - `cargo clippy --all-targets -- -D warnings` — lint all targets and treat warnings as errors. ## Architecture - `src/main.rs` owns the Tokio runtime, reads `MPD_HOST`/`MPD_PORT`, initializes the terminal, and selects between terminal input, redraw ticks, and MPD change notifications. A separate `MpdClient` connection blocks on MPD `idle`, then sends a fresh `MpdSnapshot` to the UI; the app's command connection stays available for user actions. - `src/config.rs` loads or creates the TOML configuration at `$CONFIG_HOME/rmptui/config.toml`, falling back to `$XDG_CONFIG_HOME` and then `~/.config`. The config contains MPD and playback settings plus configurable keybindings; `MPD_HOST` and `MPD_PORT` override its connection defaults. - `src/connection.rs` implements MPD's line-oriented text protocol over Tokio TCP, including command quoting, response/error parsing, and conversion of MPD responses into app models. Keep protocol I/O asynchronous. The client processes a command's complete response before issuing another command on that connection. - `src/app.rs` owns UI/application state and coordinates queue, browser, and playlist operations. `src/browser.rs` represents rows as `BrowserEntry::Directory` or `BrowserEntry::Song`, keeping song metadata with its row. Browser paths are MPD library-relative paths, not local filesystem paths. - `src/event_handler/handler.rs` maps Crossterm events to application operations. `src/ui.rs` renders the current app state with Ratatui; it should not perform MPD I/O. `src/tui.rs` owns terminal mode setup, drawing, and restoration. - `src/list.rs` contains shared list cursor behavior. `src/utils.rs` provides the audio-extension check used by the browser and directory operations. ## Repository conventions - Keep the MPD protocol models and wire-format parsing in `connection.rs`; UI and application code should use those models rather than parse raw MPD responses. - Use the crate-level `AppResult` for errors crossing module boundaries. Avoid duplicating state that can be derived from the MPD status or other canonical model data. - Keep configuration defaults and validation in `config.rs`, and read tunable behavior from `App.config` rather than adding new hard-coded runtime values. Route keyboard actions through `App.config.keybindings`; keep README controls and the generated defaults in sync. Text typed into search/name fields is content, not a keybinding, except for configured input-editing actions. - Pass MPD library paths as protocol arguments. The MPD command writer quotes and escapes each argument, so do not construct raw command strings from user-provided names or paths. - Preserve async boundaries through event handling and app operations; do not introduce blocking socket reads, polling threads, or synchronous terminal polling. - Browser `/` search retains all positive-scoring fuzzy matches in result order. `Enter` returns to normal navigation while retaining browser results; `n` and `N` cycle them. Starting a new search or changing directories resets those results. - When changing key behavior or features, keep the controls documented in `README.md` consistent with `event_handler/handler.rs`. - `AppResult` is `Send + Sync` because application errors cross Tokio task boundaries.