2021-03-02 20:37:38 +03:00
|
|
|
// Package key provides some types and functions for generating user-definable
|
|
|
|
// keymappings useful in Bubble Tea components. There are a few different ways
|
|
|
|
// you can define a keymapping with this package. Here's one example:
|
|
|
|
//
|
|
|
|
// type KeyMap struct {
|
|
|
|
// Up key.Binding
|
|
|
|
// Down key.Binding
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// var DefaultKeyMap = KeyMap{
|
|
|
|
// Up: key.NewBinding(
|
2021-09-01 18:31:14 +03:00
|
|
|
// key.WithKeys("k", "up"), // actual keybindings
|
|
|
|
// key.WithHelp("↑/k", "move up"), // corresponding help text
|
2021-03-02 20:37:38 +03:00
|
|
|
// ),
|
2021-09-01 18:31:14 +03:00
|
|
|
// Down: key.NewBinding(
|
2022-01-24 16:57:10 +03:00
|
|
|
// key.WithKeys("j", "down"),
|
|
|
|
// key.WithHelp("↓/j", "move down"),
|
2021-09-01 18:31:14 +03:00
|
|
|
// ),
|
2021-03-02 20:37:38 +03:00
|
|
|
// }
|
|
|
|
//
|
|
|
|
// func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
|
|
// switch msg := msg.(type) {
|
|
|
|
// case tea.KeyMsg:
|
|
|
|
// switch {
|
|
|
|
// case key.Matches(msg, DefaultKeyMap.Up):
|
|
|
|
// // The user pressed up
|
|
|
|
// case key.Matches(msg, DefaultKeyMap.Down):
|
|
|
|
// // The user pressed down
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// // ...
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// The help information, which is not used in the example above, can be used
|
|
|
|
// to render help text for keystrokes in your views.
|
|
|
|
package key
|
|
|
|
|
|
|
|
import (
|
|
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Binding describes a set of keybindings and, optionally, their associated
|
|
|
|
// help text.
|
|
|
|
type Binding struct {
|
|
|
|
keys []string
|
|
|
|
help Help
|
|
|
|
disabled bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// BindingOpt is an initialization option for a keybinding. It's used as an
|
|
|
|
// argument to NewBinding.
|
|
|
|
type BindingOpt func(*Binding)
|
|
|
|
|
|
|
|
// NewBinding returns a new keybinding from a set of BindingOpt options.
|
|
|
|
func NewBinding(opts ...BindingOpt) Binding {
|
|
|
|
b := &Binding{}
|
|
|
|
for _, opt := range opts {
|
|
|
|
opt(b)
|
|
|
|
}
|
|
|
|
return *b
|
|
|
|
}
|
|
|
|
|
|
|
|
// WithKeys initializes a keybinding with the given keystrokes.
|
|
|
|
func WithKeys(keys ...string) BindingOpt {
|
|
|
|
return func(b *Binding) {
|
|
|
|
b.keys = keys
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// WithHelp initializes a keybinding with the given help text.
|
|
|
|
func WithHelp(key, desc string) BindingOpt {
|
|
|
|
return func(b *Binding) {
|
|
|
|
b.help = Help{Key: key, Desc: desc}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// WithDisabled initializes a disabled keybinding.
|
|
|
|
func WithDisabled() BindingOpt {
|
|
|
|
return func(b *Binding) {
|
|
|
|
b.disabled = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetKeys sets the keys for the keybinding.
|
|
|
|
func (b *Binding) SetKeys(keys ...string) {
|
|
|
|
b.keys = keys
|
|
|
|
}
|
|
|
|
|
|
|
|
// Keys returns the keys for the keybinding.
|
|
|
|
func (b Binding) Keys() []string {
|
|
|
|
return b.keys
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetHelp sets the help text for the keybinding.
|
|
|
|
func (b *Binding) SetHelp(key, desc string) {
|
|
|
|
b.help = Help{Key: key, Desc: desc}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Help returns the Help information for the keybinding.
|
|
|
|
func (b Binding) Help() Help {
|
|
|
|
return b.help
|
|
|
|
}
|
|
|
|
|
|
|
|
// Enabled returns whether or not the keybinding is enabled. Disabled
|
|
|
|
// keybindings won't be activated and won't show up in help. Keybindings are
|
|
|
|
// enabled by default.
|
|
|
|
func (b Binding) Enabled() bool {
|
2022-07-11 17:45:18 +03:00
|
|
|
return !b.disabled && b.keys != nil
|
2021-03-02 20:37:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetEnabled enables or disables the keybinding.
|
|
|
|
func (b *Binding) SetEnabled(v bool) {
|
|
|
|
b.disabled = !v
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unbind removes the keys and help from this binding, effectively nullifying
|
|
|
|
// it. This is a step beyond disabling it, since applications can enable
|
|
|
|
// or disable key bindings based on application state.
|
|
|
|
func (b *Binding) Unbind() {
|
|
|
|
b.keys = nil
|
|
|
|
b.help = Help{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Help is help information for a given keybinding.
|
|
|
|
type Help struct {
|
|
|
|
Key string
|
|
|
|
Desc string
|
|
|
|
}
|
|
|
|
|
2021-12-21 02:17:08 +03:00
|
|
|
// Matches checks if the given KeyMsg matches the given bindings.
|
|
|
|
func Matches(k tea.KeyMsg, b ...Binding) bool {
|
2022-08-12 23:07:31 +03:00
|
|
|
keys := k.String()
|
2021-12-21 02:17:08 +03:00
|
|
|
for _, binding := range b {
|
|
|
|
for _, v := range binding.keys {
|
2022-08-12 23:07:31 +03:00
|
|
|
if keys == v && binding.Enabled() {
|
2021-12-21 02:17:08 +03:00
|
|
|
return true
|
|
|
|
}
|
2021-03-02 20:37:38 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|