@@ -2,6 +2,7 @@ package common
22
33import (
44 "image/color"
5+ "sync"
56
67 "charm.land/glamour/v2"
78 "github.com/alecthomas/chroma/v2/formatters"
@@ -18,24 +19,55 @@ func init() {
1819 formatters.Register(formatterName, xchroma.Formatter(zero, nil))
1920}
2021
22+var (
23+ mdCacheMu sync.Mutex
24+ mdCache = map[int]*glamour.TermRenderer{}
25+ quietMDCache = map[int]*glamour.TermRenderer{}
26+)
27+
2128// MarkdownRenderer returns a glamour [glamour.TermRenderer] configured with
22−// the given styles and width.
29+// the given styles and width. Renderers are memoized per width and shared
30+// across callers; call InvalidateMarkdownRendererCache when the active
31+// styles change.
2332func MarkdownRenderer(sty *styles.Styles, width int) *glamour.TermRenderer {
33+ mdCacheMu.Lock()
34+ defer mdCacheMu.Unlock()
35+ if r, ok := mdCache[width]; ok {
36+ return r
37+ }
2438 r, _ := glamour.NewTermRenderer(
2539 glamour.WithStyles(sty.Markdown),
2640 glamour.WithWordWrap(width),
2741 glamour.WithChromaFormatter(formatterName),
2842 )
43+ mdCache[width] = r
2944 return r
3045}
3146
3247// QuietMarkdownRenderer returns a glamour [glamour.TermRenderer] with no colors
33−// (plain text with structure) and the given width.
48+// (plain text with structure) and the given width. Renderers are memoized per
49+// width and shared across callers.
3450func QuietMarkdownRenderer(sty *styles.Styles, width int) *glamour.TermRenderer {
51+ mdCacheMu.Lock()
52+ defer mdCacheMu.Unlock()
53+ if r, ok := quietMDCache[width]; ok {
54+ return r
55+ }
3556 r, _ := glamour.NewTermRenderer(
3657 glamour.WithStyles(sty.QuietMarkdown),
3758 glamour.WithWordWrap(width),
3859 glamour.WithChromaFormatter(formatterName),
3960 )
61+ quietMDCache[width] = r
4062 return r
4163}
64+
65+// InvalidateMarkdownRendererCache drops every cached renderer. Call this
66+// whenever the active styles change so subsequent renderers pick up the new
67+// ansi.StyleConfig.
68+func InvalidateMarkdownRendererCache() {
69+ mdCacheMu.Lock()
70+ defer mdCacheMu.Unlock()
71+ mdCache = map[int]*glamour.TermRenderer{}
72+ quietMDCache = map[int]*glamour.TermRenderer{}
73+}