feat(windows): accent color

This commit is contained in:
Jan De Dobbeleer 2022-05-22 09:11:16 +02:00 committed by Jan De Dobbeleer
parent 37dd466adf
commit a51716d5ac
9 changed files with 92 additions and 18 deletions

View file

@ -6,8 +6,10 @@ import (
"github.com/gookit/color" "github.com/gookit/color"
) )
func MakeColors(palette Palette, cacheEnabled bool) (colors AnsiColors) { func MakeColors(palette Palette, cacheEnabled bool, accentColor string) (colors AnsiColors) {
colors = &DefaultColors{} defaultColors := &DefaultColors{}
defaultColors.SetAccentColor(accentColor)
colors = defaultColors
if palette != nil { if palette != nil {
colors = &PaletteColors{ansiColors: colors, palette: palette} colors = &PaletteColors{ansiColors: colors, palette: palette}
} }
@ -18,7 +20,9 @@ func MakeColors(palette Palette, cacheEnabled bool) (colors AnsiColors) {
} }
// DefaultColors is the default AnsiColors implementation. // DefaultColors is the default AnsiColors implementation.
type DefaultColors struct{} type DefaultColors struct {
accent *Color
}
var ( var (
// Map for color names and their respective foreground [0] or background [1] color codes // Map for color names and their respective foreground [0] or background [1] color codes
@ -48,13 +52,22 @@ const (
backgroundIndex = 1 backgroundIndex = 1
) )
func (*DefaultColors) AnsiColorFromString(colorString string, isBackground bool) AnsiColor { func (d *DefaultColors) AnsiColorFromString(colorString string, isBackground bool) AnsiColor {
if len(colorString) == 0 { if len(colorString) == 0 {
return emptyAnsiColor return emptyAnsiColor
} }
if colorString == Transparent { if colorString == Transparent {
return transparentAnsiColor return transparentAnsiColor
} }
if colorString == Accent {
if d.accent == nil {
return emptyAnsiColor
}
if isBackground {
return AnsiColor(d.accent.Background)
}
return AnsiColor(d.accent.Foreground)
}
colorFromName, err := getAnsiColorFromName(colorString, isBackground) colorFromName, err := getAnsiColorFromName(colorString, isBackground)
if err == nil { if err == nil {
return colorFromName return colorFromName

View file

@ -30,18 +30,18 @@ func TestGetAnsiFromColorString(t *testing.T) {
} }
func TestMakeColors(t *testing.T) { func TestMakeColors(t *testing.T) {
colors := MakeColors(nil, false) colors := MakeColors(nil, false, "")
assert.IsType(t, &DefaultColors{}, colors) assert.IsType(t, &DefaultColors{}, colors)
colors = MakeColors(nil, true) colors = MakeColors(nil, true, "")
assert.IsType(t, &CachedColors{}, colors) assert.IsType(t, &CachedColors{}, colors)
assert.IsType(t, &DefaultColors{}, colors.(*CachedColors).ansiColors) assert.IsType(t, &DefaultColors{}, colors.(*CachedColors).ansiColors)
colors = MakeColors(testPalette, false) colors = MakeColors(testPalette, false, "")
assert.IsType(t, &PaletteColors{}, colors) assert.IsType(t, &PaletteColors{}, colors)
assert.IsType(t, &DefaultColors{}, colors.(*PaletteColors).ansiColors) assert.IsType(t, &DefaultColors{}, colors.(*PaletteColors).ansiColors)
colors = MakeColors(testPalette, true) colors = MakeColors(testPalette, true, "")
assert.IsType(t, &CachedColors{}, colors) assert.IsType(t, &CachedColors{}, colors)
assert.IsType(t, &PaletteColors{}, colors.(*CachedColors).ansiColors) assert.IsType(t, &PaletteColors{}, colors.(*CachedColors).ansiColors)
assert.IsType(t, &DefaultColors{}, colors.(*CachedColors).ansiColors.(*PaletteColors).ansiColors) assert.IsType(t, &DefaultColors{}, colors.(*CachedColors).ansiColors.(*PaletteColors).ansiColors)

13
src/color/colors_unix.go Normal file
View file

@ -0,0 +1,13 @@
//go:build !windows
package color
func (d *DefaultColors) SetAccentColor(defaultColor string) {
if len(defaultColor) == 0 {
return
}
d.accent = &Color{
Foreground: string(d.AnsiColorFromString(defaultColor, false)),
Background: string(d.AnsiColorFromString(defaultColor, true)),
}
}

View file

@ -0,0 +1,38 @@
package color
import (
"syscall"
"unsafe"
"github.com/gookit/color"
"golang.org/x/sys/windows"
)
var (
dwmapi = syscall.NewLazyDLL("dwmapi.dll")
procDwmGetColorizationColor = dwmapi.NewProc("DwmGetColorizationColor")
)
func (d *DefaultColors) SetAccentColor(defaultColor string) {
var accentColor uint32
var pfOpaqueBlend bool
_, _, e := procDwmGetColorizationColor.Call(
uintptr(unsafe.Pointer(&accentColor)),
uintptr(unsafe.Pointer(&pfOpaqueBlend)))
if e != windows.ERROR_SUCCESS {
d.accent = &Color{
Foreground: string(d.AnsiColorFromString(defaultColor, false)),
Background: string(d.AnsiColorFromString(defaultColor, true)),
}
return
}
r := byte(accentColor >> 16)
g := byte(accentColor >> 8)
b := byte(accentColor)
foreground := color.RGB(r, g, b, false)
background := color.RGB(r, g, b, true)
d.accent = &Color{
Foreground: foreground.String(),
Background: background.String(),
}
}

View file

@ -73,6 +73,8 @@ func (c AnsiColor) ToForeground() AnsiColor {
const ( const (
// Transparent implies a transparent color // Transparent implies a transparent color
Transparent = "transparent" Transparent = "transparent"
// Accent is the OS accent color
Accent = "accent"
// ParentBackground takes the previous segment's background color // ParentBackground takes the previous segment's background color
ParentBackground = "parentBackground" ParentBackground = "parentBackground"
// ParentForeground takes the previous segment's color // ParentForeground takes the previous segment's color

View file

@ -35,6 +35,7 @@ type Config struct {
OSC99 bool `json:"osc99,omitempty"` OSC99 bool `json:"osc99,omitempty"`
ConsoleTitleTemplate string `json:"console_title_template,omitempty"` ConsoleTitleTemplate string `json:"console_title_template,omitempty"`
TerminalBackground string `json:"terminal_background,omitempty"` TerminalBackground string `json:"terminal_background,omitempty"`
AccentColor string `json:"accent_color,omitempty"`
Blocks []*Block `json:"blocks,omitempty"` Blocks []*Block `json:"blocks,omitempty"`
Tooltips []*Segment `json:"tooltips,omitempty"` Tooltips []*Segment `json:"tooltips,omitempty"`
TransientPrompt *Segment `json:"transient_prompt,omitempty"` TransientPrompt *Segment `json:"transient_prompt,omitempty"`
@ -56,7 +57,7 @@ type Config struct {
// environment and configuration. // environment and configuration.
func (cfg *Config) MakeColors(env environment.Environment) color.AnsiColors { func (cfg *Config) MakeColors(env environment.Environment) color.AnsiColors {
cacheDisabled := env.Getenv("OMP_CACHE_DISABLED") == "1" cacheDisabled := env.Getenv("OMP_CACHE_DISABLED") == "1"
return color.MakeColors(cfg.Palette, !cacheDisabled) return color.MakeColors(cfg.Palette, !cacheDisabled, cfg.AccentColor)
} }
func (cfg *Config) print(message string) { func (cfg *Config) print(message string) {

View file

@ -17,7 +17,7 @@
}, },
"color_string": { "color_string": {
"type": "string", "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|parentBackground|parentForeground|background|foreground)$", "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|accent)$",
"title": "Color string", "title": "Color string",
"description": "https://ohmyposh.dev/docs/configuration/colors", "description": "https://ohmyposh.dev/docs/configuration/colors",
"format": "color" "format": "color"
@ -2552,6 +2552,10 @@
"$ref": "#/definitions/color" "$ref": "#/definitions/color"
} }
} }
},
"accent_color": {
"title": "Accent color",
"$ref": "#/definitions/color"
} }
} }
} }

View file

@ -10,20 +10,20 @@ Oh My Posh supports multiple different color references, being:
- Typical [hex colors][hexcolors] (for example `#CB4B16`). - Typical [hex colors][hexcolors] (for example `#CB4B16`).
- 16 [ANSI color names][ansicolors]. - 16 [ANSI color names][ansicolors].
- The `transparent` keyword which can be used to create either a transparent foreground override These include 8 basic ANSI colors and `default`
or transparent background color using the segment's foreground property.
- The `foreground` keyword which can be used to reference the current segment's foreground color.
- The `background` keyword which can be used to reference the current segment's background color.
- The `parentForeground` keyword which can be used to inherit the previous active segment's foreground color.
- The `parentBackground` keyword which can be used to inherit the previous active segment's background color.
These include 8 basic ANSI colors and `default`:
`black` `red` `green` `yellow` `blue` `magenta` `cyan` `white` `default` `black` `red` `green` `yellow` `blue` `magenta` `cyan` `white` `default`
as well as 8 extended ANSI colors: as well as 8 extended ANSI colors:
`darkGray` `lightRed` `lightGreen` `lightYellow` `lightBlue` `lightMagenta` `lightCyan` `lightWhite` `darkGray` `lightRed` `lightGreen` `lightYellow` `lightBlue` `lightMagenta` `lightCyan` `lightWhite`
- The `transparent` keyword which can be used to create either a transparent foreground override
or transparent background color using the segment's foreground property.
- The `foreground` keyword which can be used to reference the current segment's foreground color.
- The `background` keyword which can be used to reference the current segment's background color.
- The `parentForeground` keyword which can be used to inherit the previous active segment's foreground color.
- The `parentBackground` keyword which can be used to inherit the previous active segment's background color.
- The `accent` keyword which references the OS accent color (Windows only).
## Color templates ## Color templates

View file

@ -69,8 +69,11 @@ For example, the following is a valid `--config` flag:
- osc99: `boolean` - when true adds support for OSC9;9; (notify terminal of current working directory) - osc99: `boolean` - when true adds support for OSC9;9; (notify terminal of current working directory)
- terminal_background: `string` [color][colors] - terminal background color, set to your terminal's background color when - terminal_background: `string` [color][colors] - terminal background color, set to your terminal's background color when
you notice black elements in Windows Terminal or the Visual Studio Code integrated terminal you notice black elements in Windows Terminal or the Visual Studio Code integrated terminal
- accent_color: `string` [color][colors] - accent color, used as a fallback when the `accent` [color][accent] is not supported
[releases]: https://github.com/JanDeDobbeleer/oh-my-posh/releases/latest [releases]: https://github.com/JanDeDobbeleer/oh-my-posh/releases/latest
[font]: /docs/configuration/fonts [font]: /docs/configuration/fonts
[schema]: https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/themes/schema.json [schema]: https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/themes/schema.json
[themes]: https://github.com/JanDeDobbeleer/oh-my-posh/tree/main/themes [themes]: https://github.com/JanDeDobbeleer/oh-my-posh/tree/main/themes
[colors]: /docs/configuration/colors
[accent]: /docs/configuration/colors#standard-colors