feat(color): enable accent color for macOS
Some checks failed
Code QL / code-ql (push) Waiting to run
Release / changelog (push) Waiting to run
Release / artifacts (push) Blocked by required conditions
Azure Static Web Apps CI/CD / Build and Deploy (push) Has been cancelled

resolves #5711
This commit is contained in:
Jan De Dobbeleer 2024-10-05 13:16:47 +02:00 committed by Jan De Dobbeleer
parent dba953a0a7
commit addef6530a
12 changed files with 118 additions and 37 deletions

View file

@ -11,7 +11,7 @@ on:
name: Build Code
jobs:
build:
runs-on: ubuntu-latest
runs-on: macos-latest
defaults:
run:
shell: pwsh

View file

@ -11,7 +11,7 @@ on:
jobs:
changelog:
runs-on: ubuntu-latest
runs-on: macos-latest
outputs:
version: ${{ steps.changelog.outputs.version }}
body: ${{ steps.changelog.outputs.clean_changelog }}

View file

@ -13,7 +13,10 @@ builds:
flags:
- -a
ldflags:
- -s -w -X github.com/jandedobbeleer/oh-my-posh/src/build.Version={{ .Version }} -X github.com/jandedobbeleer/oh-my-posh/src/build.Date={{ .Date }} -extldflags "-static"
- -s -w
- -X github.com/jandedobbeleer/oh-my-posh/src/build.Version={{ .Version }}
- -X github.com/jandedobbeleer/oh-my-posh/src/build.Date={{ .Date }}
- -extldflags "-static"
tags:
- netgo
- osusergo

2
src/cache/cache.go vendored
View file

@ -49,6 +49,7 @@ const (
ONEDAY = 1440
ONEWEEK = 10080
ONEMONTH = 43200
INFINITE = -1
)
type Entry struct {
@ -61,5 +62,6 @@ func (c *Entry) Expired() bool {
if c.TTL < 0 {
return false
}
return time.Now().Unix() >= (c.Timestamp + int64(c.TTL)*60)
}

1
src/cache/file.go vendored
View file

@ -80,6 +80,7 @@ func (fc *File) Set(key, value string, ttl int) {
Timestamp: time.Now().Unix(),
TTL: ttl,
})
fc.dirty = true
}

View file

@ -4,8 +4,10 @@ import (
"fmt"
"strconv"
"strings"
"time"
"github.com/gookit/color"
"github.com/jandedobbeleer/oh-my-posh/src/cache"
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
"github.com/jandedobbeleer/oh-my-posh/src/template"
)
@ -26,6 +28,20 @@ type Set struct {
Foreground Ansi `json:"foreground" toml:"foreground"`
}
func (c *Set) String() string {
return fmt.Sprintf("%s|%s", c.Foreground, c.Background)
}
func (c *Set) ParseString(colors string) {
parts := strings.Split(colors, "|")
if len(parts) != 2 {
return
}
c.Foreground = Ansi(parts[0])
c.Background = Ansi(parts[1])
}
type History []*Set
func (c *History) Len() int {
@ -144,6 +160,42 @@ func MakeColors(palette Palette, cacheEnabled bool, accentColor Ansi, env runtim
return
}
func (d *Defaults) SetAccentColor(env runtime.Environment, defaultColor Ansi) {
defer env.Trace(time.Now())
// get accent color from session cache first
if accent, OK := env.Session().Get("accent_color"); OK {
accentColors := &Set{}
accentColors.ParseString(accent)
d.accent = accentColors
return
}
rgb, err := GetAccentColor(env)
if err != nil {
d.accent = &Set{
Foreground: d.ToAnsi(defaultColor, false),
Background: d.ToAnsi(defaultColor, true),
}
return
}
if len(defaultColor) == 0 {
return
}
foreground := color.RGB(rgb.R, rgb.G, rgb.B, false)
background := color.RGB(rgb.R, rgb.G, rgb.B, true)
d.accent = &Set{
Foreground: Ansi(foreground.String()),
Background: Ansi(background.String()),
}
env.Session().Set("accent_color", d.accent.String(), cache.INFINITE)
}
type RGB struct {
R, G, B uint8
}

View file

@ -0,0 +1,40 @@
package color
import (
"errors"
"strconv"
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
)
func GetAccentColor(env runtime.Environment) (*RGB, error) {
output, err := env.RunCommand("defaults", "read", "-g", "AppleAccentColor")
if err != nil {
env.Error(err)
return nil, errors.New("unable to read accent color")
}
index, err := strconv.Atoi(output)
if err != nil {
env.Error(err)
return nil, errors.New("unable to parse accent color index")
}
var accentColors = map[int]RGB{
-1: {152, 152, 152}, // Graphite
0: {224, 55, 62}, // Red
1: {247, 130, 25}, // Orange
2: {255, 199, 38}, // Yellow
3: {96, 186, 70}, // Green
4: {0, 122, 255}, // Blue
5: {149, 61, 150}, // Purple
6: {247, 79, 159}, // Pink
}
color, exists := accentColors[index]
if !exists {
color = accentColors[6] // Default to graphite (white)
}
return &color, nil
}

View file

@ -6,6 +6,7 @@ import (
"github.com/alecthomas/assert"
"github.com/jandedobbeleer/oh-my-posh/src/cache"
cache_ "github.com/jandedobbeleer/oh-my-posh/src/cache/mock"
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
@ -43,6 +44,12 @@ func TestGetAnsiFromColorString(t *testing.T) {
func TestMakeColors(t *testing.T) {
env := &mock.Environment{}
env.On("Trace", testify_.Anything, testify_.Anything).Return(nil)
c := &cache_.Cache{}
c.On("Get", "accent_color").Return("", true)
env.On("Session").Return(c)
env.On("WindowsRegistryKeyValue", `HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM\ColorizationColor`).Return(&runtime.WindowsRegistryValue{}, errors.New("err"))
colors := MakeColors(nil, false, "", env)
assert.IsType(t, &Defaults{}, colors)

View file

@ -1,4 +1,4 @@
//go:build !windows
//go:build !windows && !darwin
package color
@ -7,14 +7,3 @@ import "github.com/jandedobbeleer/oh-my-posh/src/runtime"
func GetAccentColor(_ runtime.Environment) (*RGB, error) {
return nil, &runtime.NotImplemented{}
}
func (d *Defaults) SetAccentColor(_ runtime.Environment, defaultColor Ansi) {
if len(defaultColor) == 0 {
return
}
d.accent = &Set{
Foreground: d.ToAnsi(defaultColor, false),
Background: d.ToAnsi(defaultColor, true),
}
}

View file

@ -2,12 +2,14 @@ package color
import (
"errors"
"time"
"github.com/gookit/color"
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
)
func GetAccentColor(env runtime.Environment) (*RGB, error) {
defer env.Trace(time.Now())
if env == nil {
return nil, errors.New("unable to get color without environment")
}
@ -24,23 +26,3 @@ func GetAccentColor(env runtime.Environment) (*RGB, error) {
B: byte(value.DWord),
}, nil
}
func (d *Defaults) SetAccentColor(env runtime.Environment, defaultColor Ansi) {
rgb, err := GetAccentColor(env)
if err != nil {
d.accent = &Set{
Foreground: d.ToAnsi(defaultColor, false),
Background: d.ToAnsi(defaultColor, true),
}
return
}
foreground := color.RGB(rgb.R, rgb.G, rgb.B, false)
background := color.RGB(rgb.R, rgb.G, rgb.B, true)
d.accent = &Set{
Foreground: Ansi(foreground.String()),
Background: Ansi(background.String()),
}
}

View file

@ -357,22 +357,27 @@ func (term *Terminal) GOOS() string {
func (term *Terminal) RunCommand(command string, args ...string) (string, error) {
defer term.Trace(time.Now(), append([]string{command}, args...)...)
if cacheCommand, ok := term.cmdCache.Get(command); ok {
command = cacheCommand
}
output, err := cmd.Run(command, args...)
if err != nil {
term.Error(err)
}
term.Debug(output)
return output, err
}
func (term *Terminal) RunShellCommand(shell, command string) string {
defer term.Trace(time.Now())
if out, err := term.RunCommand(shell, "-c", command); err == nil {
return out
}
return ""
}

View file

@ -28,7 +28,7 @@ Oh My Posh supports multiple different color references, being:
- 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).
- The `accent` keyword which references the OS accent color (Windows and macOS only).
## Color templates