diff --git a/Makefile b/Makefile index 8288dde..1a7130c 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ debug: DEBUG=1 go run main.go build: - @go build main.go + @go build -o bin/cointop main.go # http://macappstore.org/upx build/mac: clean/mac diff --git a/cmd/cointop.go b/cmd/cointop.go index 0b7b0e3..0f09a27 100644 --- a/cmd/cointop.go +++ b/cmd/cointop.go @@ -10,7 +10,7 @@ import ( // Run ... func Run() { var v, ver, test, clean, reset bool - var config, cmcAPIKey, apiChoice string + var config, cmcAPIKey, apiChoice, colorscheme string flag.BoolVar(&v, "v", false, "Version") flag.BoolVar(&ver, "version", false, "Version") flag.BoolVar(&test, "test", false, "Run test") @@ -19,6 +19,7 @@ func Run() { flag.StringVar(&config, "config", "", "Config filepath") flag.StringVar(&cmcAPIKey, "coinmarketcap-api-key", "", "CoinMarketCap API key") flag.StringVar(&apiChoice, "api", cointop.CoinGecko, "API choice") + flag.StringVar(&colorscheme, "colorscheme", "", "Colorscheme name") flag.Parse() if v || ver { fmt.Printf("cointop v%s", cointop.Version()) @@ -33,6 +34,7 @@ func Run() { ConfigFilepath: config, CoinMarketCapAPIKey: cmcAPIKey, APIChoice: apiChoice, + Colorscheme: colorscheme, }).Run() } } diff --git a/cointop/cointop.go b/cointop/cointop.go index df314e8..2aefe8c 100644 --- a/cointop/cointop.go +++ b/cointop/cointop.go @@ -29,7 +29,7 @@ type Cointop struct { g *gocui.Gui apiChoice string colorschemename string - colorscheme *ColorScheme + colorscheme *Colorscheme marketbarviewname string marketbarview *gocui.View chartview *gocui.View @@ -115,6 +115,7 @@ type portfolio struct { // Config config options type Config struct { APIChoice string + Colorscheme string ConfigFilepath string CoinMarketCapAPIKey string NoPrompts bool @@ -126,6 +127,7 @@ type apiKeys struct { } var defaultConfigPath = "~/.cointop/config.toml" +var defaultColorscheme = "cointop" // NewCointop initializes cointop func NewCointop(config *Config) *Cointop { @@ -233,6 +235,16 @@ func NewCointop(config *Config) *Cointop { } } + if config.Colorscheme != "" { + ct.colorschemename = config.Colorscheme + } + + colors, err := ct.getColorschemeColors() + if err != nil { + log.Fatal(err) + } + ct.colorscheme = NewColorscheme(colors) + if config.APIChoice != "" { ct.apiChoice = config.APIChoice if err := ct.saveConfig(); err != nil { diff --git a/cointop/colorscheme.go b/cointop/colorscheme.go index 84b70ba..6aeced6 100644 --- a/cointop/colorscheme.go +++ b/cointop/colorscheme.go @@ -14,8 +14,8 @@ type ISprintf func(...interface{}) string // colorCache .. type colorCache map[string]ISprintf -// ColorScheme ... -type ColorScheme struct { +// Colorscheme ... +type Colorscheme struct { colors colorschemeColors cache colorCache } @@ -53,190 +53,190 @@ var gocuicolorschemeColorsMap = map[string]gocui.Attribute{ "yellow": gocui.ColorYellow, } -// NewColorScheme ... -func NewColorScheme(colors colorschemeColors) *ColorScheme { - return &ColorScheme{ +// NewColorscheme ... +func NewColorscheme(colors colorschemeColors) *Colorscheme { + return &Colorscheme{ colors: colors, cache: make(colorCache), } } // BaseFg ... -func (c *ColorScheme) BaseFg() gocui.Attribute { +func (c *Colorscheme) BaseFg() gocui.Attribute { return c.gocuiFgColor("base") } // BaseBg ... -func (c *ColorScheme) BaseBg() gocui.Attribute { +func (c *Colorscheme) BaseBg() gocui.Attribute { return c.gocuiBgColor("base") } // Chart ... -func (c *ColorScheme) Chart(a ...interface{}) string { +func (c *Colorscheme) Chart(a ...interface{}) string { return c.color("chart", a...) } // Marketbar ... -func (c *ColorScheme) Marketbar(a ...interface{}) string { +func (c *Colorscheme) Marketbar(a ...interface{}) string { return c.color("marketbar", a...) } // MarketbarSprintf ... -func (c *ColorScheme) MarketbarSprintf() ISprintf { +func (c *Colorscheme) MarketbarSprintf() ISprintf { return c.toSprintf("marketbar") } // MarketbarChangeSprintf ... -func (c *ColorScheme) MarketbarChangeSprintf() ISprintf { +func (c *Colorscheme) MarketbarChangeSprintf() ISprintf { // NOTE: reusing table styles return c.toSprintf("table_column_change") } // MarketbarChangeDownSprintf ... -func (c *ColorScheme) MarketbarChangeDownSprintf() ISprintf { +func (c *Colorscheme) MarketbarChangeDownSprintf() ISprintf { // NOTE: reusing table styles return c.toSprintf("table_column_change_down") } // MarketbarChangeUpSprintf ... -func (c *ColorScheme) MarketbarChangeUpSprintf() ISprintf { +func (c *Colorscheme) MarketbarChangeUpSprintf() ISprintf { // NOTE: reusing table styles return c.toSprintf("table_column_change_up") } // MarketBarLabelActive ... -func (c *ColorScheme) MarketBarLabelActive(a ...interface{}) string { +func (c *Colorscheme) MarketBarLabelActive(a ...interface{}) string { return c.color("marketbar_label_active", a...) } // Menu ... -func (c *ColorScheme) Menu(a ...interface{}) string { +func (c *Colorscheme) Menu(a ...interface{}) string { return c.color("menu", a...) } // MenuHeader ... -func (c *ColorScheme) MenuHeader(a ...interface{}) string { +func (c *Colorscheme) MenuHeader(a ...interface{}) string { return c.color("menu_header", a...) } // MenuLabel ... -func (c *ColorScheme) MenuLabel(a ...interface{}) string { +func (c *Colorscheme) MenuLabel(a ...interface{}) string { return c.color("menu_label", a...) } // MenuLabelActive ... -func (c *ColorScheme) MenuLabelActive(a ...interface{}) string { +func (c *Colorscheme) MenuLabelActive(a ...interface{}) string { return c.color("menu_label_active", a...) } // Searchbar ... -func (c *ColorScheme) Searchbar(a ...interface{}) string { +func (c *Colorscheme) Searchbar(a ...interface{}) string { return c.color("searchbar", a...) } // Statusbar ... -func (c *ColorScheme) Statusbar(a ...interface{}) string { +func (c *Colorscheme) Statusbar(a ...interface{}) string { return c.color("statusbar", a...) } // TableColumnPrice ... -func (c *ColorScheme) TableColumnPrice(a ...interface{}) string { +func (c *Colorscheme) TableColumnPrice(a ...interface{}) string { return c.color("table_column_price", a...) } // TableColumnPriceSprintf ... -func (c *ColorScheme) TableColumnPriceSprintf() ISprintf { +func (c *Colorscheme) TableColumnPriceSprintf() ISprintf { return c.toSprintf("table_column_price") } // TableColumnChange ... -func (c *ColorScheme) TableColumnChange(a ...interface{}) string { +func (c *Colorscheme) TableColumnChange(a ...interface{}) string { return c.color("table_column_change", a...) } // TableColumnChangeSprintf ... -func (c *ColorScheme) TableColumnChangeSprintf() ISprintf { +func (c *Colorscheme) TableColumnChangeSprintf() ISprintf { return c.toSprintf("table_column_change") } // TableColumnChangeDown ... -func (c *ColorScheme) TableColumnChangeDown(a ...interface{}) string { +func (c *Colorscheme) TableColumnChangeDown(a ...interface{}) string { return c.color("table_column_change_down", a...) } // TableColumnChangeDownSprintf ... -func (c *ColorScheme) TableColumnChangeDownSprintf() ISprintf { +func (c *Colorscheme) TableColumnChangeDownSprintf() ISprintf { return c.toSprintf("table_column_change_down") } // TableColumnChangeUp ... -func (c *ColorScheme) TableColumnChangeUp(a ...interface{}) string { +func (c *Colorscheme) TableColumnChangeUp(a ...interface{}) string { return c.color("table_column_change_up", a...) } // TableColumnChangeUpSprintf ... -func (c *ColorScheme) TableColumnChangeUpSprintf() ISprintf { +func (c *Colorscheme) TableColumnChangeUpSprintf() ISprintf { return c.toSprintf("table_column_change_up") } // TableHeader ... -func (c *ColorScheme) TableHeader(a ...interface{}) string { +func (c *Colorscheme) TableHeader(a ...interface{}) string { return c.color("table_header", a...) } // TableHeaderSprintf ... -func (c *ColorScheme) TableHeaderSprintf() ISprintf { +func (c *Colorscheme) TableHeaderSprintf() ISprintf { return c.toSprintf("table_header") } // TableHeaderColumnActive ... -func (c *ColorScheme) TableHeaderColumnActive(a ...interface{}) string { +func (c *Colorscheme) TableHeaderColumnActive(a ...interface{}) string { return c.color("table_header_column_active", a...) } // TableHeaderColumnActiveSprintf ... -func (c *ColorScheme) TableHeaderColumnActiveSprintf() ISprintf { +func (c *Colorscheme) TableHeaderColumnActiveSprintf() ISprintf { return c.toSprintf("table_header_column_active") } // TableRow ... -func (c *ColorScheme) TableRow(a ...interface{}) string { +func (c *Colorscheme) TableRow(a ...interface{}) string { return c.color("table_row", a...) } // TableRowSprintf ... -func (c *ColorScheme) TableRowSprintf() ISprintf { +func (c *Colorscheme) TableRowSprintf() ISprintf { return c.toSprintf("table_row") } // TableRowActive ... -func (c *ColorScheme) TableRowActive(a ...interface{}) string { +func (c *Colorscheme) TableRowActive(a ...interface{}) string { return c.color("table_row_active", a...) } // TableRowFavorite ... -func (c *ColorScheme) TableRowFavorite(a ...interface{}) string { +func (c *Colorscheme) TableRowFavorite(a ...interface{}) string { return c.color("table_row_favorite", a...) } // TableRowFavoriteSprintf ... -func (c *ColorScheme) TableRowFavoriteSprintf() ISprintf { +func (c *Colorscheme) TableRowFavoriteSprintf() ISprintf { return c.toSprintf("table_row_favorite") } // SetViewColor ... -func (c *ColorScheme) SetViewColor(view *gocui.View, name string) { +func (c *Colorscheme) SetViewColor(view *gocui.View, name string) { view.FgColor = c.gocuiFgColor(name) view.BgColor = c.gocuiBgColor(name) } // SetViewActiveColor ... -func (c *ColorScheme) SetViewActiveColor(view *gocui.View, name string) { +func (c *Colorscheme) SetViewActiveColor(view *gocui.View, name string) { view.SelFgColor = c.gocuiFgColor(name) view.SelBgColor = c.gocuiBgColor(name) } -func (c *ColorScheme) toSprintf(name string) ISprintf { +func (c *Colorscheme) toSprintf(name string) ISprintf { if cached, ok := c.cache[name]; ok { return cached } @@ -267,11 +267,11 @@ func (c *ColorScheme) toSprintf(name string) ISprintf { return c.cache[name] } -func (c *ColorScheme) color(name string, a ...interface{}) string { +func (c *Colorscheme) color(name string, a ...interface{}) string { return c.toSprintf(name)(a...) } -func (c *ColorScheme) gocuiFgColor(name string) gocui.Attribute { +func (c *Colorscheme) gocuiFgColor(name string) gocui.Attribute { if v, ok := c.colors[name+"_fg"].(string); ok { if fg, ok := c.toGocuiAttr(v); ok { return fg @@ -281,7 +281,7 @@ func (c *ColorScheme) gocuiFgColor(name string) gocui.Attribute { return gocui.ColorDefault } -func (c *ColorScheme) gocuiBgColor(name string) gocui.Attribute { +func (c *Colorscheme) gocuiBgColor(name string) gocui.Attribute { if v, ok := c.colors[name+"_bg"].(string); ok { if bg, ok := c.toGocuiAttr(v); ok { return bg @@ -291,25 +291,25 @@ func (c *ColorScheme) gocuiBgColor(name string) gocui.Attribute { return gocui.ColorDefault } -func (c *ColorScheme) toFgAttr(k string) (color.Attribute, bool) { +func (c *Colorscheme) toFgAttr(k string) (color.Attribute, bool) { attr, ok := fgcolorschemeColorsMap[k] return attr, ok } -func (c *ColorScheme) toBgAttr(k string) (color.Attribute, bool) { +func (c *Colorscheme) toBgAttr(k string) (color.Attribute, bool) { attr, ok := bgcolorschemeColorsMap[k] return attr, ok } -func (c *ColorScheme) toBoldAttr(v bool) (color.Attribute, bool) { +func (c *Colorscheme) toBoldAttr(v bool) (color.Attribute, bool) { return color.Bold, v } -func (c *ColorScheme) toUnderlineAttr(v bool) (color.Attribute, bool) { +func (c *Colorscheme) toUnderlineAttr(v bool) (color.Attribute, bool) { return color.Underline, v } -func (c *ColorScheme) toGocuiAttr(k string) (gocui.Attribute, bool) { +func (c *Colorscheme) toGocuiAttr(k string) (gocui.Attribute, bool) { attr, ok := gocuicolorschemeColorsMap[k] return attr, ok } diff --git a/cointop/config.go b/cointop/config.go index 227d3ea..2953fff 100644 --- a/cointop/config.go +++ b/cointop/config.go @@ -20,7 +20,7 @@ type config struct { DefaultView interface{} `toml:"defaultView"` CoinMarketCap map[string]interface{} `toml:"coinmarketcap"` API interface{} `toml:"api"` - ColorScheme interface{} `toml:"colorscheme"` + Colorscheme interface{} `toml:"colorscheme"` } func (ct *Cointop) setupConfig() error { @@ -51,7 +51,7 @@ func (ct *Cointop) setupConfig() error { if err := ct.loadAPIChoiceFromConfig(); err != nil { return err } - if err := ct.loadColorSchemeFromConfig(); err != nil { + if err := ct.loadColorschemeFromConfig(); err != nil { return err } @@ -189,7 +189,7 @@ func (ct *Cointop) configToToml() ([]byte, error) { var inputs = &config{ API: apiChoiceIfc, - ColorScheme: colorschemeIfc, + Colorscheme: colorschemeIfc, CoinMarketCap: cmcIfc, Currency: currencyIfc, DefaultView: defaultViewIfc, @@ -260,27 +260,42 @@ func (ct *Cointop) loadAPIKeysFromConfig() error { return nil } -func (ct *Cointop) loadColorSchemeFromConfig() error { - if colorscheme, ok := ct.config.ColorScheme.(string); ok { +func (ct *Cointop) loadColorschemeFromConfig() error { + if colorscheme, ok := ct.config.Colorscheme.(string); ok { ct.colorschemename = colorscheme } + return nil +} + +func (ct *Cointop) getColorschemeColors() (map[string]interface{}, error) { var colors map[string]interface{} if ct.colorschemename == "" { - ct.colorschemename = "cointop" + ct.colorschemename = defaultColorscheme if _, err := toml.Decode(DefaultColors, &colors); err != nil { - return err + return nil, err } } else { path := normalizePath(fmt.Sprintf("~/.cointop/colors/%s.toml", ct.colorschemename)) + if _, err := os.Stat(path); os.IsNotExist(err) { + // NOTE: case for when cointop is set as the theme but the colorscheme file doesn't exist + if ct.colorschemename == "cointop" { + if _, err := toml.Decode(DefaultColors, &colors); err != nil { + return nil, err + } + + return colors, nil + } + + return nil, fmt.Errorf("The colorscheme file %q was not found.\n\nFor help and colorschemes, please visit: https://github.com/cointop-sh/colors", path) + } + if _, err := toml.DecodeFile(path, &colors); err != nil { - return err + return nil, err } } - ct.colorscheme = NewColorScheme(colors) - - return nil + return colors, nil } func (ct *Cointop) loadAPIChoiceFromConfig() error { diff --git a/cointop/version.go b/cointop/version.go index 0eef0d8..048c573 100644 --- a/cointop/version.go +++ b/cointop/version.go @@ -1,7 +1,7 @@ package cointop // TODO: make dynamic based on git tag -const version = "1.2.2" +const version = "1.3.0" func (ct *Cointop) version() string { return version