Skip to content

Commit bf7eb73

Browse files
committed
Fixed API inspetor
1 parent 19e0cdb commit bf7eb73

File tree

1 file changed

+106
-3
lines changed

1 file changed

+106
-3
lines changed

tui/debugpanel.go

Lines changed: 106 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,18 @@ func (m Model) buildDebugBody(events []client.APIEvent, cursor int, pw int, ds d
410410
lines = append(lines, lbl+ds.punct.Width(rem).Render(strings.Repeat("─", rem)))
411411
}
412412

413+
// addAccentSection renders the same divider but in colorAccent — used for
414+
// the RESPONSE section to make it visually distinct from the dim REQUEST header.
415+
addAccentSection := func(label string) {
416+
accentStyle := lipgloss.NewStyle().Background(ds.panelBg).Foreground(colorAccent)
417+
lbl := accentStyle.Render(" ── " + label + " ")
418+
rem := pw - lipgloss.Width(lbl)
419+
if rem < 0 {
420+
rem = 0
421+
}
422+
lines = append(lines, lbl+accentStyle.Width(rem).Render(strings.Repeat("─", rem)))
423+
}
424+
413425
// addHeaders renders each "Name: value" header line, dim-styled.
414426
addHeaders := func(headers []string) {
415427
for _, h := range headers {
@@ -464,14 +476,14 @@ func (m Model) buildDebugBody(events []client.APIEvent, cursor int, pw int, ds d
464476
if e.ReqBody != "" {
465477
lines = append(lines, ds.bg.Width(pw).Render(""))
466478
for _, bl := range strings.Split(e.ReqBody, "\n") {
467-
lines = append(lines, ds.bg.Render(" ")+colorizeJSONLine(truncateStr(bl, pw-2)))
479+
lines = append(lines, ds.bg.Render(" ")+colorizeJSONLineForPanel(truncateStr(bl, pw-2), ds.panelBg))
468480
}
469481
}
470482

471483
lines = append(lines, ds.bg.Width(pw).Render(""))
472484

473485
// ── RESPONSE ──────────────────────────────────────────────────────────
474-
addSection("RESPONSE")
486+
addAccentSection("RESPONSE")
475487

476488
if e.Err != "" {
477489
lines = append(lines, statusErrorStyle.Render(" ✗ "+e.Err))
@@ -494,7 +506,7 @@ func (m Model) buildDebugBody(events []client.APIEvent, cursor int, pw int, ds d
494506
lines = append(lines, ds.bg.Width(pw).Render(""))
495507
if e.RespBody != "" {
496508
for _, bl := range strings.Split(e.RespBody, "\n") {
497-
lines = append(lines, ds.bg.Render(" ")+colorizeJSONLine(truncateStr(bl, pw-2)))
509+
lines = append(lines, ds.bg.Render(" ")+colorizeJSONLineForPanel(truncateStr(bl, pw-2), ds.panelBg))
498510
}
499511
} else {
500512
lines = append(lines, ds.punct.Render(" (empty body)"))
@@ -573,3 +585,94 @@ func debugDurLabel(d time.Duration) string {
573585
return fmt.Sprintf("%.1fs", d.Seconds())
574586
}
575587

588+
// colorizeJSONLineForPanel colorizes a JSON line using the given panel background
589+
// colour so token backgrounds always match the panel (focused or unfocused).
590+
// This mirrors colorizeJSONLine / tokenizeJSON in svjson.go but builds styles
591+
// dynamically rather than using the global jsonXxxStyle vars which hardcode colorBg.
592+
func colorizeJSONLineForPanel(line string, bg color.Color) string {
593+
trimmed := strings.TrimLeft(line, " \t")
594+
if trimmed == "" {
595+
return line
596+
}
597+
indent := line[:len(line)-len(trimmed)]
598+
599+
base := lipgloss.NewStyle().Background(bg)
600+
pKey := base.Foreground(colorAccent)
601+
pStr := base.Foreground(colorSuccess)
602+
pNum := base.Foreground(colorPurple)
603+
pKwd := base.Foreground(colorLoading)
604+
pPun := base.Foreground(colorDim)
605+
606+
// colorValue tokenizes a value fragment (everything after a colon, or a
607+
// standalone value / array element). Mirrors jsonColorValue from svjson.go.
608+
var colorValue func(s string) string
609+
colorValue = func(s string) string {
610+
var out strings.Builder
611+
ws := s[:len(s)-len(strings.TrimLeft(s, " \t"))]
612+
if ws != "" {
613+
out.WriteString(ws)
614+
}
615+
s = strings.TrimLeft(s, " \t")
616+
if s == "" {
617+
return out.String()
618+
}
619+
trailer := ""
620+
if s[len(s)-1] == ',' {
621+
trailer = ","
622+
s = s[:len(s)-1]
623+
}
624+
if s == "" {
625+
out.WriteString(pPun.Render(trailer))
626+
return out.String()
627+
}
628+
switch s[0] {
629+
case '"':
630+
out.WriteString(pStr.Render(s))
631+
case '{', '[', '}', ']':
632+
out.WriteString(pPun.Render(s))
633+
case 't', 'f', 'n':
634+
out.WriteString(pKwd.Render(s))
635+
default:
636+
out.WriteString(pNum.Render(s))
637+
}
638+
if trailer != "" {
639+
out.WriteString(pPun.Render(trailer))
640+
}
641+
return out.String()
642+
}
643+
644+
var out strings.Builder
645+
s := trimmed
646+
switch s[0] {
647+
case '"':
648+
end := jsonStringEnd(s, 0)
649+
if end < 0 {
650+
return line // truncated string — leave unstyled
651+
}
652+
str := s[:end]
653+
rest := s[end:]
654+
restTrim := strings.TrimLeft(rest, " ")
655+
if len(restTrim) > 0 && restTrim[0] == ':' {
656+
out.WriteString(pKey.Render(str))
657+
ws := rest[:len(rest)-len(restTrim)]
658+
out.WriteString(pPun.Render(ws + ":"))
659+
out.WriteString(colorValue(restTrim[1:]))
660+
} else {
661+
out.WriteString(pStr.Render(str))
662+
if rest != "" {
663+
out.WriteString(pPun.Render(rest))
664+
}
665+
}
666+
case '{', '}', '[', ']':
667+
out.WriteString(pPun.Render(s))
668+
default:
669+
out.WriteString(colorValue(s))
670+
}
671+
// Style the indent with the panel background so it matches rather than
672+
// falling back to the terminal default after the ANSI reset from ds.bg prefix.
673+
if indent != "" {
674+
return base.Render(indent) + out.String()
675+
}
676+
return out.String()
677+
}
678+

0 commit comments

Comments
 (0)