on main help sign in
fix(diffview): add fixes + more extensive testing for height handling
commit21ca2aed35aa8e771a047119127e5025f446854e authorAndrey Nering <andreynering@users.noreply.github.com> dateTue 10 Jun 2025, 17:01 (1 year ago) parent66cd982
3 files changed+88
internal/exp/diffview/Taskfile.yaml+20 internal/exp/diffview/diffview.go+34 internal/exp/diffview/diffview_test.go+34
internal/exp/diffview/Taskfile.yaml+20
@@ -40,3 +40,23 @@ tasks:
4040 - for: sources
4141 cmd: echo && echo "------- {{.ITEM}} -------" && echo && cat {{.ITEM}}
4242 silent: true
43+
44+ test:print:height:unified:
45+ desc: Print golden files for debugging
46+ method: none
47+ sources:
48+ - ./testdata/TestDiffViewHeight/Unified/LightMode/*.golden
49+ cmds:
50+ - for: sources
51+ cmd: echo && echo "------- {{.ITEM}} -------" && echo && cat {{.ITEM}}
52+ silent: true
53+
54+ test:print:height:split:
55+ desc: Print golden files for debugging
56+ method: none
57+ sources:
58+ - ./testdata/TestDiffViewHeight/Split/LightMode/*.golden
59+ cmds:
60+ - for: sources
61+ cmd: echo && echo "------- {{.ITEM}} -------" && echo && cat {{.ITEM}}
62+ silent: true
internal/exp/diffview/diffview.go+34
@@ -149,6 +149,9 @@ func (dv *DiffView) String() string {
149149 if dv.width > 0 {
150150 style = style.MaxWidth(dv.width)
151151 }
152+ if dv.height > 0 {
153+ style = style.MaxHeight(dv.height)
154+ }
152155
153156 switch dv.layout {
154157 case layoutUnified:
@@ -287,6 +290,7 @@ func (dv *DiffView) renderUnified() string {
287290 var b strings.Builder
288291
289292 fullContentStyle := lipgloss.NewStyle().MaxWidth(dv.fullCodeWidth)
293+ printedLines := 0
290294
291295 for _, h := range dv.unified.Hunks {
292296 if dv.lineNumbers {
@@ -296,6 +300,7 @@ func (dv *DiffView) renderUnified() string {
296300 content := ansi.Truncate(dv.hunkLineFor(h), dv.fullCodeWidth, "…")
297301 b.WriteString(dv.style.DividerLine.Code.Width(dv.fullCodeWidth).Render(content))
298302 b.WriteRune('\n')
303+ printedLines++
299304
300305 beforeLine := h.FromLine
301306 afterLine := h.ToLine
@@ -337,7 +342,19 @@ func (dv *DiffView) renderUnified() string {
337342 beforeLine++
338343 }
339344 b.WriteRune('\n')
345+
346+ printedLines++
347+ }
348+ }
349+
350+ for printedLines < dv.height {
351+ if dv.lineNumbers {
352+ b.WriteString(dv.style.MissingLine.LineNumber.Render(pad(" ", dv.beforeNumDigits)))
353+ b.WriteString(dv.style.MissingLine.LineNumber.Render(pad(" ", dv.afterNumDigits)))
340354 }
355+ b.WriteString(dv.style.MissingLine.Code.Width(dv.fullCodeWidth).Render(" "))
356+ b.WriteRune('\n')
357+ printedLines++
341358 }
342359
343360 return b.String()
@@ -349,6 +366,7 @@ func (dv *DiffView) renderSplit() string {
349366
350367 beforeFullContentStyle := lipgloss.NewStyle().MaxWidth(dv.fullCodeWidth)
351368 afterFullContentStyle := lipgloss.NewStyle().MaxWidth(dv.fullCodeWidth + btoi(dv.extraColOnAfter))
369+ printedLines := 0
352370
353371 for i, h := range dv.splitHunks {
354372 if dv.lineNumbers {
@@ -361,6 +379,7 @@ func (dv *DiffView) renderSplit() string {
361379 }
362380 b.WriteString(dv.style.DividerLine.Code.Width(dv.fullCodeWidth + btoi(dv.extraColOnAfter)).Render(" "))
363381 b.WriteRune('\n')
382+ printedLines++
364383
365384 beforeLine := h.fromLine
366385 afterLine := h.toLine
@@ -432,9 +451,24 @@ func (dv *DiffView) renderSplit() string {
432451 }
433452
434453 b.WriteRune('\n')
454+
455+ printedLines++
435456 }
436457 }
437458
459+ for printedLines < dv.height {
460+ if dv.lineNumbers {
461+ b.WriteString(dv.style.MissingLine.LineNumber.Render(pad("…", dv.beforeNumDigits)))
462+ }
463+ b.WriteString(dv.style.MissingLine.Code.Width(dv.fullCodeWidth).Render(" "))
464+ if dv.lineNumbers {
465+ b.WriteString(dv.style.MissingLine.LineNumber.Render(pad("…", dv.afterNumDigits)))
466+ }
467+ b.WriteString(dv.style.MissingLine.Code.Width(dv.fullCodeWidth + btoi(dv.extraColOnAfter)).Render(" "))
468+ b.WriteRune('\n')
469+ printedLines++
470+ }
471+
438472 return b.String()
439473}
440474
internal/exp/diffview/diffview_test.go+34
@@ -167,6 +167,32 @@ func TestDiffViewWidth(t *testing.T) {
167167 }
168168}
169169
170+func TestDiffViewHeight(t *testing.T) {
171+ for layoutName, layoutFunc := range LayoutFuncs {
172+ t.Run(layoutName, func(t *testing.T) {
173+ for themeName, themeFunc := range ThemeFuncs {
174+ t.Run(themeName, func(t *testing.T) {
175+ for height := 1; height <= 20; height++ {
176+ t.Run(fmt.Sprintf("HeightOf%03d", height), func(t *testing.T) {
177+ dv := diffview.New().
178+ Before("main.go", TestMultipleHunksBefore).
179+ After("main.go", TestMultipleHunksAfter).
180+ Height(height)
181+ dv = layoutFunc(dv)
182+ dv = themeFunc(dv)
183+
184+ output := dv.String()
185+ golden.RequireEqual(t, []byte(output))
186+
187+ assertHeight(t, height, output)
188+ })
189+ }
190+ })
191+ }
192+ })
193+ }
194+}
195+
170196func assertLineWidth(t *testing.T, expected int, output string) {
171197 var lineWidth int
172198 for line := range strings.SplitSeq(output, "\n") {
@@ -176,3 +202,11 @@ func assertLineWidth(t *testing.T, expected int, output string) {
176202 t.Errorf("expected output width to be == %d, got %d", expected, lineWidth)
177203 }
178204}
205+
206+func assertHeight(t *testing.T, expected int, output string) {
207+ output = strings.TrimSuffix(output, "\n")
208+ lines := strings.Count(output, "\n") + 1
209+ if lines != expected {
210+ t.Errorf("expected output height to be == %d, got %d", expected, lines)
211+ }
212+}