Skip to content

Commit 0d8dc09

Browse files
MaybeSam05ndeloof
authored andcommitted
cmd/display: left-pad timers for right-aligned column
Signed-off-by: Samarth Verma <verma.samarth05@gmail.com>
1 parent 02aaf25 commit 0d8dc09

2 files changed

Lines changed: 65 additions & 1 deletion

File tree

cmd/display/tty.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,10 @@ func (w *ttyWriter) printWithDimensions(terminalWidth, terminalHeight int) {
347347
}
348348
timerWidth := utf8.RuneCountInString(l.timer)
349349
if timerWidth < timerLen {
350-
l.timer = l.timer + strings.Repeat(" ", timerLen-timerWidth)
350+
// Left-pad so the timer's right edge stays aligned on the terminal.
351+
// This also prevents stale suffix characters from visually “sticking”
352+
// when a previously-rendered timer was wider (e.g. "10.6s" -> "0.0s").
353+
l.timer = strings.Repeat(" ", timerLen-timerWidth) + l.timer
351354
}
352355
}
353356

cmd/display/tty_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,67 @@ func TestPrintWithDimensions_PulledAndPullingWithLongIDs(t *testing.T) {
404404
}
405405
}
406406

407+
func TestPrintWithDimensions_TimerIsRightAligned(t *testing.T) {
408+
w, buf := newTestWriter()
409+
410+
base := time.Unix(0, 0)
411+
412+
// Long timer: "10.6s" (length 5)
413+
longTask := &task{
414+
ID: "task-long",
415+
parents: make(map[string]struct{}),
416+
startTime: base,
417+
endTime: base.Add(10*time.Second + 600*time.Millisecond),
418+
text: "Pulled",
419+
status: api.Done,
420+
spinner: NewSpinner(),
421+
}
422+
longTask.spinner.Stop()
423+
w.tasks[longTask.ID] = longTask
424+
w.ids = append(w.ids, longTask.ID)
425+
426+
// Short timer: "0.0s" (length 4)
427+
shortTask := &task{
428+
ID: "task-short",
429+
parents: make(map[string]struct{}),
430+
startTime: base,
431+
endTime: base,
432+
text: "Pulled",
433+
status: api.Done,
434+
spinner: NewSpinner(),
435+
}
436+
shortTask.spinner.Stop()
437+
w.tasks[shortTask.ID] = shortTask
438+
w.ids = append(w.ids, shortTask.ID)
439+
440+
terminalWidth := 80
441+
w.printWithDimensions(terminalWidth, 24)
442+
443+
// Strip ANSI codes from output and split by newline
444+
stripped := stripAnsi(buf.String())
445+
lines := strings.Split(stripped, "\n")
446+
447+
var nonEmptyLines []string
448+
for _, line := range lines {
449+
if strings.TrimSpace(line) != "" {
450+
nonEmptyLines = append(nonEmptyLines, line)
451+
}
452+
}
453+
454+
// Find the line containing the shorter timer.
455+
var shortLine string
456+
for _, line := range nonEmptyLines {
457+
if strings.Contains(line, "0.0s") {
458+
shortLine = line
459+
break
460+
}
461+
}
462+
assert.Assert(t, shortLine != "", "expected to find a rendered line containing \"0.0s\"")
463+
assert.Assert(t, strings.HasSuffix(shortLine, "0.0s"),
464+
"short timer should be left-padded (no trailing spaces after the timer); got: %q",
465+
shortLine)
466+
}
467+
407468
func TestLenAnsi(t *testing.T) {
408469
testCases := []struct {
409470
input string

0 commit comments

Comments
 (0)