func LoadBarConfig() {
	i3barPid := os.Getppid()
	i3barCmdline, _ := ioutil.ReadFile(
		fmt.Sprintf("/proc/%d/cmdline", i3barPid))
	barID := "bar0"
	for _, arg := range bytes.Split(i3barCmdline, []byte{0}) {
		arg := string(arg)
		if strings.HasPrefix(arg, "--bar_id=") {
			barID = strings.TrimPrefix(arg, "--bar_id=")
			break
		}
	}
	var parsed barConfig
	json.Unmarshal(getBarConfig(barID), &parsed)
	LoadFromMap(parsed.Colors)
}
LoadBarConfig automatically loads colors from the current bar's
configuration. It assumes that the parent process is the i3bar instance,
and the bar_id command-line flag identifies the bar id.
package colors  
import (
	"bufio"
	"bytes"
	"encoding/json"
	"fmt"
	"image/color"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
	"github.com/lucasb-eyer/go-colorful"
	"github.com/spf13/afero"
)
type ColorfulColor interface {
	color.Color
	Colorful() colorful.Color
}
type colorfulColor struct {
	colorful.Color
}
func (c *colorfulColor) Colorful() colorful.Color {
	return c.Color
}
func Hex(hex string) ColorfulColor {
	c, err := colorful.Hex(hex)
	if err != nil {
		return nil
	}
	return &colorfulColor{c}
}
func Scheme(name string) ColorfulColor {
	return scheme[name]
}
func Set(name string, color color.Color) {
	if color == nil {
		delete(scheme, name)
		return
	}
	if c, ok := colorful.MakeColor(color); ok {
		scheme[name] = &colorfulColor{c}
	}
}
var scheme = map[string]ColorfulColor{}
func splitAtLastEqual(s string) (string, string, bool) {
	idx := strings.LastIndex(s, "=")
	if idx < 0 {
		return "", "", false
	}
	return s[:idx], s[idx+1:], true
}
func LoadFromArgs(args []string) {
	for _, arg := range args {
		if name, value, ok := splitAtLastEqual(arg); ok {
			if color := Hex(value); color != nil {
				scheme[name] = color
			}
		}
	}
}
func LoadFromMap(s map[string]string) {
	for name, value := range s {
		if color := Hex(value); color != nil {
			scheme[name] = color
		}
	}
}
var fs = afero.NewOsFs()
func LoadFromConfig(filename string) error {
	f, err := fs.Open(filename)
	if err != nil {
		return err
	}
	defer f.Close()
	s := bufio.NewScanner(f)
	s.Split(bufio.ScanLines)
	for s.Scan() {
		line := strings.TrimSpace(s.Text())
		if !strings.HasPrefix(line, "color_") {
			continue
		}
		name, value, ok := splitAtLastEqual(line)
		if !ok {
			continue
		}
		name = strings.TrimSpace(name[len("color_"):])
		value = strings.TrimSpace(value)
		if value[0] == '"' && value[len(value)-1] == '"' {
			value = value[1 : len(value)-1]
		} else if value[0] == '\'' && value[len(value)-1] == '\'' {
			value = value[1 : len(value)-1]
		}
		if color := Hex(value); color != nil {
			scheme[name] = color
		}
	}
	return nil
}
type barConfig struct {
	Colors map[string]string `json:"colors"`
}
var getBarConfig = func(barID string) []byte {
	out, _ := exec.Command("i3-msg", "-t", "get_bar_config", barID).Output()
	return out
}