highlight.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package highlight
  2. import (
  3. "bytes"
  4. "image/color"
  5. "github.com/alecthomas/chroma/v2"
  6. "github.com/alecthomas/chroma/v2/formatters"
  7. "github.com/alecthomas/chroma/v2/lexers"
  8. chromaStyles "github.com/alecthomas/chroma/v2/styles"
  9. "github.com/charmbracelet/crush/internal/tui/styles"
  10. )
  11. func SyntaxHighlight(source, fileName string, bg color.Color) (string, error) {
  12. // Determine the language lexer to use
  13. l := lexers.Match(fileName)
  14. if l == nil {
  15. l = lexers.Analyse(source)
  16. }
  17. if l == nil {
  18. l = lexers.Fallback
  19. }
  20. l = chroma.Coalesce(l)
  21. // Get the formatter
  22. f := formatters.Get("terminal16m")
  23. if f == nil {
  24. f = formatters.Fallback
  25. }
  26. style := chroma.MustNewStyle("crush", styles.GetChromaTheme())
  27. // Modify the style to use the provided background
  28. s, err := style.Builder().Transform(
  29. func(t chroma.StyleEntry) chroma.StyleEntry {
  30. r, g, b, _ := bg.RGBA()
  31. t.Background = chroma.NewColour(uint8(r>>8), uint8(g>>8), uint8(b>>8))
  32. return t
  33. },
  34. ).Build()
  35. if err != nil {
  36. s = chromaStyles.Fallback
  37. }
  38. // Tokenize and format
  39. it, err := l.Tokenise(nil, source)
  40. if err != nil {
  41. return "", err
  42. }
  43. var buf bytes.Buffer
  44. err = f.Format(&buf, s, it)
  45. return buf.String(), err
  46. }