feat(config): add theme customization (#81)
Added theme customization via config.toml #17 ``` [theme] border = "#665C54" accent = "#FABD2F" muted = "#928374" text = "#EBDBB2" text_sel = "#FBF1C7" match = "#FE8019" desc = "#A89984" desc_sel = "#EBDBB2" sel_bg = "#504945" scroll_info = "#83A598" ghost_text = "#7C6F64" hist= "#fe8019" hist_sel = "#d65d0e" sys = "#fb4934" sys_sel = "#cc241d" alias = "#b8bb26" alias_sel = "#98971a" ``` --------- Co-authored-by: verse91 <versedev.store@proton.me> Co-authored-by: VERSE <sunnyone0901@gmail.com>
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
var defaultTheme = ThemeStyles{
|
||||
Border: "#a277ff",
|
||||
Accent: "#61ffca",
|
||||
Muted: "#6d6a7f",
|
||||
Text: "#edecee",
|
||||
TextSel: "#ffffff",
|
||||
Key: "#a277ff",
|
||||
Match: "#61ffca",
|
||||
Desc: "#9692a8",
|
||||
DescSel: "#edecee",
|
||||
SelBg: "#3d375e",
|
||||
SelText: "#110f18",
|
||||
ScrollInfo: "#a277ff",
|
||||
GhostText: "#4B4A4C",
|
||||
History: "#1a2d36",
|
||||
HistorySel: "#61ffca",
|
||||
Sys: "#1e1d28",
|
||||
SysSel: "#a277ff",
|
||||
Alias: "#2a2342",
|
||||
AliasSel: "#a277ff",
|
||||
}
|
||||
|
||||
var (
|
||||
themeMu sync.RWMutex
|
||||
themeStyles = defaultTheme
|
||||
)
|
||||
|
||||
func Theme() ThemeStyles {
|
||||
themeMu.RLock()
|
||||
defer themeMu.RUnlock()
|
||||
return themeStyles
|
||||
}
|
||||
|
||||
type ThemeStyles struct {
|
||||
Border string `toml:"border"`
|
||||
Accent string `toml:"accent"`
|
||||
Muted string `toml:"muted"`
|
||||
Text string `toml:"text"`
|
||||
TextSel string `toml:"text_sel"`
|
||||
Key string `toml:"key"`
|
||||
Match string `toml:"match"`
|
||||
Desc string `toml:"desc"`
|
||||
DescSel string `toml:"desc_sel"`
|
||||
SelBg string `toml:"sel_bg"`
|
||||
SelText string `toml:"sel_text"`
|
||||
ScrollInfo string `toml:"scroll_info"`
|
||||
GhostText string `toml:"ghost_text"`
|
||||
Sys string `toml:"sys"`
|
||||
SysSel string `toml:"sys_sel"`
|
||||
History string `toml:"hist"`
|
||||
HistorySel string `toml:"hist_sel"`
|
||||
Alias string `toml:"alias"`
|
||||
AliasSel string `toml:"alias_sel"`
|
||||
}
|
||||
|
||||
// LoadTheme reads theme.toml at filePath
|
||||
// Missing file - use defaults silently
|
||||
// Missing/empty fields - fall back to the default value for that field
|
||||
func LoadTheme(filePath string) {
|
||||
themeMu.Lock()
|
||||
defer themeMu.Unlock()
|
||||
|
||||
themeStyles = defaultTheme
|
||||
|
||||
data, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
// missing or unreadable file: use defaults
|
||||
return
|
||||
}
|
||||
|
||||
var t ThemeStyles
|
||||
if _, err := toml.Decode(string(data), &t); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
applyThemeWithFallback(&themeStyles, t, defaultTheme)
|
||||
}
|
||||
|
||||
// applyThemeWithFallback copies non-empty string fields from src into dst,
|
||||
// using def for any field that is empty in src
|
||||
func applyThemeWithFallback(dst *ThemeStyles, src, def ThemeStyles) {
|
||||
dv := reflect.ValueOf(dst).Elem()
|
||||
sv := reflect.ValueOf(src)
|
||||
dv2 := reflect.ValueOf(def)
|
||||
|
||||
for i := range dv.NumField() {
|
||||
sf := sv.Field(i).String()
|
||||
if sf != "" {
|
||||
dv.Field(i).SetString(sf)
|
||||
} else {
|
||||
dv.Field(i).SetString(dv2.Field(i).String())
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user