summaryrefslogtreecommitdiff
path: root/internal/tui/eventstream/render.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-26 23:08:14 +0200
committerPaul Buetow <paul@buetow.org>2026-02-26 23:08:14 +0200
commitc3106802208b18f78d4ff4b22e1d889ac19f817f (patch)
treec01fe438cf1d0699d7b08b919c3b5494ee18a32f /internal/tui/eventstream/render.go
parentdc7478d7dadf544787a9718608f11312bd2ea944 (diff)
tui: add paused stream column selection and split pid/tid
Diffstat (limited to 'internal/tui/eventstream/render.go')
-rw-r--r--internal/tui/eventstream/render.go79
1 files changed, 50 insertions, 29 deletions
diff --git a/internal/tui/eventstream/render.go b/internal/tui/eventstream/render.go
index e9d44f1..1f539c6 100644
--- a/internal/tui/eventstream/render.go
+++ b/internal/tui/eventstream/render.go
@@ -13,7 +13,8 @@ type columnLayout struct {
gap int
latency int
comm int
- pidTid int
+ pid int
+ tid int
syscall int
fd int
ret int
@@ -26,7 +27,12 @@ var selectedRowStyle = lipgloss.NewStyle().
Foreground(common.ColorBackground).
Background(common.ColorPrimary)
-func RenderStreamTable(width int, paused bool, totalCount, filteredCount, bufferLen, bufferCap int, filter Filter, events []StreamEvent, selectedVisibleIdx int) string {
+var selectedCellStyle = lipgloss.NewStyle().
+ Bold(true).
+ Foreground(common.ColorBackground).
+ Background(common.ColorAccent)
+
+func RenderStreamTable(width int, paused bool, totalCount, filteredCount, bufferLen, bufferCap int, filter Filter, events []StreamEvent, selectedVisibleIdx int, selectedCol int) string {
if width <= 0 {
width = 100
}
@@ -37,7 +43,11 @@ func RenderStreamTable(width int, paused bool, totalCount, filteredCount, buffer
lines = append(lines, renderFilterLine(filter))
lines = append(lines, renderColumnHeader(contentWidth))
for i, ev := range events {
- lines = append(lines, renderEventRow(ev, contentWidth, i == selectedVisibleIdx))
+ col := -1
+ if i == selectedVisibleIdx {
+ col = selectedCol
+ }
+ lines = append(lines, renderEventRow(ev, contentWidth, i == selectedVisibleIdx, col))
}
return common.PanelStyle.Width(contentWidth).Render(strings.Join(lines, "\n"))
@@ -54,7 +64,7 @@ func RenderFDTraceTable(width int, pid uint32, fd int32, totalCount int, events
lines = append(lines, fmt.Sprintf("PID:%d FD:%d matched:%d", pid, fd, totalCount))
lines = append(lines, renderColumnHeader(contentWidth))
for _, ev := range events {
- lines = append(lines, renderEventRow(ev, contentWidth, false))
+ lines = append(lines, renderEventRow(ev, contentWidth, false, -1))
}
return common.PanelStyle.Width(contentWidth).Render(strings.Join(lines, "\n"))
@@ -82,11 +92,12 @@ func renderFilterLine(filter Filter) string {
func renderColumnHeader(width int) string {
cols := computeColumnLayout(width)
- header := fmt.Sprintf("%-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s %s",
+ header := fmt.Sprintf("%-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s %s",
cols.gap, "Gap",
cols.latency, "Latency",
cols.comm, "Comm",
- cols.pidTid, "PID.TID",
+ cols.pid, "PID",
+ cols.tid, "TID",
cols.syscall, "Syscall",
cols.fd, "FD",
cols.ret, "Ret",
@@ -96,31 +107,38 @@ func renderColumnHeader(width int) string {
return common.HelpBarStyle.Render(header)
}
-func renderEventRow(ev StreamEvent, width int, selected bool) string {
+func renderEventRow(ev StreamEvent, width int, selected bool, selectedCol int) string {
cols := computeColumnLayout(width)
- pidTid := fmt.Sprintf("%d.%d", ev.PID, ev.TID)
fd := "-"
if ev.FD >= 0 {
fd = strconv.FormatInt(int64(ev.FD), 10)
}
- row := fmt.Sprintf("%-*s %-*s %-*s %-*s %-*s %-*s %-*s %-*s %s",
- cols.gap, fitCell(formatDurationNs(ev.GapNs), cols.gap),
- cols.latency, fitCell(formatDurationNs(ev.DurationNs), cols.latency),
- cols.comm, fitCell(ev.Comm, cols.comm),
- cols.pidTid, fitCell(pidTid, cols.pidTid),
- cols.syscall, fitCell(ev.Syscall, cols.syscall),
- cols.fd, fitCell(fd, cols.fd),
- cols.ret, fitCell(strconv.FormatInt(ev.RetVal, 10), cols.ret),
- cols.bytes, fitCell(strconv.FormatUint(ev.Bytes, 10), cols.bytes),
+ cells := []string{
+ fmt.Sprintf("%-*s", cols.gap, fitCell(formatDurationNs(ev.GapNs), cols.gap)),
+ fmt.Sprintf("%-*s", cols.latency, fitCell(formatDurationNs(ev.DurationNs), cols.latency)),
+ fmt.Sprintf("%-*s", cols.comm, fitCell(ev.Comm, cols.comm)),
+ fmt.Sprintf("%-*s", cols.pid, fitCell(strconv.FormatUint(uint64(ev.PID), 10), cols.pid)),
+ fmt.Sprintf("%-*s", cols.tid, fitCell(strconv.FormatUint(uint64(ev.TID), 10), cols.tid)),
+ fmt.Sprintf("%-*s", cols.syscall, fitCell(ev.Syscall, cols.syscall)),
+ fmt.Sprintf("%-*s", cols.fd, fitCell(fd, cols.fd)),
+ fmt.Sprintf("%-*s", cols.ret, fitCell(strconv.FormatInt(ev.RetVal, 10), cols.ret)),
+ fmt.Sprintf("%-*s", cols.bytes, fitCell(strconv.FormatUint(ev.Bytes, 10), cols.bytes)),
fitCell(ev.FileName, cols.file),
- )
+ }
if selected {
- return selectedRowStyle.Render(row)
+ for i := range cells {
+ if i == selectedCol {
+ cells[i] = selectedCellStyle.Render(cells[i])
+ } else {
+ cells[i] = selectedRowStyle.Render(cells[i])
+ }
+ }
+ return strings.Join(cells, " ")
}
if ev.IsError {
- return common.ErrorStyle.Render(row)
+ return common.ErrorStyle.Render(strings.Join(cells, " "))
}
- return row
+ return strings.Join(cells, " ")
}
func computeColumnLayout(width int) columnLayout {
@@ -132,38 +150,41 @@ func computeColumnLayout(width int) columnLayout {
gap := 7
latency := 8
comm := 10
- pidTid := 10
+ pid := 7
+ tid := 7
syscall := 9
fd := 4
ret := 5
bytes := 8
- fixed := gap + latency + comm + pidTid + syscall + fd + ret + bytes + 8
+ fixed := gap + latency + comm + pid + tid + syscall + fd + ret + bytes + 9
file := width - fixed
if file >= 28 {
// On wider terminals, give a little more room back to descriptive columns.
if width >= 140 {
comm = 12
syscall = 11
- pidTid = 11
- fixed = gap + latency + comm + pidTid + syscall + fd + ret + bytes + 8
+ pid = 8
+ tid = 8
+ fixed = gap + latency + comm + pid + tid + syscall + fd + ret + bytes + 9
file = width - fixed
}
- return columnLayout{gap: gap, latency: latency, comm: comm, pidTid: pidTid, syscall: syscall, fd: fd, ret: ret, bytes: bytes, file: file}
+ return columnLayout{gap: gap, latency: latency, comm: comm, pid: pid, tid: tid, syscall: syscall, fd: fd, ret: ret, bytes: bytes, file: file}
}
// Very narrow widths: compress further but keep file column readable.
comm = 8
- pidTid = 9
+ pid = 6
+ tid = 6
syscall = 8
fd = 3
ret = 4
bytes = 7
- fixed = gap + latency + comm + pidTid + syscall + fd + ret + bytes + 8
+ fixed = gap + latency + comm + pid + tid + syscall + fd + ret + bytes + 9
file = width - fixed
if file < 12 {
file = 12
}
- return columnLayout{gap: gap, latency: latency, comm: comm, pidTid: pidTid, syscall: syscall, fd: fd, ret: ret, bytes: bytes, file: file}
+ return columnLayout{gap: gap, latency: latency, comm: comm, pid: pid, tid: tid, syscall: syscall, fd: fd, ret: ret, bytes: bytes, file: file}
}
func formatDurationNs(v uint64) string {