package common import ( "bytes" "image/color" "github.com/alecthomas/chroma/v2" "github.com/alecthomas/chroma/v2/formatters" "github.com/alecthomas/chroma/v2/lexers" chromastyles "github.com/alecthomas/chroma/v2/styles" "github.com/charmbracelet/crush/internal/ui/styles" ) // SyntaxHighlight applies syntax highlighting to the given source code based // on the file name and background color. It returns the highlighted code as a // string. func SyntaxHighlight(st *styles.Styles, source, fileName string, bg color.Color) (string, error) { // Determine the language lexer to use l := lexers.Match(fileName) if l == nil { l = lexers.Analyse(source) } if l == nil { l = lexers.Fallback } l = chroma.Coalesce(l) // Get the formatter f := formatters.Get("terminal16m") if f == nil { f = formatters.Fallback } style := chroma.MustNewStyle("crush", st.ChromaTheme()) // Modify the style to use the provided background s, err := style.Builder().Transform( func(t chroma.StyleEntry) chroma.StyleEntry { r, g, b, _ := bg.RGBA() t.Background = chroma.NewColour(uint8(r>>8), uint8(g>>8), uint8(b>>8)) return t }, ).Build() if err != nil { s = chromastyles.Fallback } // Tokenize and format it, err := l.Tokenise(nil, source) if err != nil { return "", err } var buf bytes.Buffer err = f.Format(&buf, s, it) return buf.String(), err }