fix(diffview): fix rendering issue caused by line breaks added by chroma

Andrey Nering created

Change summary

internal/tui/exp/diffview/chroma.go                                          |  7 
internal/tui/exp/diffview/diffview_test.go                                   | 26 
internal/tui/exp/diffview/testdata/TestDiffViewLineBreakIssue/Split.golden   |  9 
internal/tui/exp/diffview/testdata/TestDiffViewLineBreakIssue/Unified.golden | 12 
internal/tui/exp/diffview/testdata/TestLineBreakIssue.after                  |  8 
internal/tui/exp/diffview/testdata/TestLineBreakIssue.before                 |  6 
6 files changed, 66 insertions(+), 2 deletions(-)

Detailed changes

internal/tui/exp/diffview/chroma.go 🔗

@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"image/color"
 	"io"
+	"strings"
 
 	"github.com/alecthomas/chroma/v2"
 	"github.com/charmbracelet/lipgloss/v2"
@@ -20,9 +21,11 @@ type chromaFormatter struct {
 // Format implements the chroma.Formatter interface.
 func (c chromaFormatter) Format(w io.Writer, style *chroma.Style, it chroma.Iterator) error {
 	for token := it(); token != chroma.EOF; token = it() {
+		value := strings.TrimSuffix(token.Value, "\n")
+
 		entry := style.Get(token.Type)
 		if entry.IsZero() {
-			if _, err := fmt.Fprint(w, token.Value); err != nil {
+			if _, err := fmt.Fprint(w, value); err != nil {
 				return err
 			}
 			continue
@@ -44,7 +47,7 @@ func (c chromaFormatter) Format(w io.Writer, style *chroma.Style, it chroma.Iter
 			s = s.Foreground(lipgloss.Color(entry.Colour.String()))
 		}
 
-		if _, err := fmt.Fprint(w, s.Render(token.Value)); err != nil {
+		if _, err := fmt.Fprint(w, s.Render(value)); err != nil {
 			return err
 		}
 	}

internal/tui/exp/diffview/diffview_test.go 🔗

@@ -36,6 +36,12 @@ var TestTabsBefore string
 //go:embed testdata/TestTabs.after
 var TestTabsAfter string
 
+//go:embed testdata/TestLineBreakIssue.before
+var TestLineBreakIssueBefore string
+
+//go:embed testdata/TestLineBreakIssue.after
+var TestLineBreakIssueAfter string
+
 type (
 	TestFunc  func(dv *diffview.DiffView) *diffview.DiffView
 	TestFuncs map[string]TestFunc
@@ -177,6 +183,26 @@ func TestDiffViewTabs(t *testing.T) {
 	}
 }
 
+func TestDiffViewLineBreakIssue(t *testing.T) {
+	t.Parallel()
+
+	for layoutName, layoutFunc := range LayoutFuncs {
+		t.Run(layoutName, func(t *testing.T) {
+			t.Parallel()
+
+			dv := diffview.New().
+				Before("index.js", TestLineBreakIssueBefore).
+				After("index.js", TestLineBreakIssueAfter).
+				Style(diffview.DefaultLightStyle()).
+				ChromaStyle(styles.Get("catppuccin-latte"))
+			dv = layoutFunc(dv)
+
+			output := dv.String()
+			golden.RequireEqual(t, []byte(output))
+		})
+	}
+}
+
 func TestDiffViewWidth(t *testing.T) {
 	for layoutName, layoutFunc := range LayoutFuncs {
 		t.Run(layoutName, func(t *testing.T) {

internal/tui/exp/diffview/testdata/TestDiffViewLineBreakIssue/Split.golden 🔗

@@ -0,0 +1,9 @@
+  …   @@ -1,6 +1,8 @@                     …                                     
+  1 - // this is                          1 + /**                               
+                                          2 +  * this is                        
+  2 - // a regular                        3 +  * a block                        
+  3 - // comment                          4 +  * comment                        
+                                          5 +  */                               
+  4   $(function() {                      6   $(function() {                    
+  5       console.log("Hello, world!");   7       console.log("Hello, world!"); 
+  6   });                                 8   });                               

internal/tui/exp/diffview/testdata/TestDiffViewLineBreakIssue/Unified.golden 🔗

@@ -0,0 +1,12 @@
+  …   …   @@ -1,6 +1,8 @@                   
+  1     - // this is                        
+      1 + /**                               
+      2 +  * this is                        
+  2     - // a regular                      
+      3 +  * a block                        
+  3     - // comment                        
+      4 +  * comment                        
+      5 +  */                               
+  4   6   $(function() {                    
+  5   7       console.log("Hello, world!"); 
+  6   8   });