keys.go

 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}