diff --git a/.vscode/launch.json b/.vscode/launch.json index 5ec2204755be..bab7e5915725 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -12,7 +12,8 @@ "print", "primary", "--shell=pwsh", - "--terminal-width=200" + "--terminal-width=200", + "--config=/Users/jan/.test.omp.json" ] }, { diff --git a/src/ansi/ansi_writer.go b/src/ansi/ansi_writer.go index e389a4cfbc50..bfe4d29fa273 100644 --- a/src/ansi/ansi_writer.go +++ b/src/ansi/ansi_writer.go @@ -54,7 +54,7 @@ const ( // Foreground takes the current segment's foreground color Foreground = "foreground" - anchorRegex = `^(?P<(?P[^,>]+)?,?(?P[^>]+)?>)` + AnchorRegex = `^(?P<(?P[^,>]+)?,?(?P[^>]+)?>)` colorise = "\x1b[%sm" transparent = "\x1b[0m\x1b[%s;49m\x1b[7m" transparentEnd = "\x1b[27m" @@ -288,7 +288,7 @@ func (w *Writer) Write(background, foreground, text string) { w.foreground = w.AnsiColors.ToColor("white", false, w.TrueColor) } // validate if we start with a color override - match := regex.FindNamedRegexMatch(anchorRegex, text) + match := regex.FindNamedRegexMatch(AnchorRegex, text) if len(match) != 0 { colorOverride := true for _, style := range knownStyles { @@ -320,7 +320,7 @@ func (w *Writer) Write(background, foreground, text string) { // color/end overrides first text = string(w.runes[i:]) - match = regex.FindNamedRegexMatch(anchorRegex, text) + match = regex.FindNamedRegexMatch(AnchorRegex, text) if len(match) > 0 { i = w.writeColorOverrides(match, background, i) continue diff --git a/src/engine/block.go b/src/engine/block.go index bc341b756485..ddf96f54b137 100644 --- a/src/engine/block.go +++ b/src/engine/block.go @@ -1,11 +1,13 @@ package engine import ( + "strings" "sync" "time" "github.com/jandedobbeleer/oh-my-posh/src/ansi" "github.com/jandedobbeleer/oh-my-posh/src/platform" + "github.com/jandedobbeleer/oh-my-posh/src/regex" "github.com/jandedobbeleer/oh-my-posh/src/shell" ) @@ -165,7 +167,11 @@ func (b *Block) writeSeparator(final bool) { b.writer.Write(ansi.Transparent, ansi.Background, b.activeSegment.TrailingDiamond) return } + isPreviousDiamond := b.previousActiveSegment != nil && b.previousActiveSegment.style() == Diamond + if isPreviousDiamond { + b.adjustTrailingDiamondColorOverrides() + } if isPreviousDiamond && isCurrentDiamond && len(b.activeSegment.LeadingDiamond) == 0 { b.writer.Write(ansi.Background, ansi.ParentBackground, b.previousActiveSegment.TrailingDiamond) return @@ -201,6 +207,50 @@ func (b *Block) writeSeparator(final bool) { b.writer.Write(bgColor, b.getPowerlineColor(), symbol) } +func (b *Block) adjustTrailingDiamondColorOverrides() { + // as we now already adjusted the activeSegment, we need to change the value + // of background and foreground to parentBackground and parentForeground + // this will still break when using parentBackground and parentForeground as keywords + // in a trailing diamond, but let's fix that when it happens as it requires either a rewrite + // of the logic for diamonds or storing grandparents as well like one happy family. + if b.previousActiveSegment == nil || len(b.previousActiveSegment.TrailingDiamond) == 0 { + return + } + + if !strings.Contains(b.previousActiveSegment.TrailingDiamond, ansi.Background) && !strings.Contains(b.previousActiveSegment.TrailingDiamond, ansi.Foreground) { + return + } + + match := regex.FindNamedRegexMatch(ansi.AnchorRegex, b.previousActiveSegment.TrailingDiamond) + if len(match) == 0 { + return + } + + adjustOverride := func(anchor, override string) { + newOverride := override + switch override { + case ansi.Foreground: + newOverride = ansi.ParentForeground + case ansi.Background: + newOverride = ansi.ParentBackground + } + + if override == newOverride { + return + } + + newAnchor := strings.Replace(match[ansi.ANCHOR], override, newOverride, 1) + b.previousActiveSegment.TrailingDiamond = strings.Replace(b.previousActiveSegment.TrailingDiamond, anchor, newAnchor, 1) + } + + if len(match[ansi.BG]) > 0 { + adjustOverride(match[ansi.ANCHOR], match[ansi.BG]) + } + if len(match[ansi.FG]) > 0 { + adjustOverride(match[ansi.ANCHOR], match[ansi.FG]) + } +} + func (b *Block) getPowerlineColor() string { if b.previousActiveSegment == nil { return ansi.Transparent