Preview uncommitted changes in the detail pane

For a dirty submodule, list the changed files so the user can remember
what they were doing there:

  Changes   5 files · 2M 1A 1D 1R · +37 −12
            ──────────────────────────────────
            M  render.go  src/render/  +20 −4  3d ago
            ?  scratch.txt                     5m ago

- Status.Changes: files changed against HEAD (staged and unstaged
  combined) with kind, line counts and modification time; sorted by kind,
  then by size; capped at 200 with totals over all files.
- Git provider: parse `status --porcelain=v2 -z` and one
  `diff HEAD --numstat -z -M`, only for dirty submodules.
- Detail pane: flat list with a colored status letter per file, like IDE
  source-control views; counts and age in compact columns; up to 10 files,
  every kind keeps a line, the rest is summarized as "n more".
- Fixture gains libs/work with every kind of change; mock data extended.
- Docs: F24, change preview in the UX guide, D17.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Simon Franken
2026-10-21 15:55:46 +02:00
co-authored by Claude Opus 5.5
parent 64fe34b5b0
commit 19c6f17eb2
17 changed files with 882 additions and 32 deletions
+5 -3
View File
@@ -13,6 +13,7 @@ import (
type Theme struct {
Primary lipgloss.TerminalColor // accent: branch names, commit hashes
Info lipgloss.TerminalColor
Added lipgloss.TerminalColor // added lines and files
Warn lipgloss.TerminalColor
Danger lipgloss.TerminalColor
Muted lipgloss.TerminalColor
@@ -31,6 +32,7 @@ func Default() Theme {
return Theme{
Primary: lipgloss.Color("6"), // cyan
Info: lipgloss.Color("4"), // blue
Added: lipgloss.Color("2"), // green
Warn: lipgloss.Color("3"), // yellow
Danger: lipgloss.Color("1"), // red
Muted: lipgloss.Color("8"), // bright black / grey
@@ -49,17 +51,17 @@ func Fg(c lipgloss.TerminalColor) lipgloss.Style {
// Glyphs are the few symbols used next to the state words.
type Glyphs struct {
Staged, Ahead, Behind, Collapsed, Expanded, Problems string
Staged, Ahead, Behind, Collapsed, Expanded, Problems, Minus, From, Rule string
}
func Unicode() Glyphs {
return Glyphs{
Staged: "●", Ahead: "↑", Behind: "↓", Collapsed: "▸", Expanded: "▾", Problems: "·",
Staged: "●", Ahead: "↑", Behind: "↓", Collapsed: "▸", Expanded: "▾", Problems: "·", Minus: "−", From: "←", Rule: "─",
}
}
func ASCII() Glyphs {
return Glyphs{
Staged: "*", Ahead: "^", Behind: "v", Collapsed: ">", Expanded: "v", Problems: ".",
Staged: "*", Ahead: "^", Behind: "v", Collapsed: ">", Expanded: "v", Problems: ".", Minus: "-", From: "<-", Rule: "-",
}
}