feat: add inline background color syntax

This commit is contained in:
Spencer Hedrick 2020-11-21 02:27:29 -08:00 committed by Jan De Dobbeleer
parent c0fd060c89
commit 56778276b2
3 changed files with 77 additions and 8 deletions

View file

@ -200,8 +200,8 @@ segment's configuration will not render it when in that location. The engine wil
#### Colors
You have the ability to override the foreground color for text in any property that accepts it. The syntax is custom but
should be rather straighforward: `<#ffffff>this is white</> <#FF479C>but this is pink</>`. Anything between the color start
You have the ability to override the foreground and/or background color for text in any property that accepts it. The syntax is custom but
should be rather straighforward: `<#ffffff,#000000>this is white with black background</> <#FF479C>but this is pink</>`. Anything between the color start
`<#FF479C>` and end `</>` will be colored accordingly.
For example, if you want `prefix` to print a colored bracket which isn't the same as the segment's `foreground`, you can
@ -211,6 +211,18 @@ do so like this:
"prefix": "<#CB4B16>┏[</>",
```
If you also wanted to change the background color in the previous command, you would do so like this:
```json
"prefix": "<#CB4B16,#FFFFFF>┏[</>",
```
To change *only* the background color, just omit the first color from the above string:
```json
"prefix": "<,#FFFFFF>┏[</>",
```
Oh my Posh mainly supports three different color types being
* Typical [hex colors][hexcolors] (for example `#CB4B16`).

View file

@ -146,19 +146,32 @@ func (r *Renderer) writeAndRemoveText(background, foreground, text, textToRemove
}
func (r *Renderer) write(background, foreground, text string) {
// first we match for any potentially valid color enclosed in <>
rex := regexp.MustCompile(`<([#A-Za-z0-9]+)>(.*?)<\/>`)
// first we match for any potentially valid colors enclosed in <>
rex := regexp.MustCompile(`<([#A-Za-z0-9]+)?(?:,([#A-Za-z0-9]+))?>(.*?)<\/>`)
match := rex.FindAllStringSubmatch(text, -1)
for i := range match {
extractedColor := match[i][1]
if col := r.getAnsiFromColorString(extractedColor, false); col == "" && extractedColor != Transparent {
extractedForegroundColor := match[i][1]
extractedBackgroundColor := match[i][2]
if col := r.getAnsiFromColorString(extractedForegroundColor, false); col == "" && extractedForegroundColor != Transparent && len(extractedBackgroundColor) == 0 {
continue // we skip invalid colors
}
if col := r.getAnsiFromColorString(extractedBackgroundColor, false); col == "" && extractedBackgroundColor != Transparent && len(extractedForegroundColor) == 0 {
continue // we skip invalid colors
}
// reuse function colors if only one was specified
if len(extractedBackgroundColor) == 0 {
extractedBackgroundColor = background
}
if len(extractedForegroundColor) == 0 {
extractedForegroundColor = foreground
}
escapedTextSegment := match[i][0]
innerText := match[i][2]
innerText := match[i][3]
textBeforeColorOverride := strings.Split(text, escapedTextSegment)[0]
text = r.writeAndRemoveText(background, foreground, textBeforeColorOverride, textBeforeColorOverride, text)
text = r.writeAndRemoveText(background, extractedColor, innerText, escapedTextSegment, text)
text = r.writeAndRemoveText(extractedBackgroundColor, extractedForegroundColor, innerText, escapedTextSegment, text)
}
// color the remaining part of text with background and foreground
r.writeColoredText(background, foreground, text)

View file

@ -41,6 +41,50 @@ func TestWriteColorOverride(t *testing.T) {
assert.NotContains(t, renderer.string(), "<#ff5733>")
}
func TestWriteColorOverrideBackground(t *testing.T) {
renderer := &Renderer{
Buffer: new(bytes.Buffer),
}
text := "This is white, <,#000000>this is black</>, white again"
renderer.init("pwsh")
renderer.write("#193549", "#ff5733", text)
assert.NotContains(t, renderer.string(), "000000")
}
func TestWriteColorOverrideBackground16(t *testing.T) {
renderer := &Renderer{
Buffer: new(bytes.Buffer),
}
text := "This is default <,white> this background is changed</> default again"
renderer.init("pwsh")
renderer.write("#193549", "#ff5733", text)
assert.NotContains(t, renderer.string(), "white")
assert.NotContains(t, renderer.string(), "</>")
assert.NotContains(t, renderer.string(), "<,")
}
func TestWriteColorOverrideBoth(t *testing.T) {
renderer := &Renderer{
Buffer: new(bytes.Buffer),
}
text := "This is white, <#000000,#ffffff>this is black</>, white again"
renderer.init("pwsh")
renderer.write("#193549", "#ff5733", text)
assert.NotContains(t, renderer.string(), "ffffff")
assert.NotContains(t, renderer.string(), "000000")
}
func TestWriteColorOverrideBoth16(t *testing.T) {
renderer := &Renderer{
Buffer: new(bytes.Buffer),
}
text := "This is white, <black,white>this is black</>, white again"
renderer.init("pwsh")
renderer.write("#193549", "#ff5733", text)
assert.NotContains(t, renderer.string(), "<black,white>")
assert.NotContains(t, renderer.string(), "</>")
}
func TestWriteColorTransparent(t *testing.T) {
renderer := &Renderer{
Buffer: new(bytes.Buffer),