package main import ( "encoding/json" "fmt" "math" "os" "path/filepath" ) // loadConfig reads the configuration file from the specified working directory. // If the file does not exist or cannot be read, it returns a default configuration. func loadConfig(cwd string) Config { configPath := filepath.Join(cwd, configFileName) file, err := os.ReadFile(configPath) if err != nil { return Config{ CustomColors: CustomColors{ BgColor: "#0d1117", CardBg: "#161b22", BorderColor: "#30363d", AccentColor: "#58a6ff", TextPrimary: "#c9d1d9", TextSecondary: "#8b949e", TextMuted: "#484f58", ButtonText: "#ffffff", }, } } var config Config json.Unmarshal(file, &config) if config.CustomColors.BgColor == "" { config.CustomColors = CustomColors{ BgColor: "#0d1117", CardBg: "#161b22", BorderColor: "#30363d", AccentColor: "#58a6ff", TextPrimary: "#c9d1d9", TextSecondary: "#8b949e", TextMuted: "#484f58", ButtonText: "#ffffff", } } return config } // saveConfig writes the provided configuration to the specified file path. // It marshals the config struct to JSON with indentation. func saveConfig(path string, config Config) { data, err := json.MarshalIndent(config, "", " ") if err != nil { fmt.Println("Error saving config:", err) return } os.WriteFile(path, data, 0644) } // humanize converts a byte count into a human-readable string (e.g., "1.2 MiB"). func humanize(bytes int64) string { if bytes < 1024 { return fmt.Sprintf("%d B", bytes) } exp := int(math.Log(float64(bytes)) / math.Log(1024)) pre := "KMGTPE"[exp-1 : exp] return fmt.Sprintf("%.1f %siB", float64(bytes)/math.Pow(1024, float64(exp)), pre) }