summaryrefslogtreecommitdiff
path: root/internal/tui
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
parentdc7478d7dadf544787a9718608f11312bd2ea944 (diff)
tui: add paused stream column selection and split pid/tid
Diffstat (limited to 'internal/tui')
-rw-r--r--internal/tui/common/keys.go8
-rw-r--r--internal/tui/dashboard/model.go15
-rw-r--r--internal/tui/dashboard/model_test.go16
-rw-r--r--internal/tui/eventstream/model.go53
-rw-r--r--internal/tui/eventstream/model_test.go41
-rw-r--r--internal/tui/eventstream/render.go79
-rw-r--r--internal/tui/eventstream/render_test.go16
7 files changed, 163 insertions, 65 deletions
diff --git a/internal/tui/common/keys.go b/internal/tui/common/keys.go
index acb066b..30bc848 100644
--- a/internal/tui/common/keys.go
+++ b/internal/tui/common/keys.go
@@ -64,8 +64,8 @@ func (k KeyMap) DashboardStatusHelp() []key.Binding {
k.Probes,
k.Refresh,
k.Quit,
- helpTextBinding("left/right", "tab"),
- helpTextBinding("h/l", "tab"),
+ helpTextBinding("left/right", "stream col"),
+ helpTextBinding("h/l", "stream col"),
helpTextBinding("j/k", "scroll"),
helpTextBinding("up/down", "scroll"),
)
@@ -84,8 +84,8 @@ func (k KeyMap) DashboardFullHelp() [][]key.Binding {
{k.One, k.Two, k.Three, k.Four, k.Five, k.Six},
controls,
{
- helpTextBinding("left/right", "tab"),
- helpTextBinding("h/l", "tab"),
+ helpTextBinding("left/right", "stream col"),
+ helpTextBinding("h/l", "stream col"),
helpTextBinding("j/k", "scroll"),
helpTextBinding("up/down", "scroll"),
},
diff --git a/internal/tui/dashboard/model.go b/internal/tui/dashboard/model.go
index 026e63e..fae6a1b 100644
--- a/internal/tui/dashboard/model.go
+++ b/internal/tui/dashboard/model.go
@@ -107,7 +107,7 @@ func (m Model) handleKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
prevActiveTab := m.activeTab
var cmd tea.Cmd
keyStr := msg.String()
- handled := m.handleArrowTabKey(keyStr) || m.handleScrollKey(msg)
+ handled := m.handleScrollKey(msg)
if handled && m.activeTab == TabStream && (keyStr == " " || keyStr == "space") && !m.streamModel.Paused() {
cmd = streamTickCmd()
}
@@ -164,19 +164,6 @@ func (m Model) handleKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
return m, cmd
}
-func (m *Model) handleArrowTabKey(keyStr string) bool {
- switch keyStr {
- case "right", "l":
- m.activeTab = nextTab(m.activeTab)
- return true
- case "left", "h":
- m.activeTab = prevTab(m.activeTab)
- return true
- default:
- return false
- }
-}
-
func (m *Model) handleScrollKey(msg tea.KeyMsg) bool {
keyStr := msg.String()
switch m.activeTab {
diff --git a/internal/tui/dashboard/model_test.go b/internal/tui/dashboard/model_test.go
index a0e0539..37dbe28 100644
--- a/internal/tui/dashboard/model_test.go
+++ b/internal/tui/dashboard/model_test.go
@@ -59,31 +59,31 @@ func TestKeySwitchingChangesActiveTab(t *testing.T) {
}
}
-func TestArrowAndViKeysCycleTabs(t *testing.T) {
+func TestArrowAndViKeysDoNotCycleTabs(t *testing.T) {
m := NewModelWithConfig(nil, nil, 250, common.DefaultKeyMap())
next, _ := m.Update(tea.KeyMsg{Type: tea.KeyRight})
model := next.(Model)
- if model.activeTab != TabSyscalls {
- t.Fatalf("expected right arrow to move to syscalls, got %v", model.activeTab)
+ if model.activeTab != TabOverview {
+ t.Fatalf("expected right arrow not to change tabs, got %v", model.activeTab)
}
next, _ = model.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'l'}})
model = next.(Model)
- if model.activeTab != TabFiles {
- t.Fatalf("expected l to move to files, got %v", model.activeTab)
+ if model.activeTab != TabOverview {
+ t.Fatalf("expected l not to change tabs, got %v", model.activeTab)
}
next, _ = model.Update(tea.KeyMsg{Type: tea.KeyLeft})
model = next.(Model)
- if model.activeTab != TabSyscalls {
- t.Fatalf("expected left arrow to move back to syscalls, got %v", model.activeTab)
+ if model.activeTab != TabOverview {
+ t.Fatalf("expected left arrow not to change tabs, got %v", model.activeTab)
}
next, _ = model.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{'h'}})
model = next.(Model)
if model.activeTab != TabOverview {
- t.Fatalf("expected h to move back to overview, got %v", model.activeTab)
+ t.Fatalf("expected h not to change tabs, got %v", model.activeTab)
}
}
diff --git a/internal/tui/eventstream/model.go b/internal/tui/eventstream/model.go
index 42018d5..d757209 100644
--- a/internal/tui/eventstream/model.go
+++ b/internal/tui/eventstream/model.go
@@ -7,6 +7,8 @@ import (
tea "github.com/charmbracelet/bubbletea"
)
+const streamColumnCount = 10
+
type Model struct {
source *RingBuffer
@@ -24,6 +26,7 @@ type Model struct {
scrollOffset int
autoScroll bool
selectedIdx int
+ selectedCol int
fdTraceView fdTraceViewState
width int
@@ -44,6 +47,7 @@ func NewModel(source *RingBuffer) Model {
filterModal: NewFilterModal(),
autoScroll: true,
selectedIdx: -1,
+ selectedCol: 0,
}
}
@@ -98,6 +102,10 @@ func (m *Model) HandleKey(keyStr string) bool {
case "k", "up":
m.scrollFDTraceByLines(-1)
return true
+ case "left", "h":
+ return true
+ case "right", "l":
+ return true
case "pgdown", "pgdn", "pagedown":
m.scrollFDTraceByLines(m.pageStep())
return true
@@ -135,6 +143,7 @@ func (m *Model) HandleKey(keyStr string) bool {
m.Refresh()
} else {
m.ensureSelection()
+ m.ensureSelectedCol()
m.centerSelection()
}
return true
@@ -177,6 +186,18 @@ func (m *Model) HandleKey(keyStr string) bool {
m.scrollByLines(-1)
}
return true
+ case "left", "h":
+ if m.paused {
+ m.moveSelectedColBy(-1)
+ return true
+ }
+ return false
+ case "right", "l":
+ if m.paused {
+ m.moveSelectedColBy(1)
+ return true
+ }
+ return false
case "pgdown", "pgdn", "pagedown":
if m.paused {
m.moveSelectionBy(m.pageStep())
@@ -200,6 +221,10 @@ func (m *Model) HandleKey(keyStr string) bool {
// then falls back to string matching for rune-driven shortcuts.
func (m *Model) HandleTeaKey(msg tea.KeyMsg) bool {
switch msg.Type {
+ case tea.KeyLeft:
+ return m.HandleKey("left")
+ case tea.KeyRight:
+ return m.HandleKey("right")
case tea.KeyUp:
return m.HandleKey("up")
case tea.KeyDown:
@@ -253,10 +278,14 @@ func (m *Model) View(width, height int) string {
bufferLen = m.source.Len()
}
- base := RenderStreamTable(width, m.paused, len(m.allEvents), len(m.filtered), bufferLen, ringBufferCapacity, m.filter, visible, selectedVisibleIdx)
+ selectedCol := -1
+ if m.paused && selectedVisibleIdx >= 0 {
+ selectedCol = m.selectedCol
+ }
+ base := RenderStreamTable(width, m.paused, len(m.allEvents), len(m.filtered), bufferLen, ringBufferCapacity, m.filter, visible, selectedVisibleIdx, selectedCol)
status := fmt.Sprintf("Row %d/%d | space:pause f:filter G:tail g:top c:clear j/k:scroll", rowNumber(start, len(m.filtered)), len(m.filtered))
if m.paused && m.selectedIdx >= 0 {
- status = fmt.Sprintf("Row %d/%d | Sel %d/%d | enter:fd-trace space:pause f:filter G:tail g:top c:clear j/k:select", rowNumber(start, len(m.filtered)), len(m.filtered), rowNumber(m.selectedIdx, len(m.filtered)), len(m.filtered))
+ status = fmt.Sprintf("Row %d/%d | Sel %d/%d Col %d/%d | enter:fd-trace space:pause f:filter G:tail g:top c:clear j/k:row h/l:col", rowNumber(start, len(m.filtered)), len(m.filtered), rowNumber(m.selectedIdx, len(m.filtered)), len(m.filtered), m.selectedCol+1, streamColumnCount)
}
out := base + "\n" + status
@@ -309,6 +338,7 @@ func (m *Model) applyFilter() {
m.clampSelection()
if m.paused {
m.ensureSelection()
+ m.ensureSelectedCol()
m.centerSelection()
}
}
@@ -435,6 +465,7 @@ func (m *Model) moveSelectionBy(delta int) {
return
}
m.ensureSelection()
+ m.ensureSelectedCol()
m.moveSelectionTo(m.selectedIdx + delta)
}
@@ -444,6 +475,7 @@ func (m *Model) moveSelectionTo(idx int) {
return
}
m.selectedIdx = clamp(idx, 0, len(m.filtered)-1)
+ m.ensureSelectedCol()
m.centerSelection()
}
@@ -469,6 +501,23 @@ func (m *Model) ensureSelection() {
m.selectedIdx = clamp(m.scrollOffset+mid, 0, len(m.filtered)-1)
}
+func (m *Model) ensureSelectedCol() {
+ if m.selectedCol < 0 {
+ m.selectedCol = 0
+ }
+ if m.selectedCol >= streamColumnCount {
+ m.selectedCol = streamColumnCount - 1
+ }
+}
+
+func (m *Model) moveSelectedColBy(delta int) {
+ if delta == 0 {
+ return
+ }
+ m.ensureSelectedCol()
+ m.selectedCol = clamp(m.selectedCol+delta, 0, streamColumnCount-1)
+}
+
func (m *Model) clampSelection() {
if len(m.filtered) == 0 {
m.selectedIdx = -1
diff --git a/internal/tui/eventstream/model_test.go b/internal/tui/eventstream/model_test.go
index 3dac038..e58144a 100644
--- a/internal/tui/eventstream/model_test.go
+++ b/internal/tui/eventstream/model_test.go
@@ -373,6 +373,47 @@ func TestPausedSelectionMovesAndRecentersWithJKAndArrows(t *testing.T) {
}
}
+func TestPausedSelectionMovesAcrossColumnsWithLeftRightAndHL(t *testing.T) {
+ rb := NewRingBuffer()
+ m := NewModel(rb)
+ m.height = 20
+ pushEvents(rb, 100)
+ m.Refresh()
+
+ if !m.HandleKey("space") {
+ t.Fatalf("space should toggle pause")
+ }
+ startCol := m.selectedCol
+ startRow := m.selectedIdx
+
+ if !m.HandleKey("right") {
+ t.Fatalf("right should be handled while paused")
+ }
+ if m.selectedCol != startCol+1 {
+ t.Fatalf("expected selected col +1 after right, got %d->%d", startCol, m.selectedCol)
+ }
+ if m.selectedIdx != startRow {
+ t.Fatalf("expected selected row unchanged after right, got %d->%d", startRow, m.selectedIdx)
+ }
+
+ if !m.HandleKey("l") {
+ t.Fatalf("l should be handled while paused")
+ }
+ if m.selectedCol != startCol+2 {
+ t.Fatalf("expected selected col +2 after l, got %d", m.selectedCol)
+ }
+
+ if !m.HandleKey("left") {
+ t.Fatalf("left should be handled while paused")
+ }
+ if !m.HandleKey("h") {
+ t.Fatalf("h should be handled while paused")
+ }
+ if m.selectedCol != startCol {
+ t.Fatalf("expected selected col back to start, got %d", m.selectedCol)
+ }
+}
+
func TestPausedEnterOpensFDTraceViewScopedByPIDAndFD(t *testing.T) {
rb := NewRingBuffer()
rb.Push(StreamEvent{Seq: 1, PID: 10, TID: 101, FD: 3, Syscall: "read", FileName: "/a"})
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 {
diff --git a/internal/tui/eventstream/render_test.go b/internal/tui/eventstream/render_test.go
index 33e5b38..b020edf 100644
--- a/internal/tui/eventstream/render_test.go
+++ b/internal/tui/eventstream/render_test.go
@@ -10,7 +10,7 @@ import (
func TestRenderStatusAndFilterLines(t *testing.T) {
events := []StreamEvent{{Syscall: "read", Comm: "nginx", PID: 1, TID: 2, DurationNs: 1200, GapNs: 300, Bytes: 64, FileName: "/tmp/a", RetVal: 64}}
f := Filter{Syscall: &StringFilter{Pattern: "read"}, PID: &NumericFilter{Op: OpEq, Value: 1}}
- out := RenderStreamTable(120, false, 100, 1, 100, 10000, f, events, -1)
+ out := RenderStreamTable(120, false, 100, 1, 100, 10000, f, events, -1, -1)
for _, want := range []string{"LIVE", "total:100", "filtered:1", "buffer:100/10000", "Filter:", "syscall~read", "pid=1"} {
if !strings.Contains(out, want) {
@@ -21,7 +21,7 @@ func TestRenderStatusAndFilterLines(t *testing.T) {
func TestRenderPausedAndErrorRow(t *testing.T) {
events := []StreamEvent{{Syscall: "write", Comm: "worker", PID: 1, TID: 2, DurationNs: 1000000, GapNs: 5000, Bytes: 32, FileName: "/tmp/b", RetVal: -1, IsError: true}}
- out := RenderStreamTable(120, true, 10, 1, 10, 10000, Filter{}, events, -1)
+ out := RenderStreamTable(120, true, 10, 1, 10, 10000, Filter{}, events, -1, -1)
if !strings.Contains(out, "PAUSED") {
t.Fatalf("expected PAUSED indicator\n%s", out)
@@ -36,7 +36,7 @@ func TestRenderPausedAndErrorRow(t *testing.T) {
func TestRenderShowsFDWhenPresent(t *testing.T) {
events := []StreamEvent{{Syscall: "read", Comm: "worker", PID: 1, TID: 2, FD: 9, DurationNs: 10, GapNs: 1, Bytes: 8, FileName: "/tmp/b", RetVal: 8}}
- out := RenderStreamTable(120, false, 1, 1, 1, 10000, Filter{}, events, -1)
+ out := RenderStreamTable(120, false, 1, 1, 1, 10000, Filter{}, events, -1, -1)
if !strings.Contains(out, "FD") || !strings.Contains(out, " 9 ") {
t.Fatalf("expected FD column/value in output\n%s", out)
}
@@ -54,9 +54,9 @@ func TestRenderHeaderAndTruncate(t *testing.T) {
FileName: "/very/long/path/that/should/be/truncated/for/narrow/views/file.log",
RetVal: 1,
}}
- out := RenderStreamTable(80, false, 1, 1, 1, 10000, Filter{}, events, -1)
+ out := RenderStreamTable(80, false, 1, 1, 1, 10000, Filter{}, events, -1, -1)
- for _, col := range []string{"Gap", "Latency", "Comm", "PID.TID", "Syscall", "FD", "Ret", "Bytes", "File"} {
+ for _, col := range []string{"Gap", "Latency", "Comm", "PID", "TID", "Syscall", "FD", "Ret", "Bytes", "File"} {
if !strings.Contains(out, col) {
t.Fatalf("missing column %q\n%s", col, out)
}
@@ -95,7 +95,7 @@ func TestRenderEventRowIsSingleLineWithControlCharsAndLongValues(t *testing.T) {
RetVal: -9223372036854775808,
}
- row := renderEventRow(ev, 80, false)
+ row := renderEventRow(ev, 80, false, -1)
if strings.Contains(row, "\n") || strings.Contains(row, "\r") || strings.Contains(row, "\t") {
t.Fatalf("expected a sanitized single-line row, got %q", row)
}
@@ -106,7 +106,7 @@ func TestRenderEventRowIsSingleLineWithControlCharsAndLongValues(t *testing.T) {
func TestComputeColumnLayoutGivesFileMoreSpace(t *testing.T) {
cols := computeColumnLayout(120)
- if cols.file < 50 {
+ if cols.file < 44 {
t.Fatalf("expected file column to get most width, got %d", cols.file)
}
}
@@ -124,7 +124,7 @@ func TestRenderStreamTableFitsRequestedWidth(t *testing.T) {
FileName: "/very/long/path/that/should/be/truncated/for/narrow/views/file.log",
RetVal: 1,
},
- }, -1)
+ }, -1, -1)
for _, line := range strings.Split(out, "\n") {
if lipgloss.Width(line) > 80 {