keys.go

  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}