chroma.go 1.2 KB

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