Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
47eef7f
feat(review): devicons-backed icon table with brand colors
lettertwo Jul 11, 2026
14bb3e7
feat(review): promote semantic fg colors to palette knobs
lettertwo Jul 11, 2026
79fa9a2
feat(review): nerd-mode status and header/summary iconography
lettertwo Jul 11, 2026
76b5a60
style(review): tree guides, gap label, and winbar restyle
lettertwo Jul 11, 2026
02bb12b
refactor(review): promote icons config to workon.review.icons
lettertwo Jul 12, 2026
ab6d8ce
feat(review): mouse support with click-to-focus and wheel scroll
lettertwo Jul 11, 2026
b5b1274
fix(review): compare AppEvent::Mouse structurally in PartialEq
lettertwo Jul 11, 2026
1f9a0ca
fix(review): pass row count to derive_outline_scroll in mouse tests
lettertwo Jul 11, 2026
7d328dc
fix(review): mouse wheel scrolls the viewport and leaves the cursor
lettertwo Jul 11, 2026
9ee33ab
feat(review): horizontal scroll for long diff lines
lettertwo Jul 12, 2026
8af0711
feat(review): mouse h-wheel panning and outline hscroll
lettertwo Jul 12, 2026
8766313
feat(review): distinguish outline changeset headers with counter and …
lettertwo Jul 13, 2026
a318dc6
feat(review): smart path render and tighter tree indent
lettertwo Jul 13, 2026
dae859a
feat(review): git-style XY status matrix for outline files
lettertwo Jul 13, 2026
765996c
feat(review): reorder outline cycle and show next mode in footer
lettertwo Jul 13, 2026
01f276d
feat(review): collapse and expand outline headers and directories
lettertwo Jul 13, 2026
a612cf4
fix(review): outline header label, indent, and marker polish
lettertwo Jul 15, 2026
f3c6330
feat(review): outline changeset nav and fold-all keybindings
lettertwo Jul 15, 2026
735d704
fix(review): key changeset identity by name plus span kind
lettertwo Jul 17, 2026
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
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ clap-verbosity-flag = "3.0.4"
clap_complete = { version = "4.6.5", features = ["unstable-dynamic"] }
clap_mangen = "0.3.0"
crossterm = "0.29.0"
devicons = "0.6"
dialoguer = { version = "0.12.0", features = ["fuzzy-select"] }
dirs = "6.0"
env_logger = "0.11.10"
Expand Down
12 changes: 12 additions & 0 deletions docs/adr/035-review-theming-base16-hybrid.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,18 @@ read left untested (see `terminal_query.rs`).
to render; `FgSpan` loses its `Color` field in favor of a capture index. Existing render
tests that assert concrete colors must resolve through a fixed test `Palette`.

## Revised (CS2, visual-polish pass)

The "chrome that is never a theme knob (error/warn/current-marker) stays ANSI/const in
`render.rs`" clause above is superseded. Those three colors are now `Palette` fields
(`error_fg`/`warn_fg`/`current_fg`, mapped to base08/base0A/base0B) rather than module
consts — the user explicitly approved revisiting this boundary during the icons/semantic-fg
polish pass. `dark()` keeps the shipped RGB values verbatim (the same pixel-identity
precedent the diff/cursor tints follow); `light()` takes `ONE_LIGHT`'s base08/base0A/base0B;
`from_terminal()` takes the probed scheme's base08/base0A/base0B directly, same reasoning as
the syntax slots (matching the terminal, not curated-tint-borrowing). No other part of the
hybrid boundary changes: this only moves three named colors from `const` to palette fields.

## References

- [ADR-034](034-review-git-native-config-schema.md) — `workon.review.theme` config key
Expand Down
2 changes: 2 additions & 0 deletions git-workon-review/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ vendored = ["git-workon-lib/vendored", "git2/vendored-libgit2", "git2/vendored-o
clap.workspace = true
clap_complete.workspace = true
crossterm.workspace = true
devicons.workspace = true
dirs.workspace = true
git-workon-lib.workspace = true
git2.workspace = true
Expand All @@ -53,6 +54,7 @@ tree-sitter-md.workspace = true
tree-sitter-rust.workspace = true
tree-sitter-toml-ng.workspace = true
tree-sitter-typescript.workspace = true
unicode-width.workspace = true

[package.metadata.dist]
# Redundant with publish = false today; load-bearing at the M3 flip so
Expand Down
2,113 changes: 1,901 additions & 212 deletions git-workon-review/src/app.rs

Large diffs are not rendered by default.

36 changes: 20 additions & 16 deletions git-workon-review/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
//! ```gitconfig
//! [workon "review"]
//! theme = dark ; auto | dark | light (default: auto)
//! icons = nerd ; nerd | none (default: none)
//!
//! [workon "review.diff.bind"]
//! stage-hunk = s x ; action = key tokens (space-separated)
Expand All @@ -32,19 +33,20 @@
//! width = 32
//! mode = tree
//! order = base-first ; head-first | base-first (default: head-first)
//! icons = nerd ; nerd | none (default: none)
//!
//! [workon "review.diff"]
//! layout = split
//! zoom = combined
//! ```
//!
//! ## `outline.icons` (CS5)
//! ## `icons`
//!
//! Opt-in nerd-font file/dir icons in the outline pane. There is deliberately NO auto-detection
//! Opt-in nerd-font iconography — top-level next to `theme` (`workon.review.icons`), NOT an
//! outline setting: the mode gates the outline's file/dir icons, the summary panel's glyphs,
//! and the winbar's marker/diffstat/file icons alike. There is deliberately NO auto-detection
//! — a terminal cannot report whether the user's font is patched with the nerd-font glyphs, so
//! guessing would silently render tofu/mojibake for anyone without one. Default is `none`
//! (today's plain text); set `icons = nerd` explicitly once your terminal font supports it. See
//! (plain text); set `icons = nerd` explicitly once your terminal font supports it. See
//! [`crate::icons`] for the glyph table.

use git2::Repository;
Expand Down Expand Up @@ -112,7 +114,7 @@ pub struct RawViewConfig {
pub outline_width: Option<i64>,
pub outline_mode: Option<String>,
pub outline_order: Option<String>,
pub outline_icons: Option<String>,
pub icons: Option<String>,
pub diff_layout: Option<String>,
pub diff_zoom: Option<String>,
}
Expand Down Expand Up @@ -220,10 +222,15 @@ impl<'repo> ReviewConfig<'repo> {
self.get_view_string(View::Outline, "order")
}

/// Get `workon.review.outline.icons`, raw. `None` if unset — callers apply the current
/// default ([`crate::icons::OutlineIcons::None`], CS5: no auto-detection story exists).
pub fn outline_icons(&self) -> Result<Option<String>, git2::Error> {
self.get_view_string(View::Outline, "icons")
/// Get `workon.review.icons`, raw. `None` if unset — callers apply the current default
/// ([`crate::icons::IconMode::None`]; no auto-detection story exists). Top-level like
/// `theme`, not a view setting: icon mode gates the outline, summary panel, AND winbar.
pub fn icons(&self) -> Result<Option<String>, git2::Error> {
let config = self.repo.config()?;
match config.get_string("workon.review.icons") {
Ok(val) => Ok(Some(val)),
Err(_) => Ok(None),
}
}

/// Get `workon.review.diff.layout`, raw. `None` if unset.
Expand All @@ -248,7 +255,7 @@ impl<'repo> ReviewConfig<'repo> {
outline_width: self.outline_width().ok().flatten(),
outline_mode: self.outline_mode().ok().flatten(),
outline_order: self.outline_order().ok().flatten(),
outline_icons: self.outline_icons().ok().flatten(),
icons: self.icons().ok().flatten(),
diff_layout: self.diff_layout().ok().flatten(),
diff_zoom: self.diff_zoom().ok().flatten(),
}
Expand Down Expand Up @@ -433,7 +440,7 @@ mod tests {
.config("workon.review.outline.width", "40")
.config("workon.review.outline.mode", "tree")
.config("workon.review.outline.order", "base-first")
.config("workon.review.outline.icons", "nerd")
.config("workon.review.icons", "nerd")
.config("workon.review.diff.layout", "split")
.config("workon.review.diff.zoom", "staged")
.build()
Expand All @@ -450,10 +457,7 @@ mod tests {
config.outline_order().expect("order"),
Some("base-first".to_string())
);
assert_eq!(
config.outline_icons().expect("icons"),
Some("nerd".to_string())
);
assert_eq!(config.icons().expect("icons"), Some("nerd".to_string()));
assert_eq!(
config.diff_layout().expect("layout"),
Some("split".to_string())
Expand All @@ -473,7 +477,7 @@ mod tests {
assert_eq!(config.outline_width().expect("width"), None);
assert_eq!(config.outline_mode().expect("mode"), None);
assert_eq!(config.outline_order().expect("order"), None);
assert_eq!(config.outline_icons().expect("icons"), None);
assert_eq!(config.icons().expect("icons"), None);
assert_eq!(config.diff_layout().expect("layout"), None);
assert_eq!(config.diff_zoom().expect("zoom"), None);
}
Expand Down
Loading