|
|
|
@ -167,166 +167,174 @@ func (ct *Cointop) ParseKeys(s string) (interface{}, gocui.Modifier) {
|
|
|
|
|
return key, mod
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Keybindings sets keyboard shortcut key bindings
|
|
|
|
|
func (ct *Cointop) Keybindings(g *gocui.Gui) error {
|
|
|
|
|
// SetKeybindingAction maps a shortcut key to an action
|
|
|
|
|
func (ct *Cointop) SetKeybindingAction(shortcutKey string, action string) error {
|
|
|
|
|
if shortcutKey == "" {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
action = strings.TrimSpace(strings.ToLower(action))
|
|
|
|
|
var fn func(g *gocui.Gui, v *gocui.View) error
|
|
|
|
|
key, mod := ct.ParseKeys(shortcutKey)
|
|
|
|
|
view := "table"
|
|
|
|
|
switch action {
|
|
|
|
|
case "move_up":
|
|
|
|
|
fn = ct.Keyfn(ct.CursorUp)
|
|
|
|
|
case "move_down":
|
|
|
|
|
fn = ct.Keyfn(ct.CursorDown)
|
|
|
|
|
case "previous_page":
|
|
|
|
|
fn = ct.handleHkey(key)
|
|
|
|
|
case "next_page":
|
|
|
|
|
fn = ct.Keyfn(ct.NextPage)
|
|
|
|
|
case "page_down":
|
|
|
|
|
fn = ct.Keyfn(ct.PageDown)
|
|
|
|
|
case "page_up":
|
|
|
|
|
fn = ct.Keyfn(ct.PageUp)
|
|
|
|
|
case "sort_column_symbol":
|
|
|
|
|
fn = ct.Sortfn("symbol", false)
|
|
|
|
|
case "move_to_page_first_row":
|
|
|
|
|
fn = ct.Keyfn(ct.NavigateFirstLine)
|
|
|
|
|
case "move_to_page_last_row":
|
|
|
|
|
fn = ct.Keyfn(ct.NavigateLastLine)
|
|
|
|
|
case "open_link":
|
|
|
|
|
fn = ct.Keyfn(ct.OpenLink)
|
|
|
|
|
case "refresh":
|
|
|
|
|
fn = ct.Keyfn(ct.Refresh)
|
|
|
|
|
case "sort_column_asc":
|
|
|
|
|
fn = ct.Keyfn(ct.SortAsc)
|
|
|
|
|
case "sort_column_desc":
|
|
|
|
|
fn = ct.Keyfn(ct.SortDesc)
|
|
|
|
|
case "sort_left_column":
|
|
|
|
|
fn = ct.Keyfn(ct.SortPrevCol)
|
|
|
|
|
case "sort_right_column":
|
|
|
|
|
fn = ct.Keyfn(ct.SortNextCol)
|
|
|
|
|
case "help", "toggle_show_help":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleHelp)
|
|
|
|
|
view = ""
|
|
|
|
|
case "show_help":
|
|
|
|
|
fn = ct.Keyfn(ct.ShowHelp)
|
|
|
|
|
view = ""
|
|
|
|
|
case "hide_help":
|
|
|
|
|
fn = ct.Keyfn(ct.HideHelp)
|
|
|
|
|
view = "help"
|
|
|
|
|
case "first_page":
|
|
|
|
|
fn = ct.Keyfn(ct.FirstPage)
|
|
|
|
|
case "sort_column_1h_change":
|
|
|
|
|
fn = ct.Sortfn("1h_change", true)
|
|
|
|
|
case "sort_column_24h_change":
|
|
|
|
|
fn = ct.Sortfn("24h_change", true)
|
|
|
|
|
case "sort_column_7d_change":
|
|
|
|
|
fn = ct.Sortfn("7d_change", true)
|
|
|
|
|
case "sort_column_30d_change":
|
|
|
|
|
fn = ct.Sortfn("30d_change", true)
|
|
|
|
|
case "sort_column_1y_change":
|
|
|
|
|
fn = ct.Sortfn("1y_change", true)
|
|
|
|
|
case "sort_column_available_supply":
|
|
|
|
|
fn = ct.Sortfn("available_supply", true)
|
|
|
|
|
case "toggle_row_chart":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleCoinChart)
|
|
|
|
|
case "move_to_page_visible_first_row":
|
|
|
|
|
fn = ct.Keyfn(ct.NavigatePageFirstLine)
|
|
|
|
|
case "move_to_page_visible_last_row":
|
|
|
|
|
fn = ct.Keyfn(ct.navigatePageLastLine)
|
|
|
|
|
case "sort_column_market_cap":
|
|
|
|
|
fn = ct.Sortfn("market_cap", true)
|
|
|
|
|
case "move_to_page_visible_middle_row":
|
|
|
|
|
fn = ct.Keyfn(ct.NavigatePageMiddleLine)
|
|
|
|
|
case "scroll_left":
|
|
|
|
|
fn = ct.Keyfn(ct.TableScrollLeft)
|
|
|
|
|
case "scroll_right":
|
|
|
|
|
fn = ct.Keyfn(ct.TableScrollRight)
|
|
|
|
|
case "sort_column_name":
|
|
|
|
|
fn = ct.Sortfn("name", false)
|
|
|
|
|
case "sort_column_price":
|
|
|
|
|
fn = ct.Sortfn("price", true)
|
|
|
|
|
case "sort_column_rank":
|
|
|
|
|
fn = ct.Sortfn("rank", false)
|
|
|
|
|
case "sort_column_total_supply":
|
|
|
|
|
fn = ct.Sortfn("total_supply", true)
|
|
|
|
|
case "sort_column_last_updated":
|
|
|
|
|
fn = ct.Sortfn("last_updated", true)
|
|
|
|
|
case "sort_column_24h_volume":
|
|
|
|
|
fn = ct.Sortfn("24h_volume", true)
|
|
|
|
|
case "sort_column_balance":
|
|
|
|
|
fn = ct.Sortfn("balance", true)
|
|
|
|
|
case "sort_column_holdings":
|
|
|
|
|
fn = ct.Sortfn("holdings", true)
|
|
|
|
|
case "sort_column_percent_holdings":
|
|
|
|
|
fn = ct.Sortfn("percent_holdings", true)
|
|
|
|
|
case "last_page":
|
|
|
|
|
fn = ct.Keyfn(ct.LastPage)
|
|
|
|
|
case "open_search":
|
|
|
|
|
fn = ct.Keyfn(ct.openSearch)
|
|
|
|
|
view = ""
|
|
|
|
|
case "toggle_price_alerts":
|
|
|
|
|
fn = ct.Keyfn(ct.TogglePriceAlerts)
|
|
|
|
|
case "toggle_favorite":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleFavorite)
|
|
|
|
|
case "toggle_favorites":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleFavorites)
|
|
|
|
|
case "toggle_show_favorites":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleShowFavorites)
|
|
|
|
|
case "save":
|
|
|
|
|
fn = ct.Keyfn(ct.Save)
|
|
|
|
|
case "quit":
|
|
|
|
|
fn = ct.Keyfn(ct.Quit)
|
|
|
|
|
view = ""
|
|
|
|
|
case "quit_view":
|
|
|
|
|
fn = ct.Keyfn(ct.QuitView)
|
|
|
|
|
case "next_chart_range":
|
|
|
|
|
fn = ct.Keyfn(ct.NextChartRange)
|
|
|
|
|
case "previous_chart_range":
|
|
|
|
|
fn = ct.Keyfn(ct.PrevChartRange)
|
|
|
|
|
case "first_chart_range":
|
|
|
|
|
fn = ct.Keyfn(ct.FirstChartRange)
|
|
|
|
|
case "last_chart_range":
|
|
|
|
|
fn = ct.Keyfn(ct.LastChartRange)
|
|
|
|
|
case "toggle_show_currency_convert_menu":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleConvertMenu)
|
|
|
|
|
case "show_currency_convert_menu":
|
|
|
|
|
fn = ct.Keyfn(ct.ShowConvertMenu)
|
|
|
|
|
case "hide_currency_convert_menu":
|
|
|
|
|
fn = ct.Keyfn(ct.HideConvertMenu)
|
|
|
|
|
view = "convertmenu"
|
|
|
|
|
case "toggle_portfolio":
|
|
|
|
|
fn = ct.Keyfn(ct.TogglePortfolio)
|
|
|
|
|
case "toggle_show_portfolio":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleShowPortfolio)
|
|
|
|
|
case "show_portfolio_edit_menu":
|
|
|
|
|
fn = ct.Keyfn(ct.TogglePortfolioUpdateMenu)
|
|
|
|
|
case "show_price_alert_edit_menu":
|
|
|
|
|
fn = ct.Keyfn(ct.ShowPriceAlertsUpdateMenu)
|
|
|
|
|
case "show_price_alert_add_menu":
|
|
|
|
|
fn = ct.Keyfn(ct.ShowPriceAlertsAddMenu)
|
|
|
|
|
case "toggle_table_fullscreen":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleTableFullscreen)
|
|
|
|
|
view = ""
|
|
|
|
|
case "toggle_chart_fullscreen":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleChartFullscreen)
|
|
|
|
|
view = ""
|
|
|
|
|
case "enlarge_chart":
|
|
|
|
|
fn = ct.Keyfn(ct.EnlargeChart)
|
|
|
|
|
case "shorten_chart":
|
|
|
|
|
fn = ct.Keyfn(ct.ShortenChart)
|
|
|
|
|
case "move_down_or_next_page":
|
|
|
|
|
fn = ct.Keyfn(ct.CursorDownOrNextPage)
|
|
|
|
|
case "move_up_or_previous_page":
|
|
|
|
|
fn = ct.Keyfn(ct.CursorUpOrPreviousPage)
|
|
|
|
|
default:
|
|
|
|
|
fn = ct.Keyfn(ct.Noop)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ct.SetKeybindingMod(key, mod, fn, view)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SetKeybindings sets keyboard shortcut key bindings
|
|
|
|
|
func (ct *Cointop) SetKeybindings() error {
|
|
|
|
|
for k, v := range ct.State.shortcutKeys {
|
|
|
|
|
if k == "" {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
v = strings.TrimSpace(strings.ToLower(v))
|
|
|
|
|
var fn func(g *gocui.Gui, v *gocui.View) error
|
|
|
|
|
key, mod := ct.ParseKeys(k)
|
|
|
|
|
view := "table"
|
|
|
|
|
switch v {
|
|
|
|
|
case "move_up":
|
|
|
|
|
fn = ct.Keyfn(ct.CursorUp)
|
|
|
|
|
case "move_down":
|
|
|
|
|
fn = ct.Keyfn(ct.CursorDown)
|
|
|
|
|
case "previous_page":
|
|
|
|
|
fn = ct.handleHkey(key)
|
|
|
|
|
case "next_page":
|
|
|
|
|
fn = ct.Keyfn(ct.NextPage)
|
|
|
|
|
case "page_down":
|
|
|
|
|
fn = ct.Keyfn(ct.PageDown)
|
|
|
|
|
case "page_up":
|
|
|
|
|
fn = ct.Keyfn(ct.PageUp)
|
|
|
|
|
case "sort_column_symbol":
|
|
|
|
|
fn = ct.Sortfn("symbol", false)
|
|
|
|
|
case "move_to_page_first_row":
|
|
|
|
|
fn = ct.Keyfn(ct.NavigateFirstLine)
|
|
|
|
|
case "move_to_page_last_row":
|
|
|
|
|
fn = ct.Keyfn(ct.NavigateLastLine)
|
|
|
|
|
case "open_link":
|
|
|
|
|
fn = ct.Keyfn(ct.OpenLink)
|
|
|
|
|
case "refresh":
|
|
|
|
|
fn = ct.Keyfn(ct.Refresh)
|
|
|
|
|
case "sort_column_asc":
|
|
|
|
|
fn = ct.Keyfn(ct.SortAsc)
|
|
|
|
|
case "sort_column_desc":
|
|
|
|
|
fn = ct.Keyfn(ct.SortDesc)
|
|
|
|
|
case "sort_left_column":
|
|
|
|
|
fn = ct.Keyfn(ct.SortPrevCol)
|
|
|
|
|
case "sort_right_column":
|
|
|
|
|
fn = ct.Keyfn(ct.SortNextCol)
|
|
|
|
|
case "help", "toggle_show_help":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleHelp)
|
|
|
|
|
view = ""
|
|
|
|
|
case "show_help":
|
|
|
|
|
fn = ct.Keyfn(ct.ShowHelp)
|
|
|
|
|
view = ""
|
|
|
|
|
case "hide_help":
|
|
|
|
|
fn = ct.Keyfn(ct.HideHelp)
|
|
|
|
|
view = "help"
|
|
|
|
|
case "first_page":
|
|
|
|
|
fn = ct.Keyfn(ct.FirstPage)
|
|
|
|
|
case "sort_column_1h_change":
|
|
|
|
|
fn = ct.Sortfn("1h_change", true)
|
|
|
|
|
case "sort_column_24h_change":
|
|
|
|
|
fn = ct.Sortfn("24h_change", true)
|
|
|
|
|
case "sort_column_7d_change":
|
|
|
|
|
fn = ct.Sortfn("7d_change", true)
|
|
|
|
|
case "sort_column_30d_change":
|
|
|
|
|
fn = ct.Sortfn("30d_change", true)
|
|
|
|
|
case "sort_column_1y_change":
|
|
|
|
|
fn = ct.Sortfn("1y_change", true)
|
|
|
|
|
case "sort_column_available_supply":
|
|
|
|
|
fn = ct.Sortfn("available_supply", true)
|
|
|
|
|
case "toggle_row_chart":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleCoinChart)
|
|
|
|
|
case "move_to_page_visible_first_row":
|
|
|
|
|
fn = ct.Keyfn(ct.NavigatePageFirstLine)
|
|
|
|
|
case "move_to_page_visible_last_row":
|
|
|
|
|
fn = ct.Keyfn(ct.navigatePageLastLine)
|
|
|
|
|
case "sort_column_market_cap":
|
|
|
|
|
fn = ct.Sortfn("market_cap", true)
|
|
|
|
|
case "move_to_page_visible_middle_row":
|
|
|
|
|
fn = ct.Keyfn(ct.NavigatePageMiddleLine)
|
|
|
|
|
case "scroll_left":
|
|
|
|
|
fn = ct.Keyfn(ct.TableScrollLeft)
|
|
|
|
|
case "scroll_right":
|
|
|
|
|
fn = ct.Keyfn(ct.TableScrollRight)
|
|
|
|
|
case "sort_column_name":
|
|
|
|
|
fn = ct.Sortfn("name", false)
|
|
|
|
|
case "sort_column_price":
|
|
|
|
|
fn = ct.Sortfn("price", true)
|
|
|
|
|
case "sort_column_rank":
|
|
|
|
|
fn = ct.Sortfn("rank", false)
|
|
|
|
|
case "sort_column_total_supply":
|
|
|
|
|
fn = ct.Sortfn("total_supply", true)
|
|
|
|
|
case "sort_column_last_updated":
|
|
|
|
|
fn = ct.Sortfn("last_updated", true)
|
|
|
|
|
case "sort_column_24h_volume":
|
|
|
|
|
fn = ct.Sortfn("24h_volume", true)
|
|
|
|
|
case "sort_column_balance":
|
|
|
|
|
fn = ct.Sortfn("balance", true)
|
|
|
|
|
case "sort_column_holdings":
|
|
|
|
|
fn = ct.Sortfn("holdings", true)
|
|
|
|
|
case "sort_column_percent_holdings":
|
|
|
|
|
fn = ct.Sortfn("percent_holdings", true)
|
|
|
|
|
case "last_page":
|
|
|
|
|
fn = ct.Keyfn(ct.LastPage)
|
|
|
|
|
case "open_search":
|
|
|
|
|
fn = ct.Keyfn(ct.openSearch)
|
|
|
|
|
view = ""
|
|
|
|
|
case "toggle_price_alerts":
|
|
|
|
|
fn = ct.Keyfn(ct.TogglePriceAlerts)
|
|
|
|
|
case "toggle_favorite":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleFavorite)
|
|
|
|
|
case "toggle_favorites":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleFavorites)
|
|
|
|
|
case "toggle_show_favorites":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleShowFavorites)
|
|
|
|
|
case "save":
|
|
|
|
|
fn = ct.Keyfn(ct.Save)
|
|
|
|
|
case "quit":
|
|
|
|
|
fn = ct.Keyfn(ct.Quit)
|
|
|
|
|
view = ""
|
|
|
|
|
case "quit_view":
|
|
|
|
|
fn = ct.Keyfn(ct.QuitView)
|
|
|
|
|
case "next_chart_range":
|
|
|
|
|
fn = ct.Keyfn(ct.NextChartRange)
|
|
|
|
|
case "previous_chart_range":
|
|
|
|
|
fn = ct.Keyfn(ct.PrevChartRange)
|
|
|
|
|
case "first_chart_range":
|
|
|
|
|
fn = ct.Keyfn(ct.FirstChartRange)
|
|
|
|
|
case "last_chart_range":
|
|
|
|
|
fn = ct.Keyfn(ct.LastChartRange)
|
|
|
|
|
case "toggle_show_currency_convert_menu":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleConvertMenu)
|
|
|
|
|
case "show_currency_convert_menu":
|
|
|
|
|
fn = ct.Keyfn(ct.ShowConvertMenu)
|
|
|
|
|
case "hide_currency_convert_menu":
|
|
|
|
|
fn = ct.Keyfn(ct.HideConvertMenu)
|
|
|
|
|
view = "convertmenu"
|
|
|
|
|
case "toggle_portfolio":
|
|
|
|
|
fn = ct.Keyfn(ct.TogglePortfolio)
|
|
|
|
|
case "toggle_show_portfolio":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleShowPortfolio)
|
|
|
|
|
case "show_portfolio_edit_menu":
|
|
|
|
|
fn = ct.Keyfn(ct.TogglePortfolioUpdateMenu)
|
|
|
|
|
case "show_price_alert_edit_menu":
|
|
|
|
|
fn = ct.Keyfn(ct.ShowPriceAlertsUpdateMenu)
|
|
|
|
|
case "show_price_alert_add_menu":
|
|
|
|
|
fn = ct.Keyfn(ct.ShowPriceAlertsAddMenu)
|
|
|
|
|
case "toggle_table_fullscreen":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleTableFullscreen)
|
|
|
|
|
view = ""
|
|
|
|
|
case "toggle_chart_fullscreen":
|
|
|
|
|
fn = ct.Keyfn(ct.ToggleChartFullscreen)
|
|
|
|
|
view = ""
|
|
|
|
|
case "enlarge_chart":
|
|
|
|
|
fn = ct.Keyfn(ct.EnlargeChart)
|
|
|
|
|
case "shorten_chart":
|
|
|
|
|
fn = ct.Keyfn(ct.ShortenChart)
|
|
|
|
|
case "move_down_or_next_page":
|
|
|
|
|
fn = ct.Keyfn(ct.CursorDownOrNextPage)
|
|
|
|
|
case "move_up_or_previous_page":
|
|
|
|
|
fn = ct.Keyfn(ct.CursorUpOrPreviousPage)
|
|
|
|
|
default:
|
|
|
|
|
fn = ct.Keyfn(ct.Noop)
|
|
|
|
|
if err := ct.SetKeybindingAction(k, v); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ct.SetKeybindingMod(key, mod, fn, view)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// keys to force quit
|
|
|
|
@ -352,6 +360,9 @@ func (ct *Cointop) Keybindings(g *gocui.Gui) error {
|
|
|
|
|
// keys to update portfolio holdings
|
|
|
|
|
ct.SetKeybindingMod(gocui.KeyEnter, gocui.ModNone, ct.Keyfn(ct.EnterKeyPressHandler), ct.Views.Input.Name())
|
|
|
|
|
|
|
|
|
|
key, mod := ct.ParseKeys("/")
|
|
|
|
|
ct.DeleteKeybindingMod(key, mod, "")
|
|
|
|
|
|
|
|
|
|
// mouse events
|
|
|
|
|
ct.SetKeybindingMod(gocui.MouseRelease, gocui.ModNone, ct.Keyfn(ct.MouseRelease), "")
|
|
|
|
|
ct.SetKeybindingMod(gocui.MouseLeft, gocui.ModNone, ct.Keyfn(ct.MouseLeftClick), "")
|
|
|
|
@ -382,10 +393,31 @@ func (ct *Cointop) SetKeybindingMod(key interface{}, mod gocui.Modifier, callbac
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DeleteKeybinding ...
|
|
|
|
|
func (ct *Cointop) DeleteKeybinding(shortcutKey string) error {
|
|
|
|
|
key, mod := ct.ParseKeys(shortcutKey)
|
|
|
|
|
return ct.DeleteKeybindingMod(key, mod, "")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DeleteKeybindingMod ...
|
|
|
|
|
func (ct *Cointop) DeleteKeybindingMod(key interface{}, mod gocui.Modifier, view string) error {
|
|
|
|
|
var err error
|
|
|
|
|
switch t := key.(type) {
|
|
|
|
|
case gocui.Key:
|
|
|
|
|
err = ct.g.DeleteKeybinding(view, t, mod)
|
|
|
|
|
case rune:
|
|
|
|
|
err = ct.g.DeleteKeybinding(view, t, mod)
|
|
|
|
|
}
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Keyfn returns the keybinding function as a wrapped gocui view function
|
|
|
|
|
func (ct *Cointop) Keyfn(fn func() error) func(g *gocui.Gui, v *gocui.View) error {
|
|
|
|
|
return func(g *gocui.Gui, v *gocui.View) error {
|
|
|
|
|
return fn()
|
|
|
|
|
if fn != nil {
|
|
|
|
|
return fn()
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|