chroma.go

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