Archived
For developers new to submodules (notes/usability-plan.md, D32): - x and X read "restore to pin" and "restore committed pins" - problems only, filter and fetch are shown in the footer - ? shows every key in titled columns, then a legend of the status words, symbols and spine roles; esc closes it - u reads "pull (fast-forward)" on the superproject - the detail pane suggests f when the last fetch is old - a hint above the footer until the first key - the header says "staged", like the tree Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
121 lines
5.7 KiB
Go
121 lines
5.7 KiB
Go
package tui
|
|
|
|
import (
|
|
"github.com/charmbracelet/bubbles/key"
|
|
|
|
"submarine/internal/tui/footer"
|
|
)
|
|
|
|
type keyMap struct {
|
|
Up, Down, Left, Right, Toggle key.Binding
|
|
CollapseAll, ExpandAll key.Binding
|
|
Home, End, PageUp, PageDown key.Binding
|
|
Fetch, Reload, Filter, Issues key.Binding
|
|
Copy, Restore, Switch, Update key.Binding
|
|
HardRestore key.Binding
|
|
Help, Quit, QuitUpdate key.Binding
|
|
}
|
|
|
|
func defaultKeys() keyMap {
|
|
return keyMap{
|
|
Up: key.NewBinding(key.WithKeys("up", "k"), key.WithHelp("↑/k", "up")),
|
|
Down: key.NewBinding(key.WithKeys("down", "j"), key.WithHelp("↓/j", "down")),
|
|
Left: key.NewBinding(key.WithKeys("left", "h"), key.WithHelp("←/h", "collapse, parent")),
|
|
Right: key.NewBinding(key.WithKeys("right", "l"), key.WithHelp("→/l", "expand, first child")),
|
|
Toggle: key.NewBinding(key.WithKeys(" "), key.WithHelp("space", "toggle")),
|
|
CollapseAll: key.NewBinding(key.WithKeys("shift+left", "ctrl+left", "H"), key.WithHelp("H/⇧←", "collapse all")),
|
|
ExpandAll: key.NewBinding(key.WithKeys("shift+right", "ctrl+right", "L"), key.WithHelp("L/⇧→", "expand all")),
|
|
Home: key.NewBinding(key.WithKeys("home", "g"), key.WithHelp("home/g", "first")),
|
|
End: key.NewBinding(key.WithKeys("end", "G"), key.WithHelp("end/G", "last")),
|
|
PageUp: key.NewBinding(key.WithKeys("pgup"), key.WithHelp("pgup", "page up")),
|
|
PageDown: key.NewBinding(key.WithKeys("pgdown"), key.WithHelp("pgdn", "page down")),
|
|
Fetch: key.NewBinding(key.WithKeys("f"), key.WithHelp("f", "fetch")),
|
|
Reload: key.NewBinding(key.WithKeys("r"), key.WithHelp("r", "reload")),
|
|
Filter: key.NewBinding(key.WithKeys("/"), key.WithHelp("/", "filter")),
|
|
Issues: key.NewBinding(key.WithKeys("!"), key.WithHelp("!", "problems only")),
|
|
Restore: key.NewBinding(key.WithKeys("x"), key.WithHelp("x", "restore to pin")),
|
|
HardRestore: key.NewBinding(key.WithKeys("X"), key.WithHelp("X", "restore committed pins")),
|
|
Switch: key.NewBinding(key.WithKeys("b"), key.WithHelp("b", "switch branch")),
|
|
Update: key.NewBinding(key.WithKeys("u"), key.WithHelp("u", "update pin")),
|
|
Copy: key.NewBinding(key.WithKeys("c"), key.WithHelp("c", "copy path")),
|
|
Help: key.NewBinding(key.WithKeys("?"), key.WithHelp("?", "help")),
|
|
Quit: key.NewBinding(key.WithKeys("q", "ctrl+c"), key.WithHelp("q", "quit")),
|
|
QuitUpdate: key.NewBinding(key.WithKeys("q"), key.WithHelp("q", "quit and update"), key.WithDisabled()),
|
|
}
|
|
}
|
|
|
|
// SetUpdate announces the newer release v: q quits and updates to it, and the
|
|
// plain quit moves to Q (ctrl+c always quits without updating).
|
|
func (k *keyMap) SetUpdate(v string) {
|
|
k.Quit = key.NewBinding(key.WithKeys("Q", "ctrl+c"), key.WithHelp("Q", "quit"))
|
|
k.QuitUpdate = key.NewBinding(key.WithKeys("q"), key.WithHelp("q", "quit and update to "+v))
|
|
}
|
|
|
|
// Navigation returns the bindings that move the selection or fold the tree.
|
|
func (k keyMap) Navigation() []key.Binding {
|
|
move := key.NewBinding(key.WithKeys("up"), key.WithHelp("↑↓/jk", "move"))
|
|
fold := key.NewBinding(key.WithKeys("left"), key.WithHelp("←→/hl", "collapse/expand"))
|
|
all := key.NewBinding(key.WithKeys("H"), key.WithHelp("⇧←→/HL", "all"))
|
|
return []key.Binding{move, fold, all, k.Toggle}
|
|
}
|
|
|
|
// Tools returns the bindings that act on the whole list: problems only,
|
|
// filter and fetch, most useful first, since the footer drops them from the
|
|
// end. It shows them after the navigation keys.
|
|
func (k keyMap) Tools() []key.Binding { return []key.Binding{k.Issues, k.Filter, k.Fetch} }
|
|
|
|
// Submodule returns the bindings that act on the selected submodule. They
|
|
// are shown in the detail pane, or in the footer if the pane can't show them.
|
|
func (k keyMap) Submodule() []key.Binding {
|
|
return []key.Binding{k.Copy, k.Update, k.Switch, k.Restore, k.HardRestore}
|
|
}
|
|
|
|
// Global returns the bindings that don't depend on the selection.
|
|
func (k keyMap) Global() []key.Binding { return []key.Binding{k.Help, k.Quit} }
|
|
|
|
// fullUpdate is Highlight with a short description, for the full help.
|
|
func (k keyMap) fullUpdate() []key.Binding {
|
|
if !k.QuitUpdate.Enabled() {
|
|
return nil
|
|
}
|
|
return []key.Binding{key.NewBinding(key.WithKeys("q"), key.WithHelp("q", "quit and update"))}
|
|
}
|
|
|
|
// Highlight returns the bindings that are shown after Global on a highlighted
|
|
// background: quit and update, if there is an update.
|
|
func (k keyMap) Highlight() []key.Binding {
|
|
if !k.QuitUpdate.Enabled() {
|
|
return nil
|
|
}
|
|
return []key.Binding{k.QuitUpdate}
|
|
}
|
|
|
|
// forSelection returns the keys as they read for the selection: on the
|
|
// superproject, u fast-forwards its branch (D29).
|
|
func (k keyMap) forSelection(root bool) keyMap {
|
|
if root {
|
|
k.Update.SetHelp("u", "pull (fast-forward)")
|
|
}
|
|
return k
|
|
}
|
|
|
|
// HelpGroups returns the columns of the full help, each with a title.
|
|
func (k keyMap) HelpGroups() []footer.Group {
|
|
help := key.NewBinding(key.WithKeys("?"), key.WithHelp("?", "what words mean"))
|
|
esc := key.NewBinding(key.WithKeys("esc"), key.WithHelp("esc", "close"))
|
|
return []footer.Group{
|
|
{Title: "Move", Keys: []key.Binding{k.Up, k.Down, k.Left, k.Right, k.Toggle, k.CollapseAll, k.ExpandAll}},
|
|
{Title: "Jump", Keys: []key.Binding{k.Home, k.End, k.PageUp, k.PageDown}},
|
|
{Title: "Selected submodule", Keys: k.Submodule()},
|
|
{Title: "All submodules", Keys: []key.Binding{k.Fetch, k.Reload, k.Filter, k.Issues}},
|
|
{Title: "App", Keys: append([]key.Binding{help, esc, k.Quit}, k.fullUpdate()...)},
|
|
}
|
|
}
|
|
|
|
// LegendKeys returns the column next to the legend, the help's last page;
|
|
// ? closes it too, but esc is the key to tell.
|
|
func (k keyMap) LegendKeys() footer.Group {
|
|
esc := key.NewBinding(key.WithKeys("esc"), key.WithHelp("esc", "close"))
|
|
return footer.Group{Title: "App", Keys: append([]key.Binding{esc, k.Quit}, k.fullUpdate()...)}
|
|
}
|