mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-12-28 20:39:40 -08:00
feat: enable/disable true color per terminal
This commit is contained in:
parent
481f096878
commit
8c5c836f22
|
@ -80,6 +80,7 @@ type Writer struct {
|
||||||
ParentColors []*Colors
|
ParentColors []*Colors
|
||||||
AnsiColors ColorString
|
AnsiColors ColorString
|
||||||
Plain bool
|
Plain bool
|
||||||
|
TrueColor bool
|
||||||
|
|
||||||
builder strings.Builder
|
builder strings.Builder
|
||||||
length int
|
length int
|
||||||
|
@ -283,7 +284,7 @@ func (w *Writer) Write(background, foreground, text string) {
|
||||||
w.background, w.foreground = w.asAnsiColors(background, foreground)
|
w.background, w.foreground = w.asAnsiColors(background, foreground)
|
||||||
// default to white foreground
|
// default to white foreground
|
||||||
if w.foreground.IsEmpty() {
|
if w.foreground.IsEmpty() {
|
||||||
w.foreground = w.AnsiColors.ToColor("white", false)
|
w.foreground = w.AnsiColors.ToColor("white", false, w.TrueColor)
|
||||||
}
|
}
|
||||||
// validate if we start with a color override
|
// validate if we start with a color override
|
||||||
match := regex.FindNamedRegexMatch(anchorRegex, text)
|
match := regex.FindNamedRegexMatch(anchorRegex, text)
|
||||||
|
@ -365,7 +366,7 @@ func (w *Writer) writeEscapedAnsiString(text string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Writer) getAnsiFromColorString(colorString string, isBackground bool) Color {
|
func (w *Writer) getAnsiFromColorString(colorString string, isBackground bool) Color {
|
||||||
return w.AnsiColors.ToColor(colorString, isBackground)
|
return w.AnsiColors.ToColor(colorString, isBackground, w.TrueColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Writer) writeSegmentColors() {
|
func (w *Writer) writeSegmentColors() {
|
||||||
|
|
|
@ -203,6 +203,7 @@ func TestWriteANSIColors(t *testing.T) {
|
||||||
Colors: tc.Colors,
|
Colors: tc.Colors,
|
||||||
TerminalBackground: tc.TerminalBackground,
|
TerminalBackground: tc.TerminalBackground,
|
||||||
AnsiColors: &DefaultColors{},
|
AnsiColors: &DefaultColors{},
|
||||||
|
TrueColor: true,
|
||||||
}
|
}
|
||||||
renderer.Init(shell.GENERIC)
|
renderer.Init(shell.GENERIC)
|
||||||
renderer.Write(tc.Colors.Background, tc.Colors.Foreground, tc.Input)
|
renderer.Write(tc.Colors.Background, tc.Colors.Foreground, tc.Input)
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
// This can include a valid hex color in the format `#FFFFFF`,
|
// This can include a valid hex color in the format `#FFFFFF`,
|
||||||
// but also a name of one of the first 16 ANSI colors like `lightBlue`.
|
// but also a name of one of the first 16 ANSI colors like `lightBlue`.
|
||||||
type ColorString interface {
|
type ColorString interface {
|
||||||
ToColor(colorString string, isBackground bool) Color
|
ToColor(colorString string, isBackground bool, trueColor bool) Color
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color is an ANSI color code ready to be printed to the console.
|
// Color is an ANSI color code ready to be printed to the console.
|
||||||
|
@ -98,7 +98,7 @@ const (
|
||||||
backgroundIndex = 1
|
backgroundIndex = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
func (d *DefaultColors) ToColor(colorString string, isBackground bool) Color {
|
func (d *DefaultColors) ToColor(colorString string, isBackground, trueColor bool) Color {
|
||||||
if len(colorString) == 0 {
|
if len(colorString) == 0 {
|
||||||
return emptyColor
|
return emptyColor
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,10 @@ func (d *DefaultColors) ToColor(colorString string, isBackground bool) Color {
|
||||||
}
|
}
|
||||||
style := color.HEX(colorString, isBackground)
|
style := color.HEX(colorString, isBackground)
|
||||||
if !style.IsEmpty() {
|
if !style.IsEmpty() {
|
||||||
return Color(style.String())
|
if trueColor {
|
||||||
|
return Color(style.String())
|
||||||
|
}
|
||||||
|
return Color(style.C256().String())
|
||||||
}
|
}
|
||||||
if colorInt, err := strconv.ParseInt(colorString, 10, 8); err == nil {
|
if colorInt, err := strconv.ParseInt(colorString, 10, 8); err == nil {
|
||||||
c := color.C256(uint8(colorInt), isBackground)
|
c := color.C256(uint8(colorInt), isBackground)
|
||||||
|
@ -161,12 +164,12 @@ type PaletteColors struct {
|
||||||
palette Palette
|
palette Palette
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PaletteColors) ToColor(colorString string, isBackground bool) Color {
|
func (p *PaletteColors) ToColor(colorString string, isBackground, trueColor bool) Color {
|
||||||
paletteColor, err := p.palette.ResolveColor(colorString)
|
paletteColor, err := p.palette.ResolveColor(colorString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return emptyColor
|
return emptyColor
|
||||||
}
|
}
|
||||||
ansiColor := p.ansiColors.ToColor(paletteColor, isBackground)
|
ansiColor := p.ansiColors.ToColor(paletteColor, isBackground, trueColor)
|
||||||
return ansiColor
|
return ansiColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +186,7 @@ type cachedColorKey struct {
|
||||||
isBackground bool
|
isBackground bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CachedColors) ToColor(colorString string, isBackground bool) Color {
|
func (c *CachedColors) ToColor(colorString string, isBackground, trueColor bool) Color {
|
||||||
if c.colorCache == nil {
|
if c.colorCache == nil {
|
||||||
c.colorCache = make(map[cachedColorKey]Color)
|
c.colorCache = make(map[cachedColorKey]Color)
|
||||||
}
|
}
|
||||||
|
@ -191,7 +194,7 @@ func (c *CachedColors) ToColor(colorString string, isBackground bool) Color {
|
||||||
if ansiColor, hit := c.colorCache[key]; hit {
|
if ansiColor, hit := c.colorCache[key]; hit {
|
||||||
return ansiColor
|
return ansiColor
|
||||||
}
|
}
|
||||||
ansiColor := c.ansiColors.ToColor(colorString, isBackground)
|
ansiColor := c.ansiColors.ToColor(colorString, isBackground, trueColor)
|
||||||
c.colorCache[key] = ansiColor
|
c.colorCache[key] = ansiColor
|
||||||
return ansiColor
|
return ansiColor
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package ansi
|
package ansi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/alecthomas/assert"
|
"github.com/alecthomas/assert"
|
||||||
|
"github.com/jandedobbeleer/oh-my-posh/src/mock"
|
||||||
|
"github.com/jandedobbeleer/oh-my-posh/src/platform"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetAnsiFromColorString(t *testing.T) {
|
func TestGetAnsiFromColorString(t *testing.T) {
|
||||||
|
@ -12,6 +15,7 @@ func TestGetAnsiFromColorString(t *testing.T) {
|
||||||
Expected Color
|
Expected Color
|
||||||
Color string
|
Color string
|
||||||
Background bool
|
Background bool
|
||||||
|
Color256 bool
|
||||||
}{
|
}{
|
||||||
{Case: "256 color", Expected: Color("38;5;99"), Color: "99", Background: false},
|
{Case: "256 color", Expected: Color("38;5;99"), Color: "99", Background: false},
|
||||||
{Case: "256 color", Expected: Color("38;5;122"), Color: "122", Background: false},
|
{Case: "256 color", Expected: Color("38;5;122"), Color: "122", Background: false},
|
||||||
|
@ -23,27 +27,33 @@ func TestGetAnsiFromColorString(t *testing.T) {
|
||||||
{Case: "Base 8 background", Expected: Color("41"), Color: "red", Background: true},
|
{Case: "Base 8 background", Expected: Color("41"), Color: "red", Background: true},
|
||||||
{Case: "Base 16 foreground", Expected: Color("91"), Color: "lightRed", Background: false},
|
{Case: "Base 16 foreground", Expected: Color("91"), Color: "lightRed", Background: false},
|
||||||
{Case: "Base 16 backround", Expected: Color("101"), Color: "lightRed", Background: true},
|
{Case: "Base 16 backround", Expected: Color("101"), Color: "lightRed", Background: true},
|
||||||
|
{Case: "Non true color TERM", Expected: Color("38;5;146"), Color: "#AABBCC", Color256: true},
|
||||||
}
|
}
|
||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
ansiColors := &DefaultColors{}
|
ansiColors := &DefaultColors{}
|
||||||
ansiColor := ansiColors.ToColor(tc.Color, tc.Background)
|
ansiColor := ansiColors.ToColor(tc.Color, tc.Background, !tc.Color256)
|
||||||
assert.Equal(t, tc.Expected, ansiColor, tc.Case)
|
assert.Equal(t, tc.Expected, ansiColor, tc.Case)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMakeColors(t *testing.T) {
|
func TestMakeColors(t *testing.T) {
|
||||||
colors := MakeColors(nil, false, "", nil)
|
env := &mock.MockedEnvironment{}
|
||||||
|
env.On("Flags").Return(&platform.Flags{
|
||||||
|
TrueColor: true,
|
||||||
|
})
|
||||||
|
env.On("WindowsRegistryKeyValue", `HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM\ColorizationColor`).Return(&platform.WindowsRegistryValue{}, errors.New("err"))
|
||||||
|
colors := MakeColors(nil, false, "", env)
|
||||||
assert.IsType(t, &DefaultColors{}, colors)
|
assert.IsType(t, &DefaultColors{}, colors)
|
||||||
|
|
||||||
colors = MakeColors(nil, true, "", nil)
|
colors = MakeColors(nil, true, "", env)
|
||||||
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, "", nil)
|
colors = MakeColors(testPalette, false, "", env)
|
||||||
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, "", nil)
|
colors = MakeColors(testPalette, true, "", env)
|
||||||
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)
|
||||||
|
|
|
@ -8,12 +8,12 @@ func GetAccentColor(_ platform.Environment) (*RGB, error) {
|
||||||
return nil, &platform.NotImplemented{}
|
return nil, &platform.NotImplemented{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DefaultColors) SetAccentColor(_ platform.Environment, defaultColor string) {
|
func (d *DefaultColors) SetAccentColor(env platform.Environment, defaultColor string) {
|
||||||
if len(defaultColor) == 0 {
|
if len(defaultColor) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
d.accent = &Colors{
|
d.accent = &Colors{
|
||||||
Foreground: string(d.ToColor(defaultColor, false)),
|
Foreground: string(d.ToColor(defaultColor, false, env.Flags().TrueColor)),
|
||||||
Background: string(d.ToColor(defaultColor, true)),
|
Background: string(d.ToColor(defaultColor, true, env.Flags().TrueColor)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,8 @@ func (d *DefaultColors) SetAccentColor(env platform.Environment, defaultColor st
|
||||||
rgb, err := GetAccentColor(env)
|
rgb, err := GetAccentColor(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
d.accent = &Colors{
|
d.accent = &Colors{
|
||||||
Foreground: string(d.ToColor(defaultColor, false)),
|
Foreground: string(d.ToColor(defaultColor, false, env.Flags().TrueColor)),
|
||||||
Background: string(d.ToColor(defaultColor, true)),
|
Background: string(d.ToColor(defaultColor, true, env.Flags().TrueColor)),
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ Exports the config to an image file using customized output options.`,
|
||||||
writer := &ansi.Writer{
|
writer := &ansi.Writer{
|
||||||
TerminalBackground: shell.ConsoleBackgroundColor(env, cfg.TerminalBackground),
|
TerminalBackground: shell.ConsoleBackgroundColor(env, cfg.TerminalBackground),
|
||||||
AnsiColors: writerColors,
|
AnsiColors: writerColors,
|
||||||
|
TrueColor: env.CmdFlags.TrueColor,
|
||||||
}
|
}
|
||||||
writer.Init(shell.GENERIC)
|
writer.Init(shell.GENERIC)
|
||||||
eng := &engine.Engine{
|
eng := &engine.Engine{
|
||||||
|
|
|
@ -38,6 +38,7 @@ var debugCmd = &cobra.Command{
|
||||||
TerminalBackground: shell.ConsoleBackgroundColor(env, cfg.TerminalBackground),
|
TerminalBackground: shell.ConsoleBackgroundColor(env, cfg.TerminalBackground),
|
||||||
AnsiColors: writerColors,
|
AnsiColors: writerColors,
|
||||||
Plain: plain,
|
Plain: plain,
|
||||||
|
TrueColor: env.CmdFlags.TrueColor,
|
||||||
}
|
}
|
||||||
writer.Init(shell.GENERIC)
|
writer.Init(shell.GENERIC)
|
||||||
eng := &engine.Engine{
|
eng := &engine.Engine{
|
||||||
|
|
|
@ -67,6 +67,7 @@ func (b *Block) InitPlain(env platform.Environment, config *Config) {
|
||||||
b.writer = &ansi.Writer{
|
b.writer = &ansi.Writer{
|
||||||
TerminalBackground: shell.ConsoleBackgroundColor(env, config.TerminalBackground),
|
TerminalBackground: shell.ConsoleBackgroundColor(env, config.TerminalBackground),
|
||||||
AnsiColors: config.MakeColors(),
|
AnsiColors: config.MakeColors(),
|
||||||
|
TrueColor: env.Flags().TrueColor,
|
||||||
}
|
}
|
||||||
b.writer.Init(shell.GENERIC)
|
b.writer.Init(shell.GENERIC)
|
||||||
b.env = env
|
b.env = env
|
||||||
|
|
|
@ -337,7 +337,9 @@ func (e *Engine) print() string {
|
||||||
}
|
}
|
||||||
// in bash, the entire rprompt needs to be escaped for the prompt to be interpreted correctly
|
// in bash, the entire rprompt needs to be escaped for the prompt to be interpreted correctly
|
||||||
// see https://github.com/jandedobbeleer/oh-my-posh/pull/2398
|
// see https://github.com/jandedobbeleer/oh-my-posh/pull/2398
|
||||||
writer := &ansi.Writer{}
|
writer := &ansi.Writer{
|
||||||
|
TrueColor: e.Env.Flags().TrueColor,
|
||||||
|
}
|
||||||
writer.Init(shell.GENERIC)
|
writer.Init(shell.GENERIC)
|
||||||
prompt := writer.SaveCursorPosition()
|
prompt := writer.SaveCursorPosition()
|
||||||
prompt += writer.CarriageForward()
|
prompt += writer.CarriageForward()
|
||||||
|
|
|
@ -105,6 +105,7 @@ func engineRender() {
|
||||||
writer := &ansi.Writer{
|
writer := &ansi.Writer{
|
||||||
TerminalBackground: shell.ConsoleBackgroundColor(env, cfg.TerminalBackground),
|
TerminalBackground: shell.ConsoleBackgroundColor(env, cfg.TerminalBackground),
|
||||||
AnsiColors: writerColors,
|
AnsiColors: writerColors,
|
||||||
|
TrueColor: env.CmdFlags.TrueColor,
|
||||||
}
|
}
|
||||||
writer.Init(shell.GENERIC)
|
writer.Init(shell.GENERIC)
|
||||||
engine := &Engine{
|
engine := &Engine{
|
||||||
|
|
|
@ -22,6 +22,7 @@ func New(flags *platform.Flags) *Engine {
|
||||||
TerminalBackground: shell.ConsoleBackgroundColor(env, cfg.TerminalBackground),
|
TerminalBackground: shell.ConsoleBackgroundColor(env, cfg.TerminalBackground),
|
||||||
AnsiColors: cfg.MakeColors(),
|
AnsiColors: cfg.MakeColors(),
|
||||||
Plain: flags.Plain,
|
Plain: flags.Plain,
|
||||||
|
TrueColor: env.CmdFlags.TrueColor,
|
||||||
}
|
}
|
||||||
ansiWriter.Init(env.Shell())
|
ansiWriter.Init(env.Shell())
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ type Flags struct {
|
||||||
PromptCount int
|
PromptCount int
|
||||||
Cleared bool
|
Cleared bool
|
||||||
Version string
|
Version string
|
||||||
|
TrueColor bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommandError struct {
|
type CommandError struct {
|
||||||
|
@ -300,6 +301,11 @@ func (env *Shell) Init() {
|
||||||
if env.CmdFlags.Plain {
|
if env.CmdFlags.Plain {
|
||||||
log.Plain()
|
log.Plain()
|
||||||
}
|
}
|
||||||
|
trueColor := true
|
||||||
|
if env.Getenv("TERM_PROGRAM") == "Apple_Terminal" {
|
||||||
|
trueColor = false
|
||||||
|
}
|
||||||
|
env.CmdFlags.TrueColor = trueColor
|
||||||
env.fileCache = &fileCache{}
|
env.fileCache = &fileCache{}
|
||||||
env.fileCache.Init(env.CachePath())
|
env.fileCache.Init(env.CachePath())
|
||||||
env.resolveConfigPath()
|
env.resolveConfigPath()
|
||||||
|
|
Loading…
Reference in a new issue