From 864735a540a0fb141dc6f67a8eff44a4df2488aa Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Mon, 9 Jun 2025 16:50:55 -0300 Subject: [PATCH] refactor(diffview): cache num digits on a struct variable --- internal/exp/diffview/diffview.go | 55 ++++++++++++++++--------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/internal/exp/diffview/diffview.go b/internal/exp/diffview/diffview.go index 19fc3b638d18e2442ce578ae2aa38f0be0eec582..c519223532c4e8eac851d1e8763f368bcbf0861a 100644 --- a/internal/exp/diffview/diffview.go +++ b/internal/exp/diffview/diffview.go @@ -45,8 +45,10 @@ type DiffView struct { splitHunks []splitHunk - codeWidth int - fullCodeWidth int // with leading symbols + codeWidth int + fullCodeWidth int // with leading symbols + beforeNumDigits int + afterNumDigits int } // New creates a new DiffView with default settings. @@ -130,6 +132,7 @@ func (dv *DiffView) String() string { return err.Error() } dv.convertDiffToSplit() + dv.detectNumDigits() dv.detectCodeWidth() switch dv.layout { @@ -144,14 +147,12 @@ func (dv *DiffView) String() string { // renderUnified renders the unified diff view as a string. func (dv *DiffView) renderUnified() string { - beforeNumDigits, afterNumDigits := dv.lineNumberDigits() - var b strings.Builder for _, h := range dv.unified.Hunks { if dv.lineNumbers { - b.WriteString(dv.style.DividerLine.LineNumber.Render(pad("…", beforeNumDigits))) - b.WriteString(dv.style.DividerLine.LineNumber.Render(pad("…", afterNumDigits))) + b.WriteString(dv.style.DividerLine.LineNumber.Render(pad("…", dv.beforeNumDigits))) + b.WriteString(dv.style.DividerLine.LineNumber.Render(pad("…", dv.afterNumDigits))) } b.WriteString(dv.style.DividerLine.Code.Width(dv.fullCodeWidth).Render(dv.hunkLineFor(h))) b.WriteRune('\n') @@ -165,24 +166,24 @@ func (dv *DiffView) renderUnified() string { switch l.Kind { case udiff.Equal: if dv.lineNumbers { - b.WriteString(dv.style.EqualLine.LineNumber.Render(pad(beforeLine, beforeNumDigits))) - b.WriteString(dv.style.EqualLine.LineNumber.Render(pad(afterLine, afterNumDigits))) + b.WriteString(dv.style.EqualLine.LineNumber.Render(pad(beforeLine, dv.beforeNumDigits))) + b.WriteString(dv.style.EqualLine.LineNumber.Render(pad(afterLine, dv.afterNumDigits))) } b.WriteString(dv.style.EqualLine.Code.Width(dv.fullCodeWidth).Render(" " + content)) beforeLine++ afterLine++ case udiff.Insert: if dv.lineNumbers { - b.WriteString(dv.style.InsertLine.LineNumber.Render(pad(" ", beforeNumDigits))) - b.WriteString(dv.style.InsertLine.LineNumber.Render(pad(afterLine, afterNumDigits))) + b.WriteString(dv.style.InsertLine.LineNumber.Render(pad(" ", dv.beforeNumDigits))) + b.WriteString(dv.style.InsertLine.LineNumber.Render(pad(afterLine, dv.afterNumDigits))) } b.WriteString(dv.style.InsertLine.Symbol.Render("+ ")) b.WriteString(dv.style.InsertLine.Code.Width(dv.codeWidth).Render(content)) afterLine++ case udiff.Delete: if dv.lineNumbers { - b.WriteString(dv.style.DeleteLine.LineNumber.Render(pad(beforeLine, beforeNumDigits))) - b.WriteString(dv.style.DeleteLine.LineNumber.Render(pad(" ", afterNumDigits))) + b.WriteString(dv.style.DeleteLine.LineNumber.Render(pad(beforeLine, dv.beforeNumDigits))) + b.WriteString(dv.style.DeleteLine.LineNumber.Render(pad(" ", dv.afterNumDigits))) } b.WriteString(dv.style.DeleteLine.Symbol.Render("- ")) b.WriteString(dv.style.DeleteLine.Code.Width(dv.codeWidth).Render(content)) @@ -197,17 +198,15 @@ func (dv *DiffView) renderUnified() string { // renderSplit renders the split (side-by-side) diff view as a string. func (dv *DiffView) renderSplit() string { - beforeNumDigits, afterNumDigits := dv.lineNumberDigits() - var b strings.Builder for i, h := range dv.splitHunks { if dv.lineNumbers { - b.WriteString(dv.style.DividerLine.LineNumber.Render(pad("…", beforeNumDigits))) + b.WriteString(dv.style.DividerLine.LineNumber.Render(pad("…", dv.beforeNumDigits))) } b.WriteString(dv.style.DividerLine.Code.Width(dv.fullCodeWidth).Render(dv.hunkLineFor(dv.unified.Hunks[i]))) if dv.lineNumbers { - b.WriteString(dv.style.DividerLine.LineNumber.Render(pad("…", afterNumDigits))) + b.WriteString(dv.style.DividerLine.LineNumber.Render(pad("…", dv.afterNumDigits))) } b.WriteString(dv.style.DividerLine.Code.Width(dv.fullCodeWidth).Render(" ")) b.WriteRune('\n') @@ -228,18 +227,18 @@ func (dv *DiffView) renderSplit() string { switch { case l.before == nil: if dv.lineNumbers { - b.WriteString(dv.style.MissingLine.LineNumber.Render(pad(" ", beforeNumDigits))) + b.WriteString(dv.style.MissingLine.LineNumber.Render(pad(" ", dv.beforeNumDigits))) } b.WriteString(dv.style.MissingLine.Code.Width(dv.fullCodeWidth).Render(" ")) case l.before.Kind == udiff.Equal: if dv.lineNumbers { - b.WriteString(dv.style.EqualLine.LineNumber.Render(pad(beforeLine, beforeNumDigits))) + b.WriteString(dv.style.EqualLine.LineNumber.Render(pad(beforeLine, dv.beforeNumDigits))) } b.WriteString(dv.style.EqualLine.Code.Width(dv.fullCodeWidth).Render(" " + beforeContent)) beforeLine++ case l.before.Kind == udiff.Delete: if dv.lineNumbers { - b.WriteString(dv.style.DeleteLine.LineNumber.Render(pad(beforeLine, beforeNumDigits))) + b.WriteString(dv.style.DeleteLine.LineNumber.Render(pad(beforeLine, dv.beforeNumDigits))) } b.WriteString(dv.style.DeleteLine.Symbol.Render("- ")) b.WriteString(dv.style.DeleteLine.Code.Width(dv.codeWidth).Render(beforeContent)) @@ -249,18 +248,18 @@ func (dv *DiffView) renderSplit() string { switch { case l.after == nil: if dv.lineNumbers { - b.WriteString(dv.style.MissingLine.LineNumber.Render(pad(" ", afterNumDigits))) + b.WriteString(dv.style.MissingLine.LineNumber.Render(pad(" ", dv.afterNumDigits))) } b.WriteString(dv.style.MissingLine.Code.Width(dv.fullCodeWidth).Render(" ")) case l.after.Kind == udiff.Equal: if dv.lineNumbers { - b.WriteString(dv.style.EqualLine.LineNumber.Render(pad(afterLine, afterNumDigits))) + b.WriteString(dv.style.EqualLine.LineNumber.Render(pad(afterLine, dv.afterNumDigits))) } b.WriteString(dv.style.EqualLine.Code.Width(dv.fullCodeWidth).Render(" " + afterContent)) afterLine++ case l.after.Kind == udiff.Insert: if dv.lineNumbers { - b.WriteString(dv.style.InsertLine.LineNumber.Render(pad(afterLine, afterNumDigits))) + b.WriteString(dv.style.InsertLine.LineNumber.Render(pad(afterLine, dv.afterNumDigits))) } b.WriteString(dv.style.InsertLine.Symbol.Render("+ ")) b.WriteString(dv.style.InsertLine.Code.Width(dv.codeWidth).Render(afterContent)) @@ -293,14 +292,16 @@ func (dv *DiffView) computeDiff() error { return dv.err } -// lineNumberDigits calculates the maximum number of digits needed for before and +// detectNumDigits calculates the maximum number of digits needed for before and // after line numbers. -func (dv *DiffView) lineNumberDigits() (maxBefore, maxAfter int) { +func (dv *DiffView) detectNumDigits() { + dv.beforeNumDigits = 0 + dv.afterNumDigits = 0 + for _, h := range dv.unified.Hunks { - maxBefore = max(maxBefore, len(strconv.Itoa(h.FromLine+len(h.Lines)))) - maxAfter = max(maxAfter, len(strconv.Itoa(h.ToLine+len(h.Lines)))) + dv.beforeNumDigits = max(dv.beforeNumDigits, len(strconv.Itoa(h.FromLine+len(h.Lines)))) + dv.afterNumDigits = max(dv.afterNumDigits, len(strconv.Itoa(h.ToLine+len(h.Lines)))) } - return } func (dv *DiffView) hunkLineFor(h *udiff.Hunk) string {