diff --git a/src/ansi_color.go b/src/ansi_color.go index beabb8d5940c..c586fdf47464 100644 --- a/src/ansi_color.go +++ b/src/ansi_color.go @@ -47,6 +47,7 @@ type colorWriter interface { write(background, foreground, text string) string() string reset() + setColors(background, foreground string) setParentColors(background, foreground string) } @@ -55,7 +56,8 @@ type AnsiColor struct { builder strings.Builder ansi *ansiUtils terminalBackground string - Parent *Color + Colors *Color + ParentColors *Color } type Color struct { @@ -66,12 +68,23 @@ type Color struct { const ( // Transparent implies a transparent color Transparent = "transparent" - // Inherit take the previous segment's color + // Inherit takes the previous segment's color Inherit = "inherit" + // Background takes the current segment's background color + Background = "background" + // Foreground takes the current segment's foreground color + Foreground = "foreground" ) +func (a *AnsiColor) setColors(background, foreground string) { + a.Colors = &Color{ + Background: background, + Foreground: foreground, + } +} + func (a *AnsiColor) setParentColors(background, foreground string) { - a.Parent = &Color{ + a.ParentColors = &Color{ Background: background, Foreground: foreground, } @@ -134,16 +147,28 @@ func (a *AnsiColor) write(background, foreground, text string) { } getAnsiColors := func(background, foreground string) (string, string) { - if background == Inherit && a.Parent != nil { - background = a.Parent.Background + if background == Background { + background = a.Colors.Background + } + if background == Foreground { + background = a.Colors.Foreground + } + if foreground == Foreground { + foreground = a.Colors.Foreground + } + if foreground == Background { + foreground = a.Colors.Background + } + if background == Inherit && a.ParentColors != nil { + background = a.ParentColors.Background } - if background == Inherit && a.Parent == nil { + if background == Inherit && a.ParentColors == nil { background = Transparent } - if foreground == Inherit && a.Parent != nil { - foreground = a.Parent.Foreground + if foreground == Inherit && a.ParentColors != nil { + foreground = a.ParentColors.Foreground } - if foreground == Inherit && a.Parent == nil { + if foreground == Inherit && a.ParentColors == nil { foreground = Transparent } inverted := foreground == Transparent && len(background) != 0 diff --git a/src/ansi_color_test.go b/src/ansi_color_test.go index 12efb40972d4..05a77dac324e 100644 --- a/src/ansi_color_test.go +++ b/src/ansi_color_test.go @@ -147,6 +147,36 @@ func TestWriteANSIColors(t *testing.T) { Colors: &Color{Foreground: Transparent, Background: "#FF5733"}, TerminalBackground: "#212F3C", }, + { + Case: "Foreground for foreground override", + Input: "test", + Expected: "\x1b[47m\x1b[30mtest\x1b[0m", + Colors: &Color{Foreground: "black", Background: "white"}, + }, + { + Case: "Foreground for background override", + Input: "test", + Expected: "\x1b[47m\x1b[37mtest\x1b[0m", + Colors: &Color{Foreground: "black", Background: "white"}, + }, + { + Case: "Foreground for background vice versa override", + Input: "test", + Expected: "\x1b[40m\x1b[37mtest\x1b[0m", + Colors: &Color{Foreground: "black", Background: "white"}, + }, + { + Case: "Background for background override", + Input: "<,background>test", + Expected: "\x1b[47m\x1b[30mtest\x1b[0m", + Colors: &Color{Foreground: "black", Background: "white"}, + }, + { + Case: "Background for foreground override", + Input: "<,foreground>test", + Expected: "\x1b[40m\x1b[30mtest\x1b[0m", + Colors: &Color{Foreground: "black", Background: "white"}, + }, } for _, tc := range cases { @@ -154,7 +184,8 @@ func TestWriteANSIColors(t *testing.T) { ansi.init("pwsh") renderer := &AnsiColor{ ansi: ansi, - Parent: tc.Parent, + ParentColors: tc.Parent, + Colors: tc.Colors, terminalBackground: tc.TerminalBackground, } renderer.write(tc.Colors.Background, tc.Colors.Foreground, tc.Input) diff --git a/src/block.go b/src/block.go index 6f7d77f577f4..4a2d43a89fb2 100644 --- a/src/block.go +++ b/src/block.go @@ -38,6 +38,8 @@ type Block struct { ansi *ansiUtils activeSegment *Segment previousActiveSegment *Segment + activeBackground string + activeForeground string } func (b *Block) init(env environmentInfo, writer colorWriter, ansi *ansiUtils) { @@ -126,7 +128,7 @@ func (b *Block) getPowerlineColor(foreground bool) string { return b.previousActiveSegment.background() } if b.activeSegment.Style == Diamond && len(b.activeSegment.LeadingDiamond) == 0 { - return b.activeSegment.background() + return b.activeBackground } if !foreground && b.activeSegment.Style != Powerline { return Transparent @@ -138,6 +140,9 @@ func (b *Block) getPowerlineColor(foreground bool) string { } func (b *Block) renderSegmentText(text string) { + b.activeBackground = b.activeSegment.background() + b.activeForeground = b.activeSegment.foreground() + b.writer.setColors(b.activeBackground, b.activeForeground) switch b.activeSegment.Style { case Plain: b.renderPlainSegment(text) @@ -147,11 +152,11 @@ func (b *Block) renderSegmentText(text string) { b.renderPowerLineSegment(text) } b.previousActiveSegment = b.activeSegment - b.writer.setParentColors(b.activeSegment.background(), b.activeSegment.foreground()) + b.writer.setParentColors(b.activeBackground, b.activeForeground) } func (b *Block) renderPowerLineSegment(text string) { - b.writePowerLineSeparator(b.activeSegment.background(), b.getPowerlineColor(true), false) + b.writePowerLineSeparator(b.activeBackground, b.getPowerlineColor(true), false) b.renderText(text) } @@ -160,7 +165,7 @@ func (b *Block) renderPlainSegment(text string) { } func (b *Block) renderDiamondSegment(text string) { - background := b.activeSegment.background() + background := b.activeBackground if background == Inherit { background = b.previousActiveSegment.background() } @@ -170,12 +175,10 @@ func (b *Block) renderDiamondSegment(text string) { } func (b *Block) renderText(text string) { - bg := b.activeSegment.background() - fg := b.activeSegment.foreground() defaultValue := " " - b.writer.write(bg, fg, b.activeSegment.getValue(Prefix, defaultValue)) - b.writer.write(bg, fg, text) - b.writer.write(bg, fg, b.activeSegment.getValue(Postfix, defaultValue)) + b.writer.write(b.activeBackground, b.activeForeground, b.activeSegment.getValue(Prefix, defaultValue)) + b.writer.write(b.activeBackground, b.activeForeground, text) + b.writer.write(b.activeBackground, b.activeForeground, b.activeSegment.getValue(Postfix, defaultValue)) } func (b *Block) debug() (int, []*SegmentTiming) { @@ -205,7 +208,7 @@ func (b *Block) debug() (int, []*SegmentTiming) { b.activeSegment = segment b.renderSegmentText(segmentTiming.stringValue) if b.activeSegment.Style == Powerline { - b.writePowerLineSeparator(Transparent, b.activeSegment.background(), true) + b.writePowerLineSeparator(Transparent, b.activeBackground, true) } segmentTiming.stringValue = b.writer.string() b.writer.reset()