hlctl/config/type.go

198 lines
4.1 KiB
Go

package config
import (
"errors"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/BurntSushi/toml"
"sectorinf.com/emilis/hlctl/ctllog"
"sectorinf.com/emilis/hlctl/hlcl/cmd"
)
var (
cfgPath = filepath.Join(
os.Getenv("HOME"),
".config",
"herbstluftwm",
"hlctl.toml",
)
log = ctllog.Logger{}.New("config", ctllog.ColorRGB{}.FromHex("ff5aff"))
)
type (
HlwmConfig struct {
Font string
FontBold string
Mod string
TermSpawnKey string
Term string
Groups GroupConfig
Theme Theme
Services ServicesConfig
}
ServicesConfig struct {
Services []string
}
GroupConfig struct {
Groups uint8
Tags uint8
}
Theme struct {
Colors Colors
}
Colors struct {
Active string
Normal string
Urgent string
Text string
}
)
func (h HlwmConfig) Save() error {
log.Printf("Saving to [%s]", cfgPath)
cfg, err := os.Create(cfgPath)
if err != nil {
return fmt.Errorf("opening cfg path: [%s]: %w", cfgPath, err)
}
defer cfg.Close()
err = toml.NewEncoder(cfg).Encode(h)
if err != nil {
return fmt.Errorf("encoding config to toml: %w", err)
}
return cfg.Sync()
}
func (h HlwmConfig) Validate() error {
if h.Font == "" ||
h.FontBold == "" ||
h.Mod == "" ||
h.TermSpawnKey == "" ||
h.Term == "" ||
h.Groups.Groups == 0 ||
h.Groups.Tags == 0 ||
len(h.Theme.Colors.Active) < 6 ||
len(h.Theme.Colors.Normal) < 6 ||
len(h.Theme.Colors.Urgent) < 6 ||
len(h.Theme.Colors.Text) < 6 {
return errors.New("some configuration options are missing")
}
return nil
}
// Collect the config from loaded attributes. Or get default
// if that fails.
func Collect() HlwmConfig {
getOrNothing := func(settingName string, value *string) {
v, err := Get(settingName)
if err != nil {
return
}
*value = v.String()
}
getUints := func(settingName string, value *uint8) {
v, err := Get(settingName)
if err != nil {
return
}
val, err := v.Uint()
if err != nil {
return
}
*value = uint8(val)
}
cfg := Default
getOrNothing(Font, &cfg.Font)
getOrNothing(FontBold, &cfg.FontBold)
getOrNothing(ModKey, &cfg.Mod)
getOrNothing(TermSpawnKey, &cfg.TermSpawnKey)
getOrNothing(Term, &cfg.Term)
getUints(GroupCount, &cfg.Groups.Groups)
getUints(TagsPerGroup, &cfg.Groups.Tags)
getOrNothing(ColorActive, &cfg.Theme.Colors.Active)
getOrNothing(ColorNormal, &cfg.Theme.Colors.Normal)
getOrNothing(ColorUrgent, &cfg.Theme.Colors.Urgent)
getOrNothing(ColorText, &cfg.Theme.Colors.Text)
svcsString, err := Get(Services)
if err == nil {
cfg.Services.Services = strings.Split(svcsString.String(), ";")
}
return cfg
}
func (h HlwmConfig) SetAll() error {
err := New(GroupCount, strconv.Itoa(int(h.Groups.Groups)), cmd.Uint)
if err != nil {
return fmt.Errorf("%s: %w", GroupCount, err)
}
err = New(TagsPerGroup, strconv.Itoa(int(h.Groups.Tags)), cmd.Uint)
if err != nil {
return fmt.Errorf("%s: %w", TagsPerGroup, err)
}
sets := map[string]string{
Font: h.Font,
FontBold: h.FontBold,
ModKey: h.Mod,
TermSpawnKey: h.TermSpawnKey,
Term: h.Term,
ColorActive: h.Theme.Colors.Active,
ColorNormal: h.Theme.Colors.Normal,
ColorUrgent: h.Theme.Colors.Urgent,
ColorText: h.Theme.Colors.Text,
Services: strings.Join(h.Services.Services, ";"),
}
for cfg, val := range sets {
if err := New(cfg, val, cmd.String); err != nil {
return fmt.Errorf("%s[%s]: %w", cfg, val, err)
}
}
return nil
}
func Load() HlwmConfig {
cfg := HlwmConfig{}
if _, err := toml.DecodeFile(cfgPath, &cfg); err != nil {
log.Warnf(
"could not read file [%s] for config, using default",
cfgPath,
)
return Default
}
return cfg
}
var (
Default = HlwmConfig{
Font: "-*-fixed-medium-*-*-*-12-*-*-*-*-*-*-*",
FontBold: "-*-fixed-bold-*-*-*-12-*-*-*-*-*-*-*",
Mod: "Mod4",
TermSpawnKey: "Home",
Term: "alacritty",
Groups: GroupConfig{
Groups: 3,
Tags: 5,
},
Theme: Theme{
Colors: Colors{
Active: "#800080",
Normal: "#330033",
Urgent: "#7811A1",
Text: "#898989",
},
},
Services: ServicesConfig{
Services: []string{"fcitx5"},
},
}
)