keys.go

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