Repository: JanDeDobbeleer/oh-my-posh
Pull request #1180 (2021-11-06 12:18:53)

feat(color): allow override from parent
### Prerequisites

- [x] I have read and understood the `CONTRIBUTING` guide
- [x] The commit message follows the [conventional commits][cc] guidelines
- [x] Tests for the changes have been added (for bug fixes/features)
- [ ] Docs have been added / updated (for bug fixes/features)

### Description

BREAKING CHANGE: this removes the inherit keyword used in color
overrides. Migration from inherit to parentBackground or
parentForeground is needed to stay compatible.

<!---

Tips:

If you're not comfortable with working with Git, we're working a guide (https://ohmyposh.dev/docs/contributing_git) to help you out.
Oh My Posh advises GitKraken (https://www.gitkraken.com/invite/nQmDPR9D) as your preferred cross platform Git GUI power tool.

-->

[cc]: https://www.conventionalcommits.org/en/v1.0.0/#summary



Patch:
diff --git a/src/block.go b/src/block.go
index dcbabc52..aa6b726d 100644
--- a/src/block.go
+++ b/src/block.go
@@ -166,13 +166,9 @@ func (b *Block) renderPlainSegment(text string) {
 }
 
 func (b *Block) renderDiamondSegment(text string) {
-	background := b.activeBackground
-	if background == Inherit {
-		background = b.previousActiveSegment.background()
-	}
-	b.writer.write(Transparent, background, b.activeSegment.LeadingDiamond)
+	b.writer.write(Transparent, b.activeBackground, b.activeSegment.LeadingDiamond)
 	b.renderText(text)
-	b.writer.write(Transparent, background, b.activeSegment.TrailingDiamond)
+	b.writer.write(Transparent, b.activeBackground, b.activeSegment.TrailingDiamond)
 }
 
 func (b *Block) renderText(text string) {
diff --git a/src/writer_ansi.go b/src/writer_ansi.go
index f4b4f69a..caf8706c 100644
--- a/src/writer_ansi.go
+++ b/src/writer_ansi.go
@@ -73,8 +73,10 @@ type Color struct {
 const (
 	// Transparent implies a transparent color
 	Transparent = "transparent"
-	// Inherit takes the previous segment's color
-	Inherit = "inherit"
+	// ParentBackground takes the previous segment's background color
+	ParentBackground = "parentBackground"
+	// ParentForeground takes the previous segment's color
+	ParentForeground = "parentForeground"
 	// Background takes the current segment's background color
 	Background = "background"
 	// Foreground takes the current segment's foreground color
@@ -156,30 +158,22 @@ func (a *AnsiWriter) write(background, foreground, text string) {
 	}
 
 	getAnsiColors := func(background, foreground string) (string, string) {
-		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.ParentColors == nil {
-			background = Transparent
-		}
-		if foreground == Inherit && a.ParentColors != nil {
-			foreground = a.ParentColors.Foreground
-		}
-		if foreground == Inherit && a.ParentColors == nil {
-			foreground = Transparent
+		getColorString := func(color string) string {
+			if color == Background {
+				color = a.Colors.Background
+			} else if color == Foreground {
+				color = a.Colors.Foreground
+			} else if color == ParentBackground && a.ParentColors != nil {
+				color = a.ParentColors.Background
+			} else if color == ParentForeground && a.ParentColors != nil {
+				color = a.ParentColors.Foreground
+			} else if (color == ParentForeground || color == ParentBackground) && a.ParentColors == nil {
+				color = Transparent
+			}
+			return color
 		}
+		background = getColorString(background)
+		foreground = getColorString(foreground)
 		inverted := foreground == Transparent && len(background) != 0
 		background = a.getAnsiFromColorString(background, !inverted)
 		foreground = a.getAnsiFromColorString(foreground, false)
@@ -187,7 +181,6 @@ func (a *AnsiWriter) write(background, foreground, text string) {
 	}
 
 	bgAnsi, fgAnsi := getAnsiColors(background, foreground)
-
 	text = a.ansi.escapeText(text)
 	text = a.ansi.formatText(text)
 	text = a.ansi.generateHyperlink(text)
diff --git a/themes/schema.json b/themes/schema.json
index 5b6ef6ff..1b580aa5 100644
--- a/themes/schema.json
+++ b/themes/schema.json
@@ -7,7 +7,7 @@
   "definitions": {
     "color": {
       "type": "string",
-      "pattern": "^(#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})|black|red|green|yellow|blue|magenta|cyan|white|default|darkGray|lightRed|lightGreen|lightYellow|lightBlue|lightMagenta|lightCyan|lightWhite|transparent|inherit)$",
+      "pattern": "^(#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})|black|red|green|yellow|blue|magenta|cyan|white|default|darkGray|lightRed|lightGreen|lightYellow|lightBlue|lightMagenta|lightCyan|lightWhite|transparent|parentBackground|parentForeground|background|foreground)$",
       "title": "Color string",
       "description": "https://ohmyposh.dev/docs/configure#colors",
       "format": "color"


Test patch:
diff --git a/src/writer_ansi_test.go b/src/writer_ansi_test.go
index 7d6bbcd4..e0ad7403 100644
--- a/src/writer_ansi_test.go
+++ b/src/writer_ansi_test.go
@@ -48,62 +48,69 @@ func TestWriteANSIColors(t *testing.T) {
 			Case:     "Inherit foreground",
 			Input:    "test",
 			Expected: "\x1b[47m\x1b[33mtest\x1b[0m",
-			Colors:   &Color{Foreground: Inherit, Background: "white"},
+			Colors:   &Color{Foreground: ParentForeground, Background: "white"},
 			Parent:   &Color{Foreground: "yellow", Background: "white"},
 		},
 		{
 			Case:     "Inherit background",
 			Input:    "test",
 			Expected: "\x1b[41m\x1b[30mtest\x1b[0m",
-			Colors:   &Color{Foreground: "black", Background: Inherit},
+			Colors:   &Color{Foreground: "black", Background: ParentBackground},
 			Parent:   &Color{Foreground: "yellow", Background: "red"},
 		},
 		{
 			Case:     "No parent",
 			Input:    "test",
 			Expected: "\x1b[30mtest\x1b[0m",
-			Colors:   &Color{Foreground: "black", Background: Inherit},
+			Colors:   &Color{Foreground: "black", Background: ParentBackground},
 		},
 		{
 			Case:     "Inherit override foreground",
-			Input:    "hello <inherit>world</>",
+			Input:    "hello <parentForeground>world</>",
 			Expected: "\x1b[47m\x1b[30mhello \x1b[0m\x1b[47m\x1b[33mworld\x1b[0m",
 			Colors:   &Color{Foreground: "black", Background: "white"},
 			Parent:   &Color{Foreground: "yellow", Background: "red"},
 		},
 		{
 			Case:     "Inherit override background",
-			Input:    "hello <black,inherit>world</>",
+			Input:    "hello <black,parentBackground>world</>",
 			Expected: "\x1b[47m\x1b[30mhello \x1b[0m\x1b[41m\x1b[30mworld\x1b[0m",
 			Colors:   &Color{Foreground: "black", Background: "white"},
 			Parent:   &Color{Foreground: "yellow", Background: "red"},
 		},
 		{
 			Case:     "Inherit override background, no foreground specified",
-			Input:    "hello <,inherit>world</>",
+			Input:    "hello <,parentBackground>world</>",
 			Expected: "\x1b[47m\x1b[30mhello \x1b[0m\x1b[41m\x1b[30mworld\x1b[0m",
 			Colors:   &Color{Foreground: "black", Background: "white"},
 			Parent:   &Color{Foreground: "yellow", Background: "red"},
 		},
-		{
-			Case:     "Inherit override both",
-			Input:    "hello <inherit,inherit>world</>",
-			Expected: "\x1b[47m\x1b[30mhello \x1b[0m\x1b[41m\x1b[33mworld\x1b[0m",
-			Colors:   &Color{Foreground: "black", Background: "white"},
-			Parent:   &Color{Foreground: "yellow", Background: "red"},
-		},
 		{
 			Case:     "Inherit no parent foreground",
-			Input:    "hello <inherit>world</>",
+			Input:    "hello <parentForeground>world</>",
 			Expected: "\x1b[47m\x1b[30mhello \x1b[0m\x1b[47;49m\x1b[7mworld\x1b[0m",
 			Colors:   &Color{Foreground: "black", Background: "white"},
 		},
 		{
 			Case:     "Inherit no parent background",
-			Input:    "hello <,inherit>world</>",
+			Input:    "hello <,parentBackground>world</>",
 			Expected: "\x1b[47m\x1b[30mhello \x1b[0m\x1b[30mworld\x1b[0m",
 			Colors:   &Color{Foreground: "black", Background: "white"},
 		},
+		{
+			Case:     "Inherit override both",
+			Input:    "hello <parentForeground,parentBackground>world</>",
+			Expected: "\x1b[47m\x1b[30mhello \x1b[0m\x1b[41m\x1b[33mworld\x1b[0m",
+			Colors:   &Color{Foreground: "black", Background: "white"},
+			Parent:   &Color{Foreground: "yellow", Background: "red"},
+		},
+		{
+			Case:     "Inherit override both inverted",
+			Input:    "hello <parentBackground,parentForeground>world</>",
+			Expected: "\x1b[47m\x1b[30mhello \x1b[0m\x1b[43m\x1b[31mworld\x1b[0m",
+			Colors:   &Color{Foreground: "black", Background: "white"},
+			Parent:   &Color{Foreground: "yellow", Background: "red"},
+		},
 		{
 			Case:     "Inline override",
 			Input:    "hello, <red>world</>, rabbit",