org/internal/ui/keybindings.go

186 lines
5.2 KiB
Go

package ui
import (
"strings"
"github.com/charmbracelet/bubbles/key"
"github.com/rwejlgaard/org/internal/config"
)
type keyMap struct {
Up key.Binding
Down key.Binding
Left key.Binding
Right key.Binding
ShiftUp key.Binding
ShiftDown key.Binding
CycleState key.Binding
ToggleView key.Binding
Quit key.Binding
Help key.Binding
Capture key.Binding
AddSubTask key.Binding
Delete key.Binding
Save key.Binding
ToggleFold key.Binding
EditNotes key.Binding
ToggleReorder key.Binding
ClockIn key.Binding
ClockOut key.Binding
SetDeadline key.Binding
SetPriority key.Binding
SetEffort key.Binding
Settings key.Binding
TagItem key.Binding
}
// newKeyMapFromConfig creates a keyMap from configuration
func newKeyMapFromConfig(cfg *config.Config) keyMap {
kb := cfg.Keybindings
return keyMap{
Up: key.NewBinding(
key.WithKeys(kb.Up...),
key.WithHelp(formatKeyHelp(kb.Up), "move up"),
),
Down: key.NewBinding(
key.WithKeys(kb.Down...),
key.WithHelp(formatKeyHelp(kb.Down), "move down"),
),
Left: key.NewBinding(
key.WithKeys(kb.Left...),
key.WithHelp(formatKeyHelp(kb.Left), "cycle state backward"),
),
Right: key.NewBinding(
key.WithKeys(kb.Right...),
key.WithHelp(formatKeyHelp(kb.Right), "cycle state forward"),
),
ShiftUp: key.NewBinding(
key.WithKeys(kb.ShiftUp...),
key.WithHelp(formatKeyHelp(kb.ShiftUp), "move item up"),
),
ShiftDown: key.NewBinding(
key.WithKeys(kb.ShiftDown...),
key.WithHelp(formatKeyHelp(kb.ShiftDown), "move item down"),
),
CycleState: key.NewBinding(
key.WithKeys(kb.CycleState...),
key.WithHelp(formatKeyHelp(kb.CycleState), "cycle todo state"),
),
ToggleFold: key.NewBinding(
key.WithKeys(kb.ToggleFold...),
key.WithHelp(formatKeyHelp(kb.ToggleFold), "fold/unfold"),
),
EditNotes: key.NewBinding(
key.WithKeys(kb.EditNotes...),
key.WithHelp(formatKeyHelp(kb.EditNotes), "edit notes"),
),
ToggleView: key.NewBinding(
key.WithKeys(kb.ToggleView...),
key.WithHelp(formatKeyHelp(kb.ToggleView), "toggle agenda view"),
),
Capture: key.NewBinding(
key.WithKeys(kb.Capture...),
key.WithHelp(formatKeyHelp(kb.Capture), "capture TODO"),
),
AddSubTask: key.NewBinding(
key.WithKeys(kb.AddSubTask...),
key.WithHelp(formatKeyHelp(kb.AddSubTask), "add sub-task"),
),
Delete: key.NewBinding(
key.WithKeys(kb.Delete...),
key.WithHelp(formatKeyHelp(kb.Delete), "delete item"),
),
Save: key.NewBinding(
key.WithKeys(kb.Save...),
key.WithHelp(formatKeyHelp(kb.Save), "save"),
),
ToggleReorder: key.NewBinding(
key.WithKeys(kb.ToggleReorder...),
key.WithHelp(formatKeyHelp(kb.ToggleReorder), "reorder mode"),
),
ClockIn: key.NewBinding(
key.WithKeys(kb.ClockIn...),
key.WithHelp(formatKeyHelp(kb.ClockIn), "clock in"),
),
ClockOut: key.NewBinding(
key.WithKeys(kb.ClockOut...),
key.WithHelp(formatKeyHelp(kb.ClockOut), "clock out"),
),
SetDeadline: key.NewBinding(
key.WithKeys(kb.SetDeadline...),
key.WithHelp(formatKeyHelp(kb.SetDeadline), "set deadline"),
),
SetPriority: key.NewBinding(
key.WithKeys(kb.SetPriority...),
key.WithHelp(formatKeyHelp(kb.SetPriority), "set priority"),
),
SetEffort: key.NewBinding(
key.WithKeys(kb.SetEffort...),
key.WithHelp(formatKeyHelp(kb.SetEffort), "set effort"),
),
Help: key.NewBinding(
key.WithKeys(kb.Help...),
key.WithHelp(formatKeyHelp(kb.Help), "toggle help"),
),
Quit: key.NewBinding(
key.WithKeys(kb.Quit...),
key.WithHelp(formatKeyHelp(kb.Quit), "quit"),
),
Settings: key.NewBinding(
key.WithKeys(kb.Settings...),
key.WithHelp(formatKeyHelp(kb.Settings), "settings"),
),
TagItem: key.NewBinding(
key.WithKeys(kb.TagItem...),
key.WithHelp(formatKeyHelp(kb.TagItem), "add/edit tags"),
),
}
}
// formatKeyHelp formats a slice of keys for display in help
func formatKeyHelp(keys []string) string {
if len(keys) == 0 {
return ""
}
// Take first two keys for display
if len(keys) == 1 {
return formatKey(keys[0])
}
return formatKey(keys[0]) + "/" + formatKey(keys[1])
}
// formatKey formats a single key for display
func formatKey(k string) string {
// Convert key names to symbols where appropriate
k = strings.ReplaceAll(k, "up", "↑")
k = strings.ReplaceAll(k, "down", "↓")
k = strings.ReplaceAll(k, "left", "←")
k = strings.ReplaceAll(k, "right", "→")
return k
}
func (k keyMap) ShortHelp() []key.Binding {
return []key.Binding{k.Help}
}
func (k keyMap) FullHelp() [][]key.Binding {
// This will be overridden by custom rendering in viewFullHelp
return [][]key.Binding{
{k.Up, k.Down, k.Left, k.Right},
{k.ToggleFold, k.EditNotes, k.ToggleReorder},
{k.Capture, k.AddSubTask, k.Delete, k.Save},
{k.ToggleView, k.Help, k.Quit},
}
}
// getAllBindings returns all keybindings as a flat list
func (k keyMap) getAllBindings() []key.Binding {
return []key.Binding{
k.Up, k.Down, k.Left, k.Right,
k.ToggleFold, k.EditNotes, k.ToggleReorder,
k.Capture, k.AddSubTask, k.Delete, k.Save,
k.ClockIn, k.ClockOut, k.SetDeadline, k.SetPriority, k.SetEffort,
k.TagItem, k.Settings, k.ToggleView, k.Help, k.Quit,
}
}