search: dedup detail renderers behind a shared detailWriter · Entire
Search: Dedup Detail Renderers Behind a Shared DetailWriter
aadf0b9 → main ·
alishakawaguchi · 1mo ago · 1 file · +136 added/-197 removed
The three per-type detail renderers (checkpoint/commit/session) each redefined identical label/field/wrapped-field/section helpers plus the Match-with-score and author-with-username blocks. Extract a detailWriter type that owns the shared layout so each renderer reads as a field list. No behavior change.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
5c1f6e660501 View transcript
Changes
- cmd/entire/cli
- Msearch_tui.go +136/-197
// detailWriter accumulates a label/value detail body. It owns the shared
// layout (label column width, value wrap width, section spacing) so the
// per-type renderers below differ only in which fields they emit.
type detailWriter struct {
b strings.Builder
styles searchStyles
labelWidth int
valueWidth int
showSections bool
}
func (m searchModel) newDetailWriter(title string, contentWidth int, showSections bool) *detailWriter {
const labelWidth = 12
valueWidth := contentWidth - labelWidth - 1
if valueWidth < 20 {
valueWidth = 0
}
w := &detailWriter{
styles: m.styles,
labelWidth: labelWidth,
valueWidth: valueWidth,
showSections: showSections,
}
w.b.WriteString(w.styles.render(w.styles.detailTitle, title) + "\n")
return w
}
func (w *detailWriter) label(label string) string {
return w.styles.render(w.styles.label, fmt.Sprintf("%-*s", w.labelWidth, label+":"))
}
func (w *detailWriter) field(label, value string) {
w.b.WriteString(w.label(label) + " " + value + "\n")
}
func (w *detailWriter) wrappedField(label, value string) {
if w.valueWidth == 0 || len(value) <= w.valueWidth {
w.field(label, value)
return
}
indent := strings.Repeat(" ", w.labelWidth+1)
lines := strings.Split(wrapText(value, w.valueWidth), "\n")
w.b.WriteString(w.label(label) + " " + lines[0] + "\n")
for _, line := range lines[1:] {
w.b.WriteString(indent + line + "\n")
}
}
func (w *detailWriter) section(title string) {
if w.showSections {
w.b.WriteString("\n" + w.styles.render(w.styles.detailTitle, title) + "\n")
} else {
w.b.WriteString("\n")
}
}
func (w *detailWriter) matchField(meta search.Meta) {
value := meta.MatchType
if meta.Score > 0 {
value += " " + w.styles.render(w.styles.dim, fmt.Sprintf("(score: %.3f)", meta.Score))
}
w.field("Match", value)
}
func (w *detailWriter) authorField(author string, username *string) {
value := author
if username != nil && *username != "" {
value = *username + " " + w.styles.render(w.styles.dim, "("+author+")")
}
w.field("Author", value)
}
func (w *detailWriter) String() string {
return strings.TrimRight(w.b.String(), "\n")
}