Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## [Unreleased]


### Features

* CLI flags mirroring config settings — `--no-pr`, `--view`, `--no-flash`, `--flash-duration`, `--scroll-padding`, and `--edit-command`. Each overrides the config file (precedence: flag > config > default).


### Removed

* Dead config options `[keys]`, `display.context_lines`, `pr.show_labels`, and the deprecated `pr.layout`. Existing config files using these keys still load — the keys are silently ignored.

## [1.6.0](https://github.com/upsertco/perch/compare/v1.5.1...v1.6.0) (2026-05-29)


Expand Down
24 changes: 16 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ src/
├── ui/ # Rendering via ratatui
│ └── mod.rs # Layout, file list, status line, help overlay
└── config/ # Configuration loading and defaults
└── mod.rs # TOML parsing, XDG paths, default keybindings
└── mod.rs # TOML parsing, XDG paths, CLI-flag overrides
```

The repo is a Cargo workspace. The only non-root member is `xtask/` — dev tooling (`publish = false`, `dist = false`, never shipped in releases) that provides the `cargo dev-install` / `cargo run -p xtask -- uninstall` commands.
Expand Down Expand Up @@ -134,14 +134,22 @@ Arguments:
[PATH] Path to git repository or worktree (defaults to current directory)

Options:
-c, --config <FILE> Path to config file
-d, --debounce <MS> Debounce interval in milliseconds [default: 500]
--log <LEVEL> Enable logging (trace, debug, info, warn, error)
--base <BRANCH> Base branch for the branch-scoped diff range
-h, --help Print help
-V, --version Print version
-c, --config <FILE> Path to config file
-d, --debounce <MS> Debounce interval in milliseconds [default: 500]
--log <LEVEL> Enable logging (trace, debug, info, warn, error)
--base <BRANCH> Base branch for the branch-scoped diff range
--no-pr Disable the GitHub PR status strip
--view <MODE> Startup view (normal, condensed, tree)
--no-flash Disable the row flash on change
--flash-duration <MS> Flash duration in milliseconds
--scroll-padding <N> Rows kept visible above/below the selection
--edit-command <CMD> Editor command for the `e` key
-h, --help Print help
-V, --version Print version
```

Flags that mirror config keys override the config file (precedence: flag > config > default).

## Development Commands

```bash
Expand All @@ -156,7 +164,7 @@ cargo dev-install # symlink the debug build into ~/.local/bin (xtas

## Current Status

Core feature set is complete: live file-list with numstat, status-grouped Normal view (plus Condensed and Tree view modes), PR status strip, in-app diff overlay, filesystem watching, config file + keybindings, multi-worktree support, and branch-scoped diff range. Colors follow the terminal's ANSI palette (no theming).
Core feature set is complete: live file-list with numstat, status-grouped Normal view (plus Condensed and Tree view modes), PR status strip, in-app diff overlay, filesystem watching, config file (with mirroring CLI flags), multi-worktree support, and branch-scoped diff range. Colors follow the terminal's ANSI palette (no theming).

Remaining open items:

Expand Down
38 changes: 16 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,17 @@ perch can be launched from any directory inside a git working tree — the repos
| ------------------------- | ----------------------------------------------------------------------- |
| `[PATH]` | Repository path (default `.`) |
| `-c, --config <FILE>` | Path to config file |
| `-d, --debounce <MS>` | Filesystem debounce in ms (default `200`) |
| `--log <LEVEL>` | Logging level: `trace`, `debug`, `info`, `warn`, `error` |
| `-d, --debounce <MS>` | Filesystem debounce in ms (default `500`) |
| `--base <BRANCH>` | Base branch for the branch-scoped diff range |
| `--no-pr` | Disable the GitHub PR status strip |
| `--view <MODE>` | Startup view: `normal`, `condensed`, `tree` |
| `--no-flash` | Disable the row flash on change |
| `--flash-duration <MS>` | Flash duration in ms |
| `--scroll-padding <N>` | Rows kept visible above/below the selection |
| `--edit-command <CMD>` | Editor command for the `e` key |
| `--log <LEVEL>` | Logging level: `trace`, `debug`, `info`, `warn`, `error` |

Any flag that mirrors a config setting overrides the config file. Precedence is **CLI flag > config file > built-in default**.

## Keybindings

Expand Down Expand Up @@ -79,7 +87,7 @@ Config lives at `~/.config/perch/config.toml`. All sections are optional; defaul
### Top-level

```toml
debounce_ms = 200 # filesystem event debounce in ms
debounce_ms = 500 # filesystem event debounce in ms
base_branch = "main" # optional override for branch-scoped diff base
```

Expand All @@ -94,23 +102,10 @@ working-tree status and Normal hides the Committed group.

```toml
[display]
context_lines = 3 # diff context lines
default_view = "normal" # startup view: normal | condensed | tree
flash_on_change = true # flash a file row when it changes
flash_duration_ms = 600 # flash duration
```

### `[keys]`

Rebindable single-character keys.

```toml
[keys]
quit = "q"
up = "k"
down = "j"
expand = "l"
collapse = "h"
refresh = "r"
scroll_padding = 3 # rows kept visible around the selection (0 disables)
```

### `[pr]`
Expand All @@ -120,25 +115,24 @@ Controls the compact PR status strip that appears when the current branch has an
```toml
[pr]
enabled = true
show_labels = false
```

The GitHub token is discovered from the `GITHUB_TOKEN` environment variable or your `git config`. If no token is available the PR strip silently stays hidden.

### Full example

```toml
debounce_ms = 200
debounce_ms = 500
base_branch = "main"

[display]
context_lines = 3
default_view = "normal"
flash_on_change = true
flash_duration_ms = 600
scroll_padding = 3

[pr]
enabled = true
show_labels = false
```

## Colors
Expand Down
15 changes: 2 additions & 13 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,6 @@ pub struct App {
/// branch renames so the PR poller can be restarted and a flash message
/// shown.
last_seen_branch: Option<String>,
/// CLI override for base branch
base_override: Option<String>,
/// Sender for worker requests. Bounded; drops on overflow are safe
/// since FS-driven recomputes are idempotent.
worker_tx: Sender<Request>,
Expand Down Expand Up @@ -272,13 +270,7 @@ impl Drop for TerminalGuard<'_> {
}

impl App {
pub fn new(
watch_path: PathBuf,
repo_path: PathBuf,
config: AppConfig,
debounce_ms: u64,
base_override: Option<String>,
) -> Result<Self> {
pub fn new(watch_path: PathBuf, repo_path: PathBuf, config: AppConfig) -> Result<Self> {
// Open the repo just long enough to read the branch name (sub-millisecond
// — reads `.git/HEAD`). Everything else — file list, head_info, ahead/behind,
// stash count, repo_state, merge_base — is deferred to the worker so
Expand All @@ -303,7 +295,7 @@ impl App {
// the first draw) returns immediately. Live FS updates are disabled
// until the watcher is installed; a catch-up Recompute fires then.
let t = Instant::now();
let debounce = Duration::from_millis(debounce_ms);
let debounce = Duration::from_millis(config.debounce_ms);
let watcher_pending_rx = spawn_watcher_init(watch_path.clone(), debounce);
tracing::debug!(
elapsed_ms = t.elapsed().as_millis() as u64,
Expand Down Expand Up @@ -340,7 +332,6 @@ impl App {
let (worker_resp_tx, worker_rx) = bounded::<Response>(8);
let worker_handle = Worker::spawn(
watch_path.clone(),
base_override.clone(),
config.base_branch.clone(),
worker_req_rx,
worker_resp_tx,
Expand Down Expand Up @@ -370,7 +361,6 @@ impl App {
main_missing_warned: false,
gh_rx,
last_seen_branch: None,
base_override,
worker_tx,
worker_rx,
worker_handle: Some(worker_handle),
Expand Down Expand Up @@ -1242,7 +1232,6 @@ mod input_tests {
main_missing_warned: false,
gh_rx: None,
last_seen_branch: None,
base_override: None,
worker_tx,
worker_rx,
worker_handle: None,
Expand Down
Loading
Loading