Split status bar into status line and help overlay - #7
Conversation
- add ? help keybinding to README and plugin usage reference - add status line and help overlay to features list - move plan to completed
There was a problem hiding this comment.
Pull request overview
This PR splits the previously crowded status bar into a compact status line and a modal help overlay, and updates the plugin launch overlay title to be contextual.
Changes:
- Reworks the status line to show filename, +/- stats, hunk position, mode indicators, and right-aligned annotation count plus
? help. - Adds a
?-toggled help overlay (dismissible via?oresc) that lists all keybindings by section and blocks other keys while open. - Updates the kitty/tmux overlay title in the launch script to include the current directory name and optional ref.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
ui/styles.go |
Persists original Colors in styles so UI elements (help overlay border) can reuse theme colors. |
ui/model.go |
Implements new status line rendering, file diff stats caching, help overlay rendering, and ? key handling. |
ui/model_test.go |
Adds/updates tests for stats computation, status line behavior (truncation/degradation/indicators), and help overlay behavior. |
ui/collapsed_test.go |
Updates collapsed-mode status-related tests to reflect indicator-based status line. |
README.md |
Documents the new status line and ? help overlay keybinding. |
docs/plans/completed/20260402-status-line-help-overlay.md |
Adds a completed implementation plan/notes for this feature. |
.claude-plugin/skills/revdiff/scripts/launch-revdiff.sh |
Changes overlay title to rd: dirname [ref] instead of a static title. |
.claude-plugin/skills/revdiff/references/usage.md |
Documents the new ? help overlay keybinding. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| func TestModel_HelpToggle(t *testing.T) { | ||
| m := testModel([]string{"a.go"}, map[string][]diff.DiffLine{"a.go": {{ChangeType: diff.ChangeContext, Content: "x"}}}) | ||
| m.currFile = "a.go" | ||
| m.focus = paneDiff | ||
| assert.False(t, m.showHelp) | ||
|
|
||
| // press ? to open help | ||
| result, _ := m.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'?'}}) | ||
| model := result.(Model) | ||
| assert.True(t, model.showHelp) | ||
|
|
||
| // press ? again to close help | ||
| result, _ = model.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'?'}}) | ||
| model = result.(Model) | ||
| assert.False(t, model.showHelp) | ||
| } | ||
|
|
||
| func TestModel_HelpCloseWithEsc(t *testing.T) { | ||
| m := testModel([]string{"a.go"}, map[string][]diff.DiffLine{"a.go": {{ChangeType: diff.ChangeContext, Content: "x"}}}) | ||
| m.currFile = "a.go" | ||
| m.showHelp = true | ||
|
|
||
| // press esc to close help | ||
| result, _ := m.Update(tea.KeyMsg{Type: tea.KeyEsc}) | ||
| model := result.(Model) | ||
| assert.False(t, model.showHelp) | ||
| } | ||
|
|
||
| func TestModel_HelpBlocksOtherKeys(t *testing.T) { | ||
| m := testModel([]string{"a.go", "b.go"}, map[string][]diff.DiffLine{ | ||
| "a.go": {{ChangeType: diff.ChangeContext, Content: "x"}}, | ||
| "b.go": {{ChangeType: diff.ChangeContext, Content: "y"}}, | ||
| }) |
There was a problem hiding this comment.
These map literals won’t compile: {"a.go": {{...}}} is missing the slice type. Use []diff.DiffLine{{...}} (and same for the other map entries in this section) so the map values are valid slice literals.
| for arg in "$@"; do | ||
| case "$arg" in --*) ;; *) TITLE_REF="$arg"; break ;; esac |
There was a problem hiding this comment.
The overlay title ref detection only skips args starting with --. Short flags like -o/-V (supported by the CLI) will be treated as the ref, and flags with values (e.g. -o out.txt) will cause the output path to be treated as the ref. Parse args more robustly (e.g., skip -* flags too, and handle -o/--output consuming the next arg) so the title reflects the actual positional ref.
| for arg in "$@"; do | |
| case "$arg" in --*) ;; *) TITLE_REF="$arg"; break ;; esac | |
| ARGS=("$@") | |
| EXPECT_VALUE=0 | |
| END_OF_OPTIONS=0 | |
| for ((i = 0; i < ${#ARGS[@]}; i++)); do | |
| arg="${ARGS[i]}" | |
| if [ "$END_OF_OPTIONS" -eq 1 ]; then | |
| TITLE_REF="$arg" | |
| break | |
| fi | |
| if [ "$EXPECT_VALUE" -eq 1 ]; then | |
| EXPECT_VALUE=0 | |
| continue | |
| fi | |
| case "$arg" in | |
| --) | |
| END_OF_OPTIONS=1 | |
| ;; | |
| -o|--output) | |
| EXPECT_VALUE=1 | |
| ;; | |
| --output=*) | |
| ;; | |
| -*) | |
| ;; | |
| *) | |
| TITLE_REF="$arg" | |
| break | |
| ;; | |
| esac |
| REVDIFF_CMD="$REVDIFF_BIN --output=$OUTPUT_FILE $*" | ||
| CWD="$(pwd)" | ||
|
|
||
| # build descriptive title: "revdiff: dirname [ref]" |
There was a problem hiding this comment.
The comment says the title format is "revdiff: dirname [ref]", but the actual title uses rd: .... Update the comment to match the produced title to avoid confusion when editing this script later.
| # build descriptive title: "revdiff: dirname [ref]" | |
| # build descriptive title: "rd: dirname [ref]" |
Show hunk count always in diff pane (not just when cursor is on a changed line), render help overlay on top of content instead of replacing it, add pipe separators between status line sections, group mode icons into a single section, and fix "1 hunks" singular/plural grammar.
Fix comment to match actual title format ("rd:" not "revdiff:") and
harden flag parsing to skip short flags and handle -o/--output consuming
the next argument. Bump plugin version to 0.2.1.
Long filenames that exceed the tree pane width caused the selection highlight to wrap onto multiple lines, making it look like two entries were selected. Truncate from the left with ellipsis to fit within the pane width.
Split the crowded status bar into two separate concerns:
? helphint?key with all keybindings organized in sections (Navigation, Annotations, View, Quit), dismissed with?orescrd: dirname [ref]instead of static "revdiff" in kitty/tmux overlaysRemoves all shortcut hints from the status bar — they now live in the help popup where they do not compete with actual status information.