diff --git a/README.md b/README.md index 6b0a7a2..30f0c68 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ $ cointop ### Shortcuts -List of default shortcuts: +List of default shortcut keys: Key|Action ----|------| diff --git a/cointop/chart.go b/cointop/chart.go index 25143bb..d5739c7 100644 --- a/cointop/chart.go +++ b/cointop/chart.go @@ -9,6 +9,8 @@ import ( "github.com/miguelmota/cointop/pkg/color" ) +var oneWeek = (time.Hour * 24) * 7 + func (ct *Cointop) updateChart() error { maxX := ct.Width() if maxX > ct.maxtablewidth { @@ -36,7 +38,7 @@ func (ct *Cointop) chartPoints(maxX int, coin string) error { now := time.Now() secs := now.Unix() - start := secs - oneWeek + start := secs - int64(oneWeek.Seconds()) end := secs var data []float64 diff --git a/cointop/cointop.go b/cointop/cointop.go index 2bf6f92..215c073 100644 --- a/cointop/cointop.go +++ b/cointop/cointop.go @@ -12,15 +12,6 @@ import ( "github.com/miguelmota/cointop/pkg/table" ) -var ( - oneMinute int64 = 60 - oneHour = oneMinute * 60 - oneDay = oneHour * 24 - oneWeek = oneDay * 7 - oneMonth = oneDay * 30 - oneYear = oneDay * 365 -) - // Cointop cointop type Cointop struct { g *gocui.Gui diff --git a/cointop/keybindings.go b/cointop/keybindings.go index 6e337e8..b53b9b3 100644 --- a/cointop/keybindings.go +++ b/cointop/keybindings.go @@ -1,77 +1,326 @@ package cointop import ( - "log" + "strings" "github.com/jroimartin/gocui" ) -func (ct *Cointop) keybindings(g *gocui.Gui) error { - ct.setKeybinding(gocui.KeyArrowUp, ct.cursorUp) - ct.setKeybinding(gocui.KeyArrowDown, ct.cursorDown) - ct.setKeybinding(gocui.KeyArrowLeft, ct.prevPage) - ct.setKeybinding(gocui.KeyArrowRight, ct.nextPage) - ct.setKeybinding(gocui.KeyPgdn, ct.pageUp) - ct.setKeybinding(gocui.KeyPgup, ct.pageUp) - ct.setKeybinding(gocui.KeyHome, ct.navigateFirstLine) - ct.setKeybinding(gocui.KeyEnd, ct.navigateLastLine) - ct.setKeybinding(gocui.KeyEnter, ct.openLink) - ct.setKeybinding(gocui.KeyEsc, ct.quit) - ct.setKeybinding(gocui.KeySpace, ct.openLink) - ct.setKeybinding(gocui.KeyCtrlC, ct.quit) - ct.setKeybinding(gocui.KeyCtrlD, ct.pageDown) - ct.setKeybinding(gocui.KeyCtrlN, ct.nextPage) - ct.setKeybinding(gocui.KeyCtrlP, ct.prevPage) - ct.setKeybinding(gocui.KeyCtrlR, ct.refresh) - ct.setKeybinding(gocui.KeyCtrlU, ct.pageUp) - ct.setKeybindingMod(gocui.KeyArrowUp, gocui.ModAlt, ct.sortAsc) - ct.setKeybindingMod(gocui.KeyArrowDown, gocui.ModAlt, ct.sortDesc) - ct.setKeybindingMod(gocui.KeyArrowLeft, gocui.ModAlt, ct.sortPrevCol) - ct.setKeybindingMod(gocui.KeyArrowRight, gocui.ModAlt, ct.sortNextCol) - ct.setKeybinding(gocui.KeyF1, ct.openHelp) - ct.setKeybinding('0', ct.firstPage) - ct.setKeybinding('1', ct.sortfn("1hchange", true)) - ct.setKeybinding('2', ct.sortfn("24hchange", true)) - ct.setKeybinding('7', ct.sortfn("7dchange", true)) - ct.setKeybinding('a', ct.sortfn("availablesupply", true)) - ct.setKeybinding('c', ct.toggleCoinChart) - ct.setKeybinding('g', ct.navigateFirstLine) - ct.setKeybinding('G', ct.navigateLastLine) - ct.setKeybinding('h', ct.prevPage) - ct.setKeybinding('H', ct.navigatePageFirstLine) - ct.setKeybinding('j', ct.cursorDown) - ct.setKeybinding('k', ct.cursorUp) - ct.setKeybinding('l', ct.nextPage) - ct.setKeybinding('L', ct.navigatePageLastLine) - ct.setKeybinding('m', ct.sortfn("marketcap", true)) - ct.setKeybinding('M', ct.navigatePageMiddleLine) - ct.setKeybinding('n', ct.sortfn("name", true)) - ct.setKeybinding('p', ct.sortfn("price", true)) - ct.setKeybinding('r', ct.sortfn("rank", false)) - ct.setKeybinding('s', ct.sortfn("symbol", false)) - ct.setKeybinding('t', ct.sortfn("totalsupply", true)) - ct.setKeybinding('u', ct.sortfn("lastupdated", true)) - ct.setKeybinding('v', ct.sortfn("24hvolume", true)) - ct.setKeybinding('q', ct.quit) - ct.setKeybinding('$', ct.lastPage) - ct.setKeybinding('?', ct.openHelp) - return nil +// defaults +var shortcutkeys = map[string]string{ + "arrowup": "moveup", + "arrowdown": "movedown", + "arrowleft": "prevpage", + "arrowright": "nextpage", + "pagedown": "pagedown", + "pageup": "pageup", + "home": "movepagefirstrow", + "end": "movepagelastrow", + "enter": "openlink", + "esc": "quit", + "space": "openlink", + "ctrl+c": "quit", + "ctrl+d": "pagedown", + "ctrl+n": "nextpage", + "ctrl+p": "prevpage", + "ctrl+r": "refresh", + "ctrl+u": "pageup", + "alt+arrowup": "sortcolasc", + "alt+arrowdown": "sortcoldesc", + "alt+arrowleft": "sortleftcol", + "alt+arrowright": "sortrightcol", + "f1": "help", + "0": "movefirstpage", + "1": "sortcol1hchange", + "2": "sortcol24hchange", + "7": "sortcol7dchange", + "a": "sortcolavailablesupply", + "c": "togglerowchart", + "g": "movepagefirstrow", + "G": "movepagelastrow", + "h": "prevpage", + "H": "movepagevisiblefirstrow", + "j": "movedown", + "k": "moveup", + "l": "nextpage", + "L": "movepagevisiblelastrow", + "m": "sortcolmarketcap", + "M": "movepagevisiblemiddlerow", + "n": "sortcolname", + "p": "sortcolprice", + "r": "sortcolrank", + "s": "sortcolsymbol", + "t": "sortcoltotalsupply", + "u": "sortcollastupdated", + "v": "sortcol24hvolume", + "q": "quit", + "$": "movelastpage", + "?": "help", } -func (ct *Cointop) setKeybinding(key interface{}, callback func(g *gocui.Gui, v *gocui.View) error) { - var err error - switch t := key.(type) { - case gocui.Key: - err = ct.g.SetKeybinding("", t, gocui.ModNone, callback) - case rune: - err = ct.g.SetKeybinding("", t, gocui.ModNone, callback) +func (ct *Cointop) parseKeys(s string) (interface{}, gocui.Modifier) { + var key interface{} + mod := gocui.ModNone + split := strings.Split(s, "+") + if len(split) > 1 { + m := strings.ToLower(split[0]) + k := strings.ToLower(split[1]) + if m == "alt" { + mod = gocui.ModAlt + s = k + } else if m == "ctrl" { + switch k { + case "0": // not supported? + case "1": // not supported? + case "2": + key = gocui.KeyCtrl2 + case "3": + key = gocui.KeyCtrl3 + case "4": + key = gocui.KeyCtrl4 + case "5": + key = gocui.KeyCtrl5 + case "6": + key = gocui.KeyCtrl6 + case "7": + key = gocui.KeyCtrl7 + case "8": + key = gocui.KeyCtrl8 + case "9": // not supported? + case "a": + key = gocui.KeyCtrlA + case "b": + key = gocui.KeyCtrlB + case "c": + key = gocui.KeyCtrlC + case "d": + key = gocui.KeyCtrlD + case "e": + key = gocui.KeyCtrlE + case "f": + key = gocui.KeyCtrlF + case "g": + key = gocui.KeyCtrlG + case "h": + key = gocui.KeyCtrlH + case "i": + key = gocui.KeyCtrlI + case "j": + key = gocui.KeyCtrlJ + case "k": + key = gocui.KeyCtrlK + case "l": + key = gocui.KeyCtrlL + case "m": + key = gocui.KeyCtrlL + case "n": + key = gocui.KeyCtrlN + case "o": + key = gocui.KeyCtrlO + case "p": + key = gocui.KeyCtrlP + case "q": + key = gocui.KeyCtrlQ + case "r": + key = gocui.KeyCtrlR + case "s": + key = gocui.KeyCtrlS + case "t": + key = gocui.KeyCtrlT + case "u": + key = gocui.KeyCtrlU + case "v": + key = gocui.KeyCtrlV + case "w": + key = gocui.KeyCtrlW + case "x": + key = gocui.KeyCtrlX + case "y": + key = gocui.KeyCtrlY + case "z": + key = gocui.KeyCtrlZ + case "~": + key = gocui.KeyCtrlTilde + case "[": + key = gocui.KeyCtrlLsqBracket + case "]": + key = gocui.KeyCtrlRsqBracket + case "space": + key = gocui.KeyCtrlSpace + case "backslash": + key = gocui.KeyCtrlBackslash + case "underscore": + key = gocui.KeyCtrlUnderscore + } + return key, mod + } } - if err != nil { - log.Fatal(err) + + if len(s) == 1 { + r := []rune(s) + key = r[0] + return key, mod + } + + s = strings.ToLower(s) + switch s { + case "arrowup": + fallthrough + case "uparrow": + fallthrough + case "up": + key = gocui.KeyArrowUp + case "arrowdown": + fallthrough + case "downarrow": + fallthrough + case "down": + key = gocui.KeyArrowDown + case "arrowleft": + fallthrough + case "leftarrow": + fallthrough + case "left": + key = gocui.KeyArrowLeft + case "arrowright": + fallthrough + case "rightarrow": + fallthrough + case "right": + key = gocui.KeyArrowRight + case "enter": + fallthrough + case "return": + key = gocui.KeyEnter + case "space": + fallthrough + case "spacebar": + key = gocui.KeySpace + case "esc": + fallthrough + case "escape": + key = gocui.KeyEsc + case "f1": + key = gocui.KeyF1 + case "f2": + key = gocui.KeyF2 + case "f3": + key = gocui.KeyF3 + case "f4": + key = gocui.KeyF4 + case "f5": + key = gocui.KeyF5 + case "f6": + key = gocui.KeyF6 + case "f7": + key = gocui.KeyF7 + case "f8": + key = gocui.KeyF8 + case "f9": + key = gocui.KeyF9 + case "tab": + key = gocui.KeyTab + case "pageup": + fallthrough + case "pgup": + key = gocui.KeyPgup + case "pagedown": + fallthrough + case "pgdown": + key = gocui.KeyPgdn + case "home": + key = gocui.KeyHome + case "end": + key = gocui.KeyEnd } + + return key, mod } -func (ct *Cointop) setKeybindingMod(key interface{}, mod gocui.Modifier, callback func(g *gocui.Gui, v *gocui.View) error) { +func (ct *Cointop) keybindings(g *gocui.Gui) error { + for k, v := range shortcutkeys { + var fn func(g *gocui.Gui, v *gocui.View) error + key, mod := ct.parseKeys(k) + switch v { + case "moveup": + fn = ct.cursorUp + case "movedown": + fn = ct.cursorDown + case "prevpage": + fn = ct.prevPage + case "nextpage": + fn = ct.nextPage + case "pagedown": + fn = ct.pageDown + case "pageup": + fn = ct.pageUp + case "sortcolsymbol": + fn = ct.sortfn("symbol", false) + case "movepagefirstrow": + fn = ct.navigateFirstLine + case "movepagelastrow": + fn = ct.navigateLastLine + case "openlink": + fn = ct.openLink + case "refresh": + fn = ct.refresh + case "sortcolasc": + fn = ct.sortAsc + case "sortcoldesc": + fn = ct.sortDesc + case "sortleftcol": + fn = ct.sortPrevCol + case "sortrightcol": + fn = ct.sortNextCol + case "help": + fn = ct.openHelp + case "movefirstpage": + fn = ct.firstPage + case "sortcol1hchange": + fn = ct.sortfn("1hchange", true) + case "sortcol24hchange": + fn = ct.sortfn("24hchange", true) + case "sortcol7dchange": + fn = ct.sortfn("7dchange", true) + case "sortcolavailablesupply": + fn = ct.sortfn("availablesupply", true) + case "togglerowchart": + fn = ct.toggleCoinChart + case "movepagevisiblefirstrow": + fn = ct.navigatePageFirstLine + case "movepagevisiblelastrow": + fn = ct.navigatePageLastLine + case "sortcolmarketcap": + fn = ct.sortfn("marketcap", true) + case "movepagevisiblemiddlerow": + fn = ct.navigatePageMiddleLine + case "sortcolname": + fn = ct.sortfn("name", true) + case "sortcolprice": + fn = ct.sortfn("price", true) + case "sortcolrank": + fn = ct.sortfn("rank", false) + case "sortcoltotalsupply": + fn = ct.sortfn("totalsupply", true) + case "sortcollastupdated": + fn = ct.sortfn("lastupdated", true) + case "sortcol24hvolume": + fn = ct.sortfn("24hvolume", true) + case "movelastpage": + fn = ct.lastPage + case "quit": + fn = ct.quit + default: + fn = keynoop + } + + ct.setKeybindingMod(key, mod, fn) + } + + return nil +} + +func (ct *Cointop) setKeybindingMod(key interface{}, mod gocui.Modifier, callback func(g *gocui.Gui, v *gocui.View) error) error { var err error switch t := key.(type) { case gocui.Key: @@ -79,7 +328,9 @@ func (ct *Cointop) setKeybindingMod(key interface{}, mod gocui.Modifier, callbac case rune: err = ct.g.SetKeybinding("", t, mod, callback) } - if err != nil { - log.Fatal(err) - } + return err +} + +func keynoop(g *gocui.Gui, v *gocui.View) error { + return nil }