1package diffview
2
3import (
4 "fmt"
5 "image/color"
6 "io"
7 "strings"
8
9 "github.com/alecthomas/chroma/v2"
10 "github.com/charmbracelet/crush/internal/ansiext"
11 "github.com/charmbracelet/lipgloss/v2"
12)
13
14var _ chroma.Formatter = chromaFormatter{}
15
16// chromaFormatter is a custom formatter for Chroma that uses Lip Gloss for
17// foreground styling, while keeping a forced background color.
18type chromaFormatter struct {
19 bgColor color.Color
20}
21
22// Format implements the chroma.Formatter interface.
23func (c chromaFormatter) Format(w io.Writer, style *chroma.Style, it chroma.Iterator) error {
24 for token := it(); token != chroma.EOF; token = it() {
25 value := strings.TrimSuffix(token.Value, "\n")
26 value = ansiext.Escape(value)
27
28 entry := style.Get(token.Type)
29 if entry.IsZero() {
30 if _, err := fmt.Fprint(w, value); err != nil {
31 return err
32 }
33 continue
34 }
35
36 s := lipgloss.NewStyle().
37 Background(c.bgColor)
38
39 if entry.Bold == chroma.Yes {
40 s = s.Bold(true)
41 }
42 if entry.Underline == chroma.Yes {
43 s = s.Underline(true)
44 }
45 if entry.Italic == chroma.Yes {
46 s = s.Italic(true)
47 }
48 if entry.Colour.IsSet() {
49 s = s.Foreground(lipgloss.Color(entry.Colour.String()))
50 }
51
52 if _, err := fmt.Fprint(w, s.Render(value)); err != nil {
53 return err
54 }
55 }
56 return nil
57}