mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-05 21:15:38 -05:00
251 lines
7.0 KiB
Go
251 lines
7.0 KiB
Go
package dank16
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
type VSCodeTheme struct {
|
|
Schema string `json:"$schema"`
|
|
Name string `json:"name"`
|
|
Type string `json:"type"`
|
|
Colors map[string]string `json:"colors"`
|
|
TokenColors []VSCodeTokenColor `json:"tokenColors"`
|
|
SemanticHighlighting bool `json:"semanticHighlighting"`
|
|
SemanticTokenColors map[string]VSCodeTokenSetting `json:"semanticTokenColors"`
|
|
}
|
|
|
|
type VSCodeTokenColor struct {
|
|
Scope interface{} `json:"scope"`
|
|
Settings VSCodeTokenSetting `json:"settings"`
|
|
}
|
|
|
|
type VSCodeTokenSetting struct {
|
|
Foreground string `json:"foreground,omitempty"`
|
|
FontStyle string `json:"fontStyle,omitempty"`
|
|
}
|
|
|
|
func updateTokenColor(tc interface{}, scopeToColor map[string]string) {
|
|
tcMap, ok := tc.(map[string]interface{})
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
scopes, ok := tcMap["scope"].([]interface{})
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
settings, ok := tcMap["settings"].(map[string]interface{})
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
isYaml := hasScopeContaining(scopes, "yaml")
|
|
|
|
for _, scope := range scopes {
|
|
scopeStr, ok := scope.(string)
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
if scopeStr == "string" && isYaml {
|
|
continue
|
|
}
|
|
|
|
if applyColorToScope(settings, scope, scopeToColor) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
func applyColorToScope(settings map[string]interface{}, scope interface{}, scopeToColor map[string]string) bool {
|
|
scopeStr, ok := scope.(string)
|
|
if !ok {
|
|
return false
|
|
}
|
|
|
|
newColor, exists := scopeToColor[scopeStr]
|
|
if !exists {
|
|
return false
|
|
}
|
|
|
|
settings["foreground"] = newColor
|
|
return true
|
|
}
|
|
|
|
func hasScopeContaining(scopes []interface{}, substring string) bool {
|
|
for _, scope := range scopes {
|
|
scopeStr, ok := scope.(string)
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
for i := 0; i <= len(scopeStr)-len(substring); i++ {
|
|
if scopeStr[i:i+len(substring)] == substring {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func EnrichVSCodeTheme(themeData []byte, colors []string) ([]byte, error) {
|
|
var theme map[string]interface{}
|
|
if err := json.Unmarshal(themeData, &theme); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
colorsMap, ok := theme["colors"].(map[string]interface{})
|
|
if !ok {
|
|
colorsMap = make(map[string]interface{})
|
|
theme["colors"] = colorsMap
|
|
}
|
|
|
|
bg := colors[0]
|
|
isLight := false
|
|
if len(bg) == 7 && bg[0] == '#' {
|
|
r, g, b := 0, 0, 0
|
|
fmt.Sscanf(bg[1:], "%02x%02x%02x", &r, &g, &b)
|
|
luminance := (0.299*float64(r) + 0.587*float64(g) + 0.114*float64(b)) / 255.0
|
|
isLight = luminance > 0.5
|
|
}
|
|
|
|
if isLight {
|
|
theme["type"] = "light"
|
|
} else {
|
|
theme["type"] = "dark"
|
|
}
|
|
|
|
colorsMap["terminal.ansiBlack"] = colors[0]
|
|
colorsMap["terminal.ansiRed"] = colors[1]
|
|
colorsMap["terminal.ansiGreen"] = colors[2]
|
|
colorsMap["terminal.ansiYellow"] = colors[3]
|
|
colorsMap["terminal.ansiBlue"] = colors[4]
|
|
colorsMap["terminal.ansiMagenta"] = colors[5]
|
|
colorsMap["terminal.ansiCyan"] = colors[6]
|
|
colorsMap["terminal.ansiWhite"] = colors[7]
|
|
colorsMap["terminal.ansiBrightBlack"] = colors[8]
|
|
colorsMap["terminal.ansiBrightRed"] = colors[9]
|
|
colorsMap["terminal.ansiBrightGreen"] = colors[10]
|
|
colorsMap["terminal.ansiBrightYellow"] = colors[11]
|
|
colorsMap["terminal.ansiBrightBlue"] = colors[12]
|
|
colorsMap["terminal.ansiBrightMagenta"] = colors[13]
|
|
colorsMap["terminal.ansiBrightCyan"] = colors[14]
|
|
colorsMap["terminal.ansiBrightWhite"] = colors[15]
|
|
|
|
tokenColors, ok := theme["tokenColors"].([]interface{})
|
|
if ok {
|
|
scopeToColor := map[string]string{
|
|
"comment": colors[8],
|
|
"punctuation.definition.comment": colors[8],
|
|
"keyword": colors[5],
|
|
"storage.type": colors[13],
|
|
"storage.modifier": colors[5],
|
|
"variable": colors[15],
|
|
"variable.parameter": colors[7],
|
|
"meta.object-literal.key": colors[4],
|
|
"meta.property.object": colors[4],
|
|
"variable.other.property": colors[4],
|
|
"constant.other.symbol": colors[12],
|
|
"constant.numeric": colors[12],
|
|
"constant.language": colors[12],
|
|
"constant.character": colors[3],
|
|
"entity.name.type": colors[12],
|
|
"support.type": colors[13],
|
|
"entity.name.class": colors[12],
|
|
"entity.name.function": colors[2],
|
|
"support.function": colors[2],
|
|
"support.class": colors[15],
|
|
"support.variable": colors[15],
|
|
"variable.language": colors[12],
|
|
"entity.name.tag.yaml": colors[12],
|
|
"string.unquoted.plain.out.yaml": colors[15],
|
|
"string.unquoted.yaml": colors[15],
|
|
"string": colors[3],
|
|
}
|
|
|
|
for i, tc := range tokenColors {
|
|
updateTokenColor(tc, scopeToColor)
|
|
tokenColors[i] = tc
|
|
}
|
|
|
|
yamlRules := []VSCodeTokenColor{
|
|
{
|
|
Scope: "entity.name.tag.yaml",
|
|
Settings: VSCodeTokenSetting{Foreground: colors[12]},
|
|
},
|
|
{
|
|
Scope: []string{"string.unquoted.plain.out.yaml", "string.unquoted.yaml"},
|
|
Settings: VSCodeTokenSetting{Foreground: colors[15]},
|
|
},
|
|
}
|
|
|
|
for _, rule := range yamlRules {
|
|
tokenColors = append(tokenColors, rule)
|
|
}
|
|
|
|
theme["tokenColors"] = tokenColors
|
|
}
|
|
|
|
if semanticTokenColors, ok := theme["semanticTokenColors"].(map[string]interface{}); ok {
|
|
updates := map[string]string{
|
|
"variable": colors[15],
|
|
"variable.readonly": colors[12],
|
|
"property": colors[4],
|
|
"function": colors[2],
|
|
"method": colors[2],
|
|
"type": colors[12],
|
|
"class": colors[12],
|
|
"typeParameter": colors[13],
|
|
"enumMember": colors[12],
|
|
"string": colors[3],
|
|
"number": colors[12],
|
|
"comment": colors[8],
|
|
"keyword": colors[5],
|
|
"operator": colors[15],
|
|
"parameter": colors[7],
|
|
"namespace": colors[15],
|
|
}
|
|
|
|
for key, color := range updates {
|
|
if existing, ok := semanticTokenColors[key].(map[string]interface{}); ok {
|
|
existing["foreground"] = color
|
|
} else {
|
|
semanticTokenColors[key] = map[string]interface{}{
|
|
"foreground": color,
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
semanticTokenColors := make(map[string]interface{})
|
|
updates := map[string]string{
|
|
"variable": colors[7],
|
|
"variable.readonly": colors[12],
|
|
"property": colors[4],
|
|
"function": colors[2],
|
|
"method": colors[2],
|
|
"type": colors[12],
|
|
"class": colors[12],
|
|
"typeParameter": colors[13],
|
|
"enumMember": colors[12],
|
|
"string": colors[3],
|
|
"number": colors[12],
|
|
"comment": colors[8],
|
|
"keyword": colors[5],
|
|
"operator": colors[15],
|
|
"parameter": colors[7],
|
|
"namespace": colors[15],
|
|
}
|
|
|
|
for key, color := range updates {
|
|
semanticTokenColors[key] = map[string]interface{}{
|
|
"foreground": color,
|
|
}
|
|
}
|
|
theme["semanticTokenColors"] = semanticTokenColors
|
|
}
|
|
|
|
return json.MarshalIndent(theme, "", " ")
|
|
}
|