Add sementic colors for time, header and "default"

master
joce 3 years ago
parent b45fbfe908
commit 3df70dc52c
  1. 2
      cmd/mop/main.go
  2. 12
      layout.go
  3. 20
      markup.go
  4. 84
      profile.go
  5. 25
      screen.go

@ -143,5 +143,5 @@ func main() {
defer screen.Close()
mainLoop(screen, profile)
profile.Save()
profile.Save()
}

@ -168,7 +168,7 @@ func (layout *Layout) prettify(quotes *Quotes) []Stock {
profile := quotes.profile
if profile.Filter != ""{ // Fix for blank display if invalid filter expression was cleared.
if profile.Filter != "" { // Fix for blank display if invalid filter expression was cleared.
if profile.filterExpression != nil {
if layout.filter == nil { // Initialize filter on first invocation.
layout.filter = NewFilter(profile)
@ -218,11 +218,11 @@ func buildMarketTemplate() *template.Template {
//-----------------------------------------------------------------------------
func buildQuotesTemplate() *template.Template {
markup := `<right><white>{{.Now}}</></right>
markup := `<right><time>{{.Now}}</></right>
{{.Header}}
<header>{{.Header}}</>
{{range.Stocks}}{{if eq .Direction 1}}<gain>{{else if eq .Direction -1}}<loss>{{end}}{{.Ticker}}{{.LastTrade}}{{.Change}}{{.ChangePct}}{{.Open}}{{.Low}}{{.High}}{{.Low52}}{{.High52}}{{.Volume}}{{.AvgVolume}}{{.PeRatio}}{{.Dividend}}{{.Yield}}{{.MarketCap}}{{.PreOpen}}{{.AfterHours}}</>
{{end}}`
@ -234,7 +234,7 @@ func highlight(collections ...map[string]string) {
for _, collection := range collections {
change := collection[`change`]
if change[len(change)-1:] == `%` {
change = change[0:len(change)-1]
change = change[0 : len(change)-1]
}
adv, err := strconv.ParseFloat(change, 64)
if err == nil {
@ -272,9 +272,9 @@ func group(stocks []Stock) []Stock {
func arrowFor(column int, profile *Profile) string {
if column == profile.SortColumn {
if profile.Ascending {
return string('\U00002191')
return string('')
}
return string('\U00002193')
return string('')
}
return ``
}

@ -5,9 +5,10 @@
package mop
import (
`github.com/nsf/termbox-go`
`regexp`
`strings`
"regexp"
"strings"
"github.com/nsf/termbox-go"
)
// Markup implements some minimalistic text formatting conventions that
@ -35,9 +36,6 @@ type Markup struct {
// colors and column alignments.
func NewMarkup(profile *Profile) *Markup {
markup := &Markup{}
markup.Foreground = termbox.ColorDefault
markup.Background = termbox.ColorDefault
markup.RightAligned = false
markup.tags = make(map[string]termbox.Attribute)
markup.tags[`/`] = termbox.ColorDefault
@ -67,6 +65,14 @@ func NewMarkup(profile *Profile) *Markup {
markup.tags[`gain`] = markup.tags[profile.Colors.Gain]
markup.tags[`loss`] = markup.tags[profile.Colors.Loss]
markup.tags[`tag`] = markup.tags[profile.Colors.Tag]
markup.tags[`header`] = markup.tags[profile.Colors.Header]
markup.tags[`time`] = markup.tags[profile.Colors.Time]
markup.tags[`default`] = markup.tags[profile.Colors.Default]
markup.Foreground = markup.tags[profile.Colors.Default]
markup.Background = termbox.ColorDefault
markup.RightAligned = false
markup.regex = markup.supportedTags() // Once we have the hash we could build the regex.
@ -138,7 +144,7 @@ func (markup *Markup) process(tag string, open bool) bool {
if attribute >= termbox.AttrBold {
markup.Foreground &= ^attribute // Clear the Termbox attribute.
} else {
markup.Foreground = termbox.ColorDefault
markup.Foreground = markup.tags[`default`]
}
}
}

@ -16,22 +16,28 @@ import (
const defaultGainColor = "green"
const defaultLossColor = "red"
const defaultTagColor = "yellow"
const defaultHeaderColor = "lightgray"
const defaultTimeColor = "lightgray"
const defaultColor = "lightgray"
// Profile manages Mop program settings as defined by user (ex. list of
// stock tickers). The settings are serialized using JSON and saved in
// the ~/.moprc file.
type Profile struct {
Tickers []string // List of stock tickers to display.
MarketRefresh int // Time interval to refresh market data.
QuotesRefresh int // Time interval to refresh stock quotes.
SortColumn int // Column number by which we sort stock quotes.
Ascending bool // True when sort order is ascending.
Grouped bool // True when stocks are grouped by advancing/declining.
Filter string // Filter in human form
Colors struct { // User defined colors
Gain string
Loss string
Tag string
Tickers []string // List of stock tickers to display.
MarketRefresh int // Time interval to refresh market data.
QuotesRefresh int // Time interval to refresh stock quotes.
SortColumn int // Column number by which we sort stock quotes.
Ascending bool // True when sort order is ascending.
Grouped bool // True when stocks are grouped by advancing/declining.
Filter string // Filter in human form
Colors struct { // User defined colors
Gain string
Loss string
Tag string
Header string
Time string
Default string
}
filterExpression *govaluate.EvaluableExpression // The filter as a govaluate expression
selectedColumn int // Stores selected column number when the column editor is active.
@ -40,24 +46,24 @@ type Profile struct {
func IsSupportedColor(colorName string) bool {
switch colorName {
case
"black",
"red",
"green",
"yellow",
"blue",
"magenta",
"cyan",
"white",
"darkgray",
"lightred",
"lightgreen",
"lightyellow",
"lightblue",
"lightmagenta",
"lightcyan",
"lightgray":
return true
case
"black",
"red",
"green",
"yellow",
"blue",
"magenta",
"cyan",
"white",
"darkgray",
"lightred",
"lightgreen",
"lightyellow",
"lightblue",
"lightmagenta",
"lightcyan",
"lightgray":
return true
}
return false
}
@ -78,13 +84,19 @@ func NewProfile(filename string) *Profile {
profile.Colors.Gain = defaultGainColor
profile.Colors.Loss = defaultLossColor
profile.Colors.Tag = defaultTagColor
profile.Colors.Header = defaultHeaderColor
profile.Colors.Time = defaultTimeColor
profile.Colors.Default = defaultColor
profile.Save()
} else {
json.Unmarshal(data, profile)
InitColor(profile.Colors.Gain, defaultGainColor)
InitColor(profile.Colors.Loss, defaultLossColor)
InitColor(profile.Colors.Tag, defaultTagColor)
InitColor(&profile.Colors.Gain, defaultGainColor)
InitColor(&profile.Colors.Loss, defaultLossColor)
InitColor(&profile.Colors.Tag, defaultTagColor)
InitColor(&profile.Colors.Header, defaultHeaderColor)
InitColor(&profile.Colors.Time, defaultTimeColor)
InitColor(&profile.Colors.Default, defaultColor)
profile.SetFilter(profile.Filter)
}
@ -93,10 +105,10 @@ func NewProfile(filename string) *Profile {
return profile
}
func InitColor(color string, defaultValue string) {
color = strings.ToLower(color)
if !IsSupportedColor(color) {
color = defaultValue;
func InitColor(color *string, defaultValue string) {
*color = strings.ToLower(*color)
if !IsSupportedColor(*color) {
*color = defaultValue
}
}

@ -5,11 +5,12 @@
package mop
import (
`github.com/nsf/termbox-go`
`strings`
`time`
`strconv`
`fmt`
"fmt"
"strconv"
"strings"
"time"
"github.com/nsf/termbox-go"
)
// Screen is thin wrapper around Termbox library to provide basic display
@ -90,7 +91,7 @@ func (screen *Screen) ClearLine(x int, y int) *Screen {
func (screen *Screen) Draw(objects ...interface{}) *Screen {
zonename, _ := time.Now().In(time.Local).Zone()
if screen.pausedAt != nil {
defer screen.DrawLine(0, 0, `<right><r>`+screen.pausedAt.Format(`3:04:05pm ` + zonename)+`</r></right>`)
defer screen.DrawLine(0, 0, `<right><r>`+screen.pausedAt.Format(`3:04:05pm `+zonename)+`</r></right>`)
}
for _, ptr := range objects {
switch ptr.(type) {
@ -102,7 +103,7 @@ func (screen *Screen) Draw(objects ...interface{}) *Screen {
screen.draw(screen.layout.Quotes(object.Fetch()))
case time.Time:
timestamp := ptr.(time.Time).Format(`3:04:05pm ` + zonename)
screen.DrawLine(0, 0, `<right>`+timestamp+`</right>`)
screen.DrawLine(0, 0, `<right><time>`+timestamp+`</></right>`)
default:
screen.draw(ptr.(string))
}
@ -146,7 +147,7 @@ func (screen *Screen) draw(str string) {
drewHeading := false
tempFormat := "%" + strconv.Itoa(screen.width) + "s"
blankLine := fmt.Sprintf(tempFormat,"")
blankLine := fmt.Sprintf(tempFormat, "")
allLines = strings.Split(str, "\n")
// Write the lines being updated.
@ -154,9 +155,9 @@ func (screen *Screen) draw(str string) {
screen.DrawLine(0, row, allLines[row])
// Did we draw the underlined heading row? This is a crude
// check, but--see comments below...
if strings.Contains(allLines[row],"Ticker") &&
strings.Contains(allLines[row],"Last") &&
strings.Contains(allLines[row],"Change") {
if strings.Contains(allLines[row], "Ticker") &&
strings.Contains(allLines[row], "Last") &&
strings.Contains(allLines[row], "Change") {
drewHeading = true
}
}
@ -173,7 +174,7 @@ func (screen *Screen) draw(str string) {
// cycle. In that case, padding with blank lines would overwrite the
// stocks list.)
if drewHeading {
for i := len(allLines)-1; i < screen.height; i++ {
for i := len(allLines) - 1; i < screen.height; i++ {
screen.DrawLine(0, i, blankLine)
}
}

Loading…
Cancel
Save