Skip to content

Commit 8d55df1

Browse files
committed
add key bindings map support
1 parent dc19c7e commit 8d55df1

File tree

1 file changed

+100
-44
lines changed

1 file changed

+100
-44
lines changed

gui.go

Lines changed: 100 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,58 @@ import (
44
"fmt"
55
"github.com/gdamore/tcell"
66
"github.com/rivo/tview"
7+
"strings"
78
"time"
89
)
910

11+
type KeyBindings map[string][]tcell.Key
12+
13+
var keyBindings = KeyBindings{
14+
"search": {tcell.KeyF2, tcell.KeyCtrlS},
15+
"keys": {tcell.KeyF3, tcell.KeyCtrlK},
16+
"key_list_value": {tcell.KeyF6, tcell.KeyCtrlH},
17+
"key_string_value": {tcell.KeyF7, tcell.KeyCtrlA},
18+
"key_hash": {tcell.KeyF6, tcell.KeyCtrlH},
19+
"output": {tcell.KeyF9, tcell.KeyCtrlO},
20+
"command": {tcell.KeyF1, tcell.KeyCtrlN},
21+
"command_focus": {tcell.KeyF4, tcell.KeyCtrlF},
22+
"command_result": {tcell.KeyF5, tcell.KeyCtrlR},
23+
"quit": {tcell.KeyEsc, tcell.KeyCtrlQ},
24+
"switch_focus": {tcell.KeyTab},
25+
}
26+
27+
func (kb KeyBindings) SearchKey(k tcell.Key) string {
28+
for name, bind := range kb {
29+
for _, b := range bind {
30+
if b == k {
31+
return name
32+
}
33+
}
34+
}
35+
36+
return ""
37+
}
38+
39+
func (kb KeyBindings) KeyID(key string) string {
40+
return key
41+
}
42+
43+
func (kb KeyBindings) Keys(key string) []tcell.Key {
44+
return kb[key]
45+
}
46+
47+
func (kb KeyBindings) Name(key string) string {
48+
keyNames := make([]string, 0)
49+
for _, k := range kb[key] {
50+
keyNames = append(keyNames, tcell.KeyNames[k])
51+
}
52+
53+
return strings.Join(keyNames, ", ")
54+
}
55+
1056
type primitiveKey struct {
1157
Primitive tview.Primitive
12-
Key tcell.Key
58+
Key string
1359
}
1460

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

99-
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.searchPanel, Key: tcell.KeyF2})
100-
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.keyItemsPanel, Key: tcell.KeyF3})
145+
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.searchPanel, Key: keyBindings.KeyID("search")})
146+
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.keyItemsPanel, Key: keyBindings.KeyID("keys")})
101147

102148
gli.app.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
103-
switch event.Key() {
104-
case tcell.KeyTab:
149+
150+
if gli.config.Debug {
151+
gli.outputChan <- OutputMessage{Message: fmt.Sprintf("Key %s pressed", tcell.KeyNames[event.Key()])}
152+
}
153+
154+
name := keyBindings.SearchKey(event.Key())
155+
switch name {
156+
case "switch_focus":
105157
nextFocusIndex := gli.currentFocusIndex + 1
106158
if nextFocusIndex > len(gli.focusPrimitives)-1 {
107159
nextFocusIndex = 0
@@ -111,9 +163,9 @@ func NewRedisGli(redisClient RedisClient, maxKeyLimit int64, version string, git
111163
gli.currentFocusIndex = nextFocusIndex
112164

113165
return nil
114-
case tcell.KeyEsc:
166+
case "quit":
115167
gli.app.Stop()
116-
case tcell.KeyF1:
168+
case "command":
117169
if gli.commandMode {
118170
gli.commandMode = false
119171
gli.redrawRightPanel(gli.mainPanel)
@@ -132,7 +184,7 @@ func NewRedisGli(redisClient RedisClient, maxKeyLimit int64, version string, git
132184
}
133185
default:
134186
for i, pv := range gli.focusPrimitives {
135-
if pv.Key == event.Key() {
187+
if pv.Key == name {
136188
gli.app.SetFocus(pv.Primitive)
137189
gli.currentFocusIndex = i
138190
break
@@ -146,19 +198,6 @@ func NewRedisGli(redisClient RedisClient, maxKeyLimit int64, version string, git
146198
return gli
147199
}
148200

149-
func (gli *RedisGli) redrawRightPanel(center tview.Primitive) {
150-
gli.rightPanel.RemoveItem(gli.metaPanel).
151-
RemoveItem(gli.outputPanel).
152-
RemoveItem(gli.mainPanel).
153-
RemoveItem(gli.commandPanel).
154-
RemoveItem(gli.helpPanel)
155-
156-
gli.rightPanel.AddItem(gli.helpPanel, 5, 1, false).
157-
AddItem(gli.metaPanel, 4, 1, false).
158-
AddItem(center, 0, 7, false).
159-
AddItem(gli.outputPanel, 8, 1, false)
160-
}
161-
162201
// Start create the ui and start the program
163202
func (gli *RedisGli) Start() error {
164203
go gli.app.QueueUpdateDraw(func() {
@@ -217,6 +256,19 @@ func (gli *RedisGli) Start() error {
217256
return gli.app.SetRoot(gli.pages, true).Run()
218257
}
219258

259+
func (gli *RedisGli) redrawRightPanel(center tview.Primitive) {
260+
gli.rightPanel.RemoveItem(gli.metaPanel).
261+
RemoveItem(gli.outputPanel).
262+
RemoveItem(gli.mainPanel).
263+
RemoveItem(gli.commandPanel).
264+
RemoveItem(gli.helpPanel)
265+
266+
gli.rightPanel.AddItem(gli.helpPanel, 5, 1, false).
267+
AddItem(gli.metaPanel, 4, 1, false).
268+
AddItem(center, 0, 7, false).
269+
AddItem(gli.outputPanel, 8, 1, false)
270+
}
271+
220272
func (gli *RedisGli) createSummaryPanel() *tview.TextView {
221273
panel := tview.NewTextView()
222274
panel.SetBorder(true).SetTitle(" Info ")
@@ -229,10 +281,9 @@ func (gli *RedisGli) keyItemsFormat(index int, key string) string {
229281

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

234285
resultPanel := tview.NewTextView()
235-
resultPanel.SetBorder(true).SetTitle(" Results (F5) ")
286+
resultPanel.SetBorder(true).SetTitle(fmt.Sprintf(" Results (%s) ", keyBindings.Name("command_result")))
236287

237288
formPanel := tview.NewInputField().SetLabel("Command ")
238289
var locked bool
@@ -246,8 +297,8 @@ func (gli *RedisGli) createCommandPanel() *tview.Flex {
246297
gli.pages.AddPage(
247298
pageID,
248299
tview.NewModal().
249-
SetText("之前的命令正在处理中,请稍候...").
250-
AddButtons([]string{"确定"}).
300+
SetText("Other command is processing, please wait...").
301+
AddButtons([]string{"OK"}).
251302
SetDoneFunc(func(buttonIndex int, buttonLabel string) {
252303
gli.pages.HidePage(pageID).RemovePage(pageID)
253304
gli.app.SetFocus(formPanel)
@@ -283,13 +334,13 @@ func (gli *RedisGli) createCommandPanel() *tview.Flex {
283334
formPanel.SetText("")
284335
})
285336
// formPanel.SetBackgroundColor(tcell.ColorOrange)
286-
formPanel.SetBorder(true).SetTitle(" Commands (F4) ")
337+
formPanel.SetBorder(true).SetTitle(fmt.Sprintf(" Commands (%s) ", keyBindings.Name("command_focus")))
287338

288339
gli.commandFormPanel = formPanel
289340
gli.commandResultPanel = resultPanel
290341

291-
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.commandFormPanel, Key: tcell.KeyF4})
292-
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.commandResultPanel, Key: tcell.KeyF5})
342+
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.commandFormPanel, Key: keyBindings.KeyID("command_focus")})
343+
gli.focusPrimitives = append(gli.focusPrimitives, primitiveKey{Primitive: gli.commandResultPanel, Key: keyBindings.KeyID("command_result")})
293344

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

300351
// createSearchPanel create search panel
301352
func (gli *RedisGli) createSearchPanel() *tview.InputField {
302-
searchArea := tview.NewInputField().SetLabel(" Key ")
353+
searchArea := tview.NewInputField().SetLabel(" KeyID ")
303354
searchArea.SetDoneFunc(func(key tcell.Key) {
304355
if key != tcell.KeyEnter {
305356
return
@@ -327,14 +378,14 @@ func (gli *RedisGli) createSearchPanel() *tview.InputField {
327378
gli.keyItemsPanel.AddItem(gli.keyItemsFormat(i, k), "", 0, gli.itemSelectedHandler(i, k))
328379
}
329380
})
330-
searchArea.SetBorder(true).SetTitle(" Search (F2) ")
381+
searchArea.SetBorder(true).SetTitle(fmt.Sprintf(" Search (%s) ", keyBindings.Name("search")))
331382
return searchArea
332383
}
333384

334385
// createKeyItemsPanel create key items panel
335386
func (gli *RedisGli) createKeyItemsPanel() *tview.List {
336387
keyItemsList := tview.NewList().ShowSecondaryText(false)
337-
keyItemsList.SetBorder(true).SetTitle(" Keys (F3) ")
388+
keyItemsList.SetBorder(true).SetTitle(fmt.Sprintf(" Keys (%s) ", keyBindings.Name("keys")))
338389
return keyItemsList
339390
}
340391

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

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

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

389440
gli.helpMessagePanel = tview.NewTextView()
390-
gli.helpMessagePanel.SetTextColor(tcell.ColorOrange).SetText(" ❈ Press F1 to switch between command panel and value panel, Esc to quit")
441+
gli.helpMessagePanel.SetTextColor(tcell.ColorOrange).SetText(fmt.Sprintf(
442+
" ❈ %s - open command panel, %s - switch focus, %s - quit",
443+
keyBindings.Name("command"),
444+
keyBindings.Name("switch_focus"),
445+
keyBindings.Name("quit"),
446+
))
391447

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

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

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

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

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

410466
return func(index int, key string) func() {
411467
return func() {
@@ -447,7 +503,7 @@ func (gli *RedisGli) createKeySelectedHandler() func(index int, key string) func
447503
}
448504

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

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

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

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

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

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

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

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

0 commit comments

Comments
 (0)