diff options
| author | Paul Buetow <paul@buetow.org> | 2026-02-26 23:08:14 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-02-26 23:08:14 +0200 |
| commit | c3106802208b18f78d4ff4b22e1d889ac19f817f (patch) | |
| tree | c01fe438cf1d0699d7b08b919c3b5494ee18a32f /internal/tui/eventstream/render.go | |
| parent | dc7478d7dadf544787a9718608f11312bd2ea944 (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.go | 79 |
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 { |
