1package models
2
3import (
4 "charm.land/bubbles/v2/key"
5)
6
7type KeyMap struct {
8 Select,
9 Next,
10 Previous,
11 Choose,
12 Tab,
13 Close key.Binding
14
15 isAPIKeyHelp bool
16 isAPIKeyValid bool
17
18 isClaudeAuthChoiseHelp bool
19 isClaudeOAuthHelp bool
20 isClaudeOAuthURLState bool
21 isClaudeOAuthHelpComplete bool
22}
23
24func DefaultKeyMap() KeyMap {
25 return KeyMap{
26 Select: key.NewBinding(
27 key.WithKeys("enter", "ctrl+y"),
28 key.WithHelp("enter", "choose"),
29 ),
30 Next: key.NewBinding(
31 key.WithKeys("down", "ctrl+n"),
32 key.WithHelp("↓", "next item"),
33 ),
34 Previous: key.NewBinding(
35 key.WithKeys("up", "ctrl+p"),
36 key.WithHelp("↑", "previous item"),
37 ),
38 Choose: key.NewBinding(
39 key.WithKeys("left", "right", "h", "l"),
40 key.WithHelp("←→", "choose"),
41 ),
42 Tab: key.NewBinding(
43 key.WithKeys("tab"),
44 key.WithHelp("tab", "toggle type"),
45 ),
46 Close: key.NewBinding(
47 key.WithKeys("esc", "alt+esc"),
48 key.WithHelp("esc", "exit"),
49 ),
50 }
51}
52
53// KeyBindings implements layout.KeyMapProvider
54func (k KeyMap) KeyBindings() []key.Binding {
55 return []key.Binding{
56 k.Select,
57 k.Next,
58 k.Previous,
59 k.Tab,
60 k.Close,
61 }
62}
63
64// FullHelp implements help.KeyMap.
65func (k KeyMap) FullHelp() [][]key.Binding {
66 m := [][]key.Binding{}
67 slice := k.KeyBindings()
68 for i := 0; i < len(slice); i += 4 {
69 end := min(i+4, len(slice))
70 m = append(m, slice[i:end])
71 }
72 return m
73}
74
75// ShortHelp implements help.KeyMap.
76func (k KeyMap) ShortHelp() []key.Binding {
77 if k.isClaudeAuthChoiseHelp {
78 return []key.Binding{
79 key.NewBinding(
80 key.WithKeys("left", "right", "h", "l"),
81 key.WithHelp("←→", "choose"),
82 ),
83 key.NewBinding(
84 key.WithKeys("enter"),
85 key.WithHelp("enter", "accept"),
86 ),
87 key.NewBinding(
88 key.WithKeys("esc"),
89 key.WithHelp("esc", "back"),
90 ),
91 }
92 }
93 if k.isClaudeOAuthHelp {
94 if k.isClaudeOAuthHelpComplete {
95 return []key.Binding{
96 key.NewBinding(
97 key.WithKeys("enter"),
98 key.WithHelp("enter", "close"),
99 ),
100 }
101 }
102
103 enterHelp := "submit"
104 if k.isClaudeOAuthURLState {
105 enterHelp = "open"
106 }
107
108 bindings := []key.Binding{
109 key.NewBinding(
110 key.WithKeys("enter"),
111 key.WithHelp("enter", enterHelp),
112 ),
113 }
114
115 if k.isClaudeOAuthURLState {
116 bindings = append(bindings, key.NewBinding(
117 key.WithKeys("c"),
118 key.WithHelp("c", "copy url"),
119 ))
120 }
121
122 bindings = append(bindings, key.NewBinding(
123 key.WithKeys("esc"),
124 key.WithHelp("esc", "back"),
125 ))
126
127 return bindings
128 }
129 if k.isAPIKeyHelp && !k.isAPIKeyValid {
130 return []key.Binding{
131 key.NewBinding(
132 key.WithKeys("enter"),
133 key.WithHelp("enter", "submit"),
134 ),
135 k.Close,
136 }
137 } else if k.isAPIKeyValid {
138 return []key.Binding{
139 k.Select,
140 }
141 }
142 return []key.Binding{
143 key.NewBinding(
144 key.WithKeys("down", "up"),
145 key.WithHelp("↑↓", "choose"),
146 ),
147 k.Tab,
148 k.Select,
149 k.Close,
150 }
151}