fix(tui): approval nav lockups, shell non-diff preview, hint dedup
Three QA-found issues in the approval gate: - displayState gated the in-session/approval surfaces on hasApproval before sessionEntered, so moving the list cursor onto a session with a pending gate auto-opened it, and `l` back-to-list couldn't escape (the gate re-popped). Require sessionEntered first. - The band ran every preview through the two-column diff renderer, so a shell tool's argv JSON rendered as an identical-column "diff". Detect real unified diffs (isUnifiedDiff); render other previews as plain text, and drop the ^x fullscreen hint when there's nothing to expand. - The footer duplicated the band's approve/reject/steer/diff keys. It now shows navigation (l back / e events / q quit) instead.
This commit is contained in:
@@ -78,6 +78,48 @@ func parseUnifiedDiff(diff string) []diffRow {
|
||||
return rows
|
||||
}
|
||||
|
||||
// isUnifiedDiff reports whether s looks like a unified diff (file/hunk headers)
|
||||
// rather than arbitrary preview text such as a shell argv JSON. Non-diff previews
|
||||
// must not go through the two-column renderer (it would show identical columns).
|
||||
func isUnifiedDiff(s string) bool {
|
||||
return strings.Contains(s, "@@ -") || strings.HasPrefix(s, "--- ") || strings.Contains(s, "\n--- ")
|
||||
}
|
||||
|
||||
// previewPlainLines splits non-diff preview text into display lines.
|
||||
func previewPlainLines(s string) []string {
|
||||
return strings.Split(strings.TrimRight(s, "\n"), "\n")
|
||||
}
|
||||
|
||||
// previewRowCount is the number of content rows a preview occupies — diff rows
|
||||
// for a real diff, plain lines otherwise. Drives band sizing and scroll bounds.
|
||||
func previewRowCount(s string) int {
|
||||
if isUnifiedDiff(s) {
|
||||
return len(parseUnifiedDiff(s))
|
||||
}
|
||||
return len(previewPlainLines(s))
|
||||
}
|
||||
|
||||
// renderPreviewLines renders non-diff preview text as dim plain lines (single
|
||||
// column), up to maxRows starting at off, each truncated to width.
|
||||
func (m Model) renderPreviewLines(content string, width, maxRows, off int) []string {
|
||||
lines := previewPlainLines(content)
|
||||
if off < 0 {
|
||||
off = 0
|
||||
}
|
||||
if off > len(lines) {
|
||||
off = len(lines)
|
||||
}
|
||||
end := off + maxRows
|
||||
if end > len(lines) {
|
||||
end = len(lines)
|
||||
}
|
||||
out := make([]string, 0, end-off)
|
||||
for _, ln := range lines[off:end] {
|
||||
out = append(out, m.theme.span(truncate(ln, width), m.theme.P.Dim))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// hunkStarts reads the starting old/new line numbers from an @@ -a,b +c,d @@ marker.
|
||||
func hunkStarts(h string) (int, int) {
|
||||
old, newer := 1, 1
|
||||
|
||||
Reference in New Issue
Block a user