Files
vault-tui/internal/ui/keys/keymap.go
T
f.weber ae30ba1240 feat(vault-tui): implement KV client and service for managing secrets
- Added internal/vault/client.go for creating a Vault client with configuration settings.
- Introduced internal/vault/errors.go to classify Vault API errors for better UI handling.
- Created internal/vault/kv.go to manage KV secrets, including listing, reading, writing, and deleting operations.
- Implemented internal/vault/mounts.go to list and describe secret engine mounts.
- Developed internal/vault/service.go to provide a unified entry point for Vault operations.
- Added internal/vault/kv_test.go for comprehensive testing of KV operations.
- Introduced internal/ui/toast.go for transient notifications in the UI.
- Added renovate.json for dependency management and updates.
2026-08-14 11:09:03 +02:00

128 lines
5.7 KiB
Go

// Package keys defines the TUI's keybindings and how config.File's `keys:`
// section can rebind them.
package keys
import "charm.land/bubbles/v2/key"
// KeyMap holds every action the TUI's root Update dispatches on. Screens
// consult the same KeyMap so a rebind in config.yaml takes effect
// everywhere at once.
type KeyMap struct {
Up, Down key.Binding
Top, Bottom key.Binding
Enter, Back key.Binding
Refresh key.Binding
Filter key.Binding
Palette key.Binding
ToggleMask key.Binding
ToggleMaskAll key.Binding
CopyValue key.Binding
Versions key.Binding
Rollback key.Binding
Undelete key.Binding
New, Edit key.Binding
Save, Cancel key.Binding
AddField key.Binding
DeleteField key.Binding
Delete, Destroy key.Binding
Profiles key.Binding
Logout key.Binding
Help, Quit key.Binding
ForceQuit key.Binding
}
// Default returns the built-in vim-flavoured keymap.
func Default() *KeyMap {
return &KeyMap{
Up: key.NewBinding(key.WithKeys("k", "up"), key.WithHelp("k/↑", "up")),
Down: key.NewBinding(key.WithKeys("j", "down"), key.WithHelp("j/↓", "down")),
Top: key.NewBinding(key.WithKeys("g", "home"), key.WithHelp("g", "top")),
Bottom: key.NewBinding(key.WithKeys("G", "end"), key.WithHelp("G", "bottom")),
Enter: key.NewBinding(key.WithKeys("enter", "l"), key.WithHelp("↵", "open")),
Back: key.NewBinding(key.WithKeys("esc", "h"), key.WithHelp("esc", "back")),
Refresh: key.NewBinding(key.WithKeys("r"), key.WithHelp("r", "refresh")),
Filter: key.NewBinding(key.WithKeys("/"), key.WithHelp("/", "filter")),
Palette: key.NewBinding(key.WithKeys(":"), key.WithHelp(":", "goto path")),
ToggleMask: key.NewBinding(key.WithKeys("s"), key.WithHelp("s", "show/hide value")),
ToggleMaskAll: key.NewBinding(key.WithKeys("S"), key.WithHelp("S", "show/hide all")),
CopyValue: key.NewBinding(key.WithKeys("y"), key.WithHelp("y", "copy value")),
Versions: key.NewBinding(key.WithKeys("V"), key.WithHelp("V", "versions")),
Rollback: key.NewBinding(key.WithKeys("R"), key.WithHelp("R", "rollback to this version")),
Undelete: key.NewBinding(key.WithKeys("u"), key.WithHelp("u", "undelete this version")),
New: key.NewBinding(key.WithKeys("n"), key.WithHelp("n", "new secret")),
Edit: key.NewBinding(key.WithKeys("e"), key.WithHelp("e", "edit")),
Save: key.NewBinding(key.WithKeys("ctrl+s"), key.WithHelp("^s", "save")),
Cancel: key.NewBinding(key.WithKeys("esc"), key.WithHelp("esc", "cancel")),
AddField: key.NewBinding(key.WithKeys("ctrl+a"), key.WithHelp("^a", "add field")),
DeleteField: key.NewBinding(key.WithKeys("ctrl+x"), key.WithHelp("^x", "remove field")),
Delete: key.NewBinding(key.WithKeys("d"), key.WithHelp("d", "delete")),
Destroy: key.NewBinding(key.WithKeys("D"), key.WithHelp("D", "destroy")),
Profiles: key.NewBinding(key.WithKeys("p"), key.WithHelp("p", "switch profile")),
Logout: key.NewBinding(key.WithKeys("ctrl+l"), key.WithHelp("^l", "logout")),
Help: key.NewBinding(key.WithKeys("?"), key.WithHelp("?", "help")),
Quit: key.NewBinding(key.WithKeys("q"), key.WithHelp("q", "quit")),
ForceQuit: key.NewBinding(key.WithKeys("ctrl+c"), key.WithHelp("^c", "quit")),
}
}
func (k *KeyMap) registry() map[string]*key.Binding {
return map[string]*key.Binding{
"up": &k.Up, "down": &k.Down, "top": &k.Top, "bottom": &k.Bottom,
"enter": &k.Enter, "back": &k.Back, "refresh": &k.Refresh, "filter": &k.Filter,
"palette": &k.Palette, "toggle_mask": &k.ToggleMask, "toggle_mask_all": &k.ToggleMaskAll,
"copy_value": &k.CopyValue, "versions": &k.Versions, "rollback": &k.Rollback,
"undelete": &k.Undelete, "new": &k.New, "edit": &k.Edit, "save": &k.Save,
"cancel": &k.Cancel, "add_field": &k.AddField, "delete_field": &k.DeleteField,
"delete": &k.Delete, "destroy": &k.Destroy, "profiles": &k.Profiles, "logout": &k.Logout,
"help": &k.Help, "quit": &k.Quit, "force_quit": &k.ForceQuit,
}
}
// Apply overrides the defaults from config.File's `keys:` map. An unknown
// action name is a startup error, not a silently ignored typo.
func (k *KeyMap) Apply(cfg map[string][]string) error {
reg := k.registry()
for action, keyStrs := range cfg {
b, ok := reg[action]
if !ok {
return unknownActionError(action)
}
*b = key.NewBinding(key.WithKeys(keyStrs...), key.WithHelp(b.Help().Key, b.Help().Desc))
}
return nil
}
type unknownActionError string
func (e unknownActionError) Error() string {
return "unknown keybinding action " + string(e) + " in config `keys:` section"
}
// DisableWrites turns off every write-capable binding — the UI-side half of
// read-only enforcement (the real guard is vault.KV.ReadOnly).
func (k *KeyMap) DisableWrites() {
for _, b := range []*key.Binding{
&k.New, &k.Edit, &k.Save, &k.AddField, &k.DeleteField,
&k.Delete, &k.Destroy, &k.Rollback, &k.Undelete,
} {
b.SetEnabled(false)
}
}
// ShortHelp/FullHelp implement help.KeyMap for the global bindings and
// back the "?" help overlay (screen_help.go). Individual screens' footers
// use the narrower, screen-specific views in help.go instead.
func (k *KeyMap) ShortHelp() []key.Binding {
return []key.Binding{k.Up, k.Down, k.Enter, k.Back, k.Help, k.Quit}
}
func (k *KeyMap) FullHelp() [][]key.Binding {
return [][]key.Binding{
{k.Up, k.Down, k.Top, k.Bottom, k.Enter, k.Back},
{k.Refresh, k.Filter, k.Palette, k.ToggleMask, k.ToggleMaskAll, k.CopyValue},
{k.Versions, k.Rollback, k.Undelete, k.New, k.Edit, k.Save},
{k.Cancel, k.AddField, k.DeleteField, k.Delete, k.Destroy},
{k.Profiles, k.Logout, k.Help, k.Quit, k.ForceQuit},
}
}