1package tui
2
3import (
4 "github.com/charmbracelet/bubbles/v2/key"
5)
6
7type KeyMap struct {
8 Quit key.Binding
9 Help key.Binding
10 Commands key.Binding
11 Sessions key.Binding
12
13 pageBindings []key.Binding
14}
15
16func DefaultKeyMap() KeyMap {
17 return KeyMap{
18 Quit: key.NewBinding(
19 key.WithKeys("ctrl+c"),
20 key.WithHelp("ctrl+c", "quit"),
21 ),
22 Help: key.NewBinding(
23 key.WithKeys("ctrl+?", "ctrl+_", "ctrl+/"),
24 key.WithHelp("ctrl+?", "more"),
25 ),
26 Commands: key.NewBinding(
27 key.WithKeys("ctrl+p"),
28 key.WithHelp("ctrl+p", "commands"),
29 ),
30 Sessions: key.NewBinding(
31 key.WithKeys("ctrl+s"),
32 key.WithHelp("ctrl+s", "sessions"),
33 ),
34 }
35}
36
37// FullHelp implements help.KeyMap.
38func (k KeyMap) FullHelp() [][]key.Binding {
39 m := [][]key.Binding{}
40 slice := []key.Binding{
41 k.Commands,
42 k.Sessions,
43 k.Quit,
44 k.Help,
45 }
46 slice = k.prependEscAndTab(slice)
47 slice = append(slice, k.pageBindings...)
48 // remove duplicates
49 seen := make(map[string]bool)
50 cleaned := []key.Binding{}
51 for _, b := range slice {
52 if !seen[b.Help().Key] {
53 seen[b.Help().Key] = true
54 cleaned = append(cleaned, b)
55 }
56 }
57
58 for i := 0; i < len(cleaned); i += 3 {
59 end := min(i+3, len(cleaned))
60 m = append(m, cleaned[i:end])
61 }
62 return m
63}
64
65func (k KeyMap) prependEscAndTab(bindings []key.Binding) []key.Binding {
66 var cancel key.Binding
67 var tab key.Binding
68 for _, b := range k.pageBindings {
69 if b.Help().Key == "esc" {
70 cancel = b
71 }
72 if b.Help().Key == "tab" {
73 tab = b
74 }
75 }
76 if tab.Help().Key != "" {
77 bindings = append([]key.Binding{tab}, bindings...)
78 }
79 if cancel.Help().Key != "" {
80 bindings = append([]key.Binding{cancel}, bindings...)
81 }
82 return bindings
83}
84
85// ShortHelp implements help.KeyMap.
86func (k KeyMap) ShortHelp() []key.Binding {
87 bindings := []key.Binding{
88 k.Commands,
89 k.Sessions,
90 k.Quit,
91 k.Help,
92 }
93 return k.prependEscAndTab(bindings)
94}