Skip to content

Commit

Permalink
fix(color): resolve palette before ANSI conversion
Browse files Browse the repository at this point in the history
resolves #5790
  • Loading branch information
JanDeDobbeleer committed Nov 4, 2024
1 parent 4ac1033 commit 6a8cecb
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 9 deletions.
16 changes: 16 additions & 0 deletions src/color/colors.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var TrueColor = true
// but also a name of one of the first 16 ANSI colors like `lightBlue`.
type String interface {
ToAnsi(colorString Ansi, isBackground bool) Ansi
Resolve(colorString Ansi) (Ansi, error)
}

type Set struct {
Expand Down Expand Up @@ -150,12 +151,15 @@ func MakeColors(palette Palette, cacheEnabled bool, accentColor Ansi, env runtim
defaultColors := &Defaults{}
defaultColors.SetAccentColor(env, accentColor)
colors = defaultColors

if palette != nil {
colors = &PaletteColors{ansiColors: colors, palette: palette}
}

if cacheEnabled {
colors = &Cached{ansiColors: colors}
}

return
}

Expand Down Expand Up @@ -288,6 +292,10 @@ func (d *Defaults) ToAnsi(ansiColor Ansi, isBackground bool) Ansi {
return emptyColor
}

func (d *Defaults) Resolve(colorString Ansi) (Ansi, error) {
return colorString, nil
}

// getAnsiColorFromName returns the color code for a given color name if the name is
// known ANSI color name.
func getAnsiColorFromName(colorValue Ansi, isBackground bool) (Ansi, error) {
Expand Down Expand Up @@ -325,6 +333,10 @@ func (p *PaletteColors) ToAnsi(colorString Ansi, isBackground bool) Ansi {
return ansiColor
}

func (p *PaletteColors) Resolve(colorString Ansi) (Ansi, error) {
return p.palette.ResolveColor(colorString)
}

// Cached is the AnsiColors Decorator that does simple color lookup caching.
// ToColor calls are cheap, but not free, and having a simple cache in
// has measurable positive effect on performance.
Expand All @@ -350,3 +362,7 @@ func (c *Cached) ToAnsi(colorString Ansi, isBackground bool) Ansi {
c.colorCache[key] = ansiColor
return ansiColor
}

func (c *Cached) Resolve(colorString Ansi) (Ansi, error) {
return c.ansiColors.Resolve(colorString)
}
22 changes: 13 additions & 9 deletions src/terminal/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,10 +382,6 @@ func writeEscapedAnsiString(text string) {
builder.WriteString(text)
}

func getAnsiFromColorString(colorString color.Ansi, isBackground bool) color.Ansi {
return Colors.ToAnsi(colorString, isBackground)
}

func write(s rune) {
if isInvisible {
return
Expand Down Expand Up @@ -430,7 +426,7 @@ func writeSegmentColors() {

switch {
case fg.IsTransparent() && len(BackgroundColor) != 0:
background := getAnsiFromColorString(BackgroundColor, false)
background := Colors.ToAnsi(BackgroundColor, false)
writeEscapedAnsiString(fmt.Sprintf(colorise, background))
writeEscapedAnsiString(fmt.Sprintf(colorise, bg.ToForeground()))
case fg.IsTransparent() && !bg.IsEmpty():
Expand Down Expand Up @@ -496,7 +492,7 @@ func writeArchorOverride(match map[string]string, background color.Ansi, i int)
currentColor.Add(bg, fg)

if currentColor.Foreground().IsTransparent() && len(BackgroundColor) != 0 {
background := getAnsiFromColorString(BackgroundColor, false)
background := Colors.ToAnsi(BackgroundColor, false)
writeEscapedAnsiString(fmt.Sprintf(colorise, background))
writeEscapedAnsiString(fmt.Sprintf(colorise, currentColor.Background().ToForeground()))
return position
Expand Down Expand Up @@ -606,12 +602,20 @@ func asAnsiColors(background, foreground color.Ansi) (color.Ansi, color.Ansi) {
background = background.Resolve(CurrentColors, ParentColors)
foreground = foreground.Resolve(CurrentColors, ParentColors)

if bg, err := Colors.Resolve(background); err == nil {
background = bg
}

if fg, err := Colors.Resolve(foreground); err == nil {
foreground = fg
}

inverted := foreground == color.Transparent && len(background) != 0

backgroundAnsi := getAnsiFromColorString(background, !inverted)
foregroundAnsi := getAnsiFromColorString(foreground, false)
background = Colors.ToAnsi(background, !inverted)
foreground = Colors.ToAnsi(foreground, false)

return backgroundAnsi, foregroundAnsi
return background, foreground
}

func trimAnsi(text string) string {
Expand Down

0 comments on commit 6a8cecb

Please sign in to comment.