Skip to content

Commit

Permalink
add key bindings map support
Browse files Browse the repository at this point in the history
  • Loading branch information
mylxsw committed Apr 22, 2019
1 parent dc19c7e commit 8d55df1
Showing 1 changed file with 100 additions and 44 deletions.
144 changes: 100 additions & 44 deletions gui.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,58 @@ import (
"fmt"
"github.com/gdamore/tcell"
"github.com/rivo/tview"
"strings"
"time"
)

type KeyBindings map[string][]tcell.Key

var keyBindings = KeyBindings{
"search": {tcell.KeyF2, tcell.KeyCtrlS},
"keys": {tcell.KeyF3, tcell.KeyCtrlK},
"key_list_value": {tcell.KeyF6, tcell.KeyCtrlH},
"key_string_value": {tcell.KeyF7, tcell.KeyCtrlA},
"key_hash": {tcell.KeyF6, tcell.KeyCtrlH},
"output": {tcell.KeyF9, tcell.KeyCtrlO},
"command": {tcell.KeyF1, tcell.KeyCtrlN},
"command_focus": {tcell.KeyF4, tcell.KeyCtrlF},
"command_result": {tcell.KeyF5, tcell.KeyCtrlR},
"quit": {tcell.KeyEsc, tcell.KeyCtrlQ},
"switch_focus": {tcell.KeyTab},
}

func (kb KeyBindings) SearchKey(k tcell.Key) string {
for name, bind := range kb {
for _, b := range bind {
if b == k {
return name
}
}
}

return ""
}

func (kb KeyBindings) KeyID(key string) string {
return key
}

func (kb KeyBindings) Keys(key string) []tcell.Key {
return kb[key]
}

func (kb KeyBindings) Name(key string) string {
keyNames := make([]string, 0)
for _, k := range kb[key] {
keyNames = append(keyNames, tcell.KeyNames[k])
}

return strings.Join(keyNames, ", ")
}

type primitiveKey struct {
Primitive tview.Primitive
Key tcell.Key
Key string
}

type OutputMessage struct {
Expand Down Expand Up @@ -96,12 +142,18 @@ func NewRedisGli(redisClient RedisClient, maxKeyLimit int64, version string, git
AddItem(gli.leftPanel, 0, 3, false).
AddItem(gli.rightPanel, 0, 8, false)

gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.searchPanel, Key: tcell.KeyF2})
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.keyItemsPanel, Key: tcell.KeyF3})
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.searchPanel, Key: keyBindings.KeyID("search")})
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.keyItemsPanel, Key: keyBindings.KeyID("keys")})

gli.app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
switch event.Key() {
case tcell.KeyTab:

if gli.config.Debug {
gli.outputChan <- OutputMessage{Message: fmt.Sprintf("Key %s pressed", tcell.KeyNames[event.Key()])}
}

name := keyBindings.SearchKey(event.Key())
switch name {
case "switch_focus":
nextFocusIndex := gli.currentFocusIndex + 1
if nextFocusIndex > len(gli.focusPrimitives)-1 {
nextFocusIndex = 0
Expand All @@ -111,9 +163,9 @@ func NewRedisGli(redisClient RedisClient, maxKeyLimit int64, version string, git
gli.currentFocusIndex = nextFocusIndex

return nil
case tcell.KeyEsc:
case "quit":
gli.app.Stop()
case tcell.KeyF1:
case "command":
if gli.commandMode {
gli.commandMode = false
gli.redrawRightPanel(gli.mainPanel)
Expand All @@ -132,7 +184,7 @@ func NewRedisGli(redisClient RedisClient, maxKeyLimit int64, version string, git
}
default:
for i, pv := range gli.focusPrimitives {
if pv.Key == event.Key() {
if pv.Key == name {
gli.app.SetFocus(pv.Primitive)
gli.currentFocusIndex = i
break
Expand All @@ -146,19 +198,6 @@ func NewRedisGli(redisClient RedisClient, maxKeyLimit int64, version string, git
return gli
}

func (gli *RedisGli) redrawRightPanel(center tview.Primitive) {
gli.rightPanel.RemoveItem(gli.metaPanel).
RemoveItem(gli.outputPanel).
RemoveItem(gli.mainPanel).
RemoveItem(gli.commandPanel).
RemoveItem(gli.helpPanel)

gli.rightPanel.AddItem(gli.helpPanel, 5, 1, false).
AddItem(gli.metaPanel, 4, 1, false).
AddItem(center, 0, 7, false).
AddItem(gli.outputPanel, 8, 1, false)
}

// Start create the ui and start the program
func (gli *RedisGli) Start() error {
go gli.app.QueueUpdateDraw(func() {
Expand Down Expand Up @@ -217,6 +256,19 @@ func (gli *RedisGli) Start() error {
return gli.app.SetRoot(gli.pages, true).Run()
}

func (gli *RedisGli) redrawRightPanel(center tview.Primitive) {
gli.rightPanel.RemoveItem(gli.metaPanel).
RemoveItem(gli.outputPanel).
RemoveItem(gli.mainPanel).
RemoveItem(gli.commandPanel).
RemoveItem(gli.helpPanel)

gli.rightPanel.AddItem(gli.helpPanel, 5, 1, false).
AddItem(gli.metaPanel, 4, 1, false).
AddItem(center, 0, 7, false).
AddItem(gli.outputPanel, 8, 1, false)
}

func (gli *RedisGli) createSummaryPanel() *tview.TextView {
panel := tview.NewTextView()
panel.SetBorder(true).SetTitle(" Info ")
Expand All @@ -229,10 +281,9 @@ func (gli *RedisGli) keyItemsFormat(index int, key string) string {

func (gli *RedisGli) createCommandPanel() *tview.Flex {
flex := tview.NewFlex().SetDirection(tview.FlexRow)
// flex.SetBorder(true).SetTitle(" Commands (F1) ").SetBackgroundColor(tcell.Color16)

resultPanel := tview.NewTextView()
resultPanel.SetBorder(true).SetTitle(" Results (F5) ")
resultPanel.SetBorder(true).SetTitle(fmt.Sprintf(" Results (%s) ", keyBindings.Name("command_result")))

formPanel := tview.NewInputField().SetLabel("Command ")
var locked bool
Expand All @@ -246,8 +297,8 @@ func (gli *RedisGli) createCommandPanel() *tview.Flex {
gli.pages.AddPage(
pageID,
tview.NewModal().
SetText("之前的命令正在处理中,请稍候...").
AddButtons([]string{"确定"}).
SetText("Other command is processing, please wait...").
AddButtons([]string{"OK"}).
SetDoneFunc(func(buttonIndex int, buttonLabel string) {
gli.pages.HidePage(pageID).RemovePage(pageID)
gli.app.SetFocus(formPanel)
Expand Down Expand Up @@ -283,13 +334,13 @@ func (gli *RedisGli) createCommandPanel() *tview.Flex {
formPanel.SetText("")
})
// formPanel.SetBackgroundColor(tcell.ColorOrange)
formPanel.SetBorder(true).SetTitle(" Commands (F4) ")
formPanel.SetBorder(true).SetTitle(fmt.Sprintf(" Commands (%s) ", keyBindings.Name("command_focus")))

gli.commandFormPanel = formPanel
gli.commandResultPanel = resultPanel

gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.commandFormPanel, Key: tcell.KeyF4})
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.commandResultPanel, Key: tcell.KeyF5})
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.commandFormPanel, Key: keyBindings.KeyID("command_focus")})
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.commandResultPanel, Key: keyBindings.KeyID("command_result")})

flex.AddItem(formPanel, 4, 0, false).
AddItem(resultPanel, 0, 1, false)
Expand All @@ -299,7 +350,7 @@ func (gli *RedisGli) createCommandPanel() *tview.Flex {

// createSearchPanel create search panel
func (gli *RedisGli) createSearchPanel() *tview.InputField {
searchArea := tview.NewInputField().SetLabel(" Key ")
searchArea := tview.NewInputField().SetLabel(" KeyID ")
searchArea.SetDoneFunc(func(key tcell.Key) {
if key != tcell.KeyEnter {
return
Expand Down Expand Up @@ -327,14 +378,14 @@ func (gli *RedisGli) createSearchPanel() *tview.InputField {
gli.keyItemsPanel.AddItem(gli.keyItemsFormat(i, k), "", 0, gli.itemSelectedHandler(i, k))
}
})
searchArea.SetBorder(true).SetTitle(" Search (F2) ")
searchArea.SetBorder(true).SetTitle(fmt.Sprintf(" Search (%s) ", keyBindings.Name("search")))
return searchArea
}

// createKeyItemsPanel create key items panel
func (gli *RedisGli) createKeyItemsPanel() *tview.List {
keyItemsList := tview.NewList().ShowSecondaryText(false)
keyItemsList.SetBorder(true).SetTitle(" Keys (F3) ")
keyItemsList.SetBorder(true).SetTitle(fmt.Sprintf(" Keys (%s) ", keyBindings.Name("keys")))
return keyItemsList
}

Expand Down Expand Up @@ -371,9 +422,9 @@ func (gli *RedisGli) createMainPanel() *tview.Flex {
// createOutputPanel create a panel for outputFunc
func (gli *RedisGli) createOutputPanel() *tview.List {
outputArea := tview.NewList().ShowSecondaryText(false)
outputArea.SetBorder(true).SetTitle(" Output (F9) ")
outputArea.SetBorder(true).SetTitle(fmt.Sprintf(" Output (%s) ", keyBindings.Name("output")))

gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: outputArea, Key: tcell.KeyF9})
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: outputArea, Key: keyBindings.KeyID("output")})

return outputArea
}
Expand All @@ -387,7 +438,12 @@ func (gli *RedisGli) createHelpPanel() *tview.Flex {
helpPanel.AddItem(gli.helpServerInfoPanel, 2, 1, false)

gli.helpMessagePanel = tview.NewTextView()
gli.helpMessagePanel.SetTextColor(tcell.ColorOrange).SetText(" ❈ Press F1 to switch between command panel and value panel, Esc to quit")
gli.helpMessagePanel.SetTextColor(tcell.ColorOrange).SetText(fmt.Sprintf(
" ❈ %s - open command panel, %s - switch focus, %s - quit",
keyBindings.Name("command"),
keyBindings.Name("switch_focus"),
keyBindings.Name("quit"),
))

helpPanel.AddItem(gli.helpMessagePanel, 1, 1, false)

Expand All @@ -399,13 +455,13 @@ func (gli *RedisGli) createKeySelectedHandler() func(index int, key string) func

// 用于KV展示的视图
mainStringView := tview.NewTextView()
mainStringView.SetBorder(true).SetTitle(" Value (F7) ")
mainStringView.SetBorder(true).SetTitle(fmt.Sprintf(" Value (%s) ", keyBindings.Name("key_string_value")))

mainHashView := tview.NewList().ShowSecondaryText(false)
mainHashView.SetBorder(true).SetTitle(" Hash Key (F6) ")
mainHashView.SetBorder(true).SetTitle(fmt.Sprintf(" Hash KeyID (%s) ", keyBindings.Name("key_hash")))

mainListView := tview.NewList().ShowSecondaryText(false).SetSecondaryTextColor(tcell.ColorOrangeRed)
mainListView.SetBorder(true).SetTitle(" Value (F6) ")
mainListView.SetBorder(true).SetTitle(fmt.Sprintf(" Value (%s) ", keyBindings.Name("key_list_value")))

return func(index int, key string) func() {
return func() {
Expand Down Expand Up @@ -447,7 +503,7 @@ func (gli *RedisGli) createKeySelectedHandler() func(index int, key string) func
}

gli.mainPanel.AddItem(mainStringView.SetText(fmt.Sprintf(" %s", result)), 0, 1, false)
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: mainStringView, Key: tcell.KeyF7})
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: mainStringView, Key: keyBindings.KeyID("key_string_value")})
case "list":
values, err := gli.redisClient.LRange(key, 0, 1000).Result()
if err != nil {
Expand All @@ -460,7 +516,7 @@ func (gli *RedisGli) createKeySelectedHandler() func(index int, key string) func
}

gli.mainPanel.AddItem(mainListView, 0, 1, false)
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: mainListView, Key: tcell.KeyF6})
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: mainListView, Key: keyBindings.KeyID("key_list_value")})

case "set":
values, err := gli.redisClient.SMembers(key).Result()
Expand All @@ -474,7 +530,7 @@ func (gli *RedisGli) createKeySelectedHandler() func(index int, key string) func
}

gli.mainPanel.AddItem(mainListView, 0, 1, false)
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: mainListView, Key: tcell.KeyF6})
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: mainListView, Key: keyBindings.KeyID("key_list_value")})

case "zset":
values, err := gli.redisClient.ZRangeWithScores(key, 0, 1000).Result()
Expand All @@ -492,7 +548,7 @@ func (gli *RedisGli) createKeySelectedHandler() func(index int, key string) func
}

gli.mainPanel.AddItem(mainListView, 0, 1, false)
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: mainListView, Key: tcell.KeyF6})
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: mainListView, Key: keyBindings.KeyID("key_list_value")})

case "hash":
hashKeys, err := gli.redisClient.HKeys(key).Result()
Expand All @@ -518,11 +574,11 @@ func (gli *RedisGli) createKeySelectedHandler() func(index int, key string) func
gli.mainPanel.AddItem(mainHashView, 0, 3, false).
AddItem(mainStringView, 0, 7, false)

gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: mainHashView, Key: tcell.KeyF6})
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: mainStringView, Key: tcell.KeyF7})
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: mainHashView, Key: keyBindings.KeyID("key_hash")})
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: mainStringView, Key: keyBindings.KeyID("key_string_value")})
}
gli.outputChan <- OutputMessage{tcell.ColorGreen, fmt.Sprintf("query %s OK, type=%s, ttl=%s", key, keyType, ttl.String())}
gli.metaPanel.SetText(fmt.Sprintf("Key: %s\nType: %s, TTL: %s", key, keyType, ttl.String())).SetTextAlign(tview.AlignCenter)
gli.metaPanel.SetText(fmt.Sprintf("KeyID: %s\nType: %s, TTL: %s", key, keyType, ttl.String())).SetTextAlign(tview.AlignCenter)
}
}
}

0 comments on commit 8d55df1

Please sign in to comment.