feat: l for details; details for vaults, scopes and files; getting started; the age of cached lists #17

Merged
keb merged 17 commits from feat/l-for-details into main 2026-10-11 14:24:09 +02:00
5 changed files with 15 additions and 9 deletions
Showing only changes of commit 365cb5b1df - Show all commits

No files matched your search

+2 -1
View File
@@ -65,7 +65,8 @@ use most:
| Key | Action | | Key | Action |
|---|---| |---|---|
| `j`/`k`, `h`/`l`, `enter`, `esc` | move, switch panes, drill in, back | | `j`/`k`, `enter`, `esc` | move, drill in, back |
| `l` / `h` | the details of what's selected / back |
| `/` | filter the list you're in | | `/` | filter the list you're in |
| `space` | reveal / hide the value | | `space` | reveal / hide the value |
| `y` | copy the value (cleared from the clipboard after 30s) | | `y` | copy the value (cleared from the clipboard after 30s) |
+4 -4
View File
@@ -13,7 +13,8 @@ The rule: a letter in the lists, ctrl+ that letter where you type a filter
|---|---| |---|---|
| `j`/`k`, `↑`/`↓` | move | | `j`/`k`, `↑`/`↓` | move |
| `g`/`G` | top / bottom | | `g`/`G` | top / bottom |
| `tab`/`l`, `shift+tab`/`h` | next / previous pane | | `tab`, `shift+tab`/`h` | next / previous pane |
| `l` | the details of what's selected, on the right (`h` goes back) |
| `1`–`4` | jump to pane | | `1`–`4` | jump to pane |
| `enter` / `esc`, `⌫` | drill in / back (also clears a filter or leaves the versions view) | | `enter` / `esc`, `⌫` | drill in / back (also clears a filter or leaves the versions view) |
| `[` / `]` | previous / next tab of the focused pane: Sources and Favourites in Sources; Secrets, Keys, Certs in Secrets | | `[` / `]` | previous / next tab of the focused pane: Sources and Favourites in Sources; Secrets, Keys, Certs in Secrets |
@@ -107,9 +108,8 @@ anything loads.
The pane on the right describes what's selected in the pane you're in: the The pane on the right describes what's selected in the pane you're in: the
account or subscription in Sources, the vault in Vaults, the secret in account or subscription in Sources, the vault in Vaults, the secret in
Secrets. Going into it (`4`, or `tab` from an account's row) keeps it on Secrets. Going into it (`l`, or `4`) keeps it on that; there `j`/`k`,
that; there `j`/`k`, `/` and `y` work on its rows, and `shift+tab` goes `/` and `y` work on its rows, and `h` goes back. A value you reveal stays in view whichever pane you're in, until
back. A value you reveal stays in view whichever pane you're in, until
it's hidden. it's hidden.
On top, the status pane (`0`) shows the version, a newer release and how On top, the status pane (`0`) shows the version, a newer release and how
+2
View File
@@ -821,6 +821,8 @@ func (m *Model) handleKey(msg tea.KeyPressMsg) (cmd tea.Cmd, quit bool) {
if r, ok := m.sources.Selected(); ok && m.focus == paneContainers && r.kind == rowGroup { if r, ok := m.sources.Selected(); ok && m.focus == paneContainers && r.kind == rowGroup {
m.focus = paneDetail // an account's row: nothing between m.focus = paneDetail // an account's row: nothing between
} }
case key.Matches(msg, k.Details):
m.focus = paneDetail // what's selected, on the right
case key.Matches(msg, k.PrevPane): case key.Matches(msg, k.PrevPane):
if m.focus == paneDetail { if m.focus == paneDetail {
m.focus = m.lastLeft // back to what it describes m.focus = m.lastLeft // back to what it describes
+3 -1
View File
@@ -758,7 +758,9 @@ func TestFocusKeys(t *testing.T) {
}{ }{
{"tab", paneContainers}, {"enter", paneSecrets}, {"enter", paneDetail}, {"tab", paneContainers}, {"enter", paneSecrets}, {"enter", paneDetail},
{"enter", paneDetail}, {"esc", paneSecrets}, {"shift+tab", paneContainers}, {"enter", paneDetail}, {"esc", paneSecrets}, {"shift+tab", paneContainers},
{"4", paneDetail}, {"l", paneSources}, {"h", paneDetail}, {"4", paneDetail}, {"tab", paneSources}, {"shift+tab", paneDetail},
// l: what's selected, on the right; h: back to it.
{"2", paneContainers}, {"l", paneDetail}, {"h", paneContainers}, {"h", paneSources}, {"l", paneDetail},
} { } {
d.keys(tc.key) d.keys(tc.key)
if d.m.focus != tc.want { if d.m.focus != tc.want {
+4 -3
View File
@@ -36,7 +36,7 @@ const (
type Map struct { type Map struct {
// lists // lists
Up, Down, Top, Bottom key.Binding Up, Down, Top, Bottom key.Binding
NextPane, PrevPane key.Binding NextPane, PrevPane, Details key.Binding
Pane0, Pane1, Pane2, Pane3, Pane4 key.Binding Pane0, Pane1, Pane2, Pane3, Pane4 key.Binding
NextTab, PrevTab key.Binding NextTab, PrevTab key.Binding
Enter, Back, Filter key.Binding Enter, Back, Filter key.Binding
@@ -87,7 +87,8 @@ func (m *Map) Actions() []Action {
a(Lists, "top", &m.Top, "top", "move", "Jump to the top of the focused list."), a(Lists, "top", &m.Top, "top", "move", "Jump to the top of the focused list."),
a(Lists, "bottom", &m.Bottom, "bottom", "move", "Jump to the bottom of the focused list."), a(Lists, "bottom", &m.Bottom, "bottom", "move", "Jump to the bottom of the focused list."),
a(Lists, "nextPane", &m.NextPane, "next pane", "move", "Focus the next pane: Sources, Vaults, Secrets, detail."), a(Lists, "nextPane", &m.NextPane, "next pane", "move", "Focus the next pane: Sources, Vaults, Secrets, detail."),
a(Lists, "prevPane", &m.PrevPane, "prev pane", "move", "Focus the previous pane."), a(Lists, "prevPane", &m.PrevPane, "prev pane", "move", "Focus the previous pane; from the detail pane, the one it describes."),
a(Lists, "details", &m.Details, "details", "move", "Focus the detail pane on the right, on what's selected: a source, vault, file or secret."),
a(Lists, "pane1", &m.Pane1, "Sources pane", "move", "Focus the Sources pane."), a(Lists, "pane1", &m.Pane1, "Sources pane", "move", "Focus the Sources pane."),
a(Lists, "pane2", &m.Pane2, "Vaults pane", "move", "Focus the Vaults (or Scopes) pane."), a(Lists, "pane2", &m.Pane2, "Vaults pane", "move", "Focus the Vaults (or Scopes) pane."),
a(Lists, "pane3", &m.Pane3, "Secrets pane", "move", "Focus the Secrets pane."), a(Lists, "pane3", &m.Pane3, "Secrets pane", "move", "Focus the Secrets pane."),
@@ -178,7 +179,7 @@ func (m *Map) Actions() []Action {
var defaults = map[string][]string{ var defaults = map[string][]string{
"lists.up": {"k", "up", "ctrl+k", "ctrl+p"}, "lists.down": {"j", "down", "ctrl+j", "ctrl+n"}, "lists.up": {"k", "up", "ctrl+k", "ctrl+p"}, "lists.down": {"j", "down", "ctrl+j", "ctrl+n"},
"lists.top": {"g", "home"}, "lists.bottom": {"G", "end"}, "lists.top": {"g", "home"}, "lists.bottom": {"G", "end"},
"lists.nextPane": {"tab", "l", "right"}, "lists.prevPane": {"shift+tab", "h", "left"}, "lists.nextPane": {"tab"}, "lists.prevPane": {"shift+tab", "h", "left"}, "lists.details": {"l", "right"},
"lists.pane1": {"1"}, "lists.pane2": {"2"}, "lists.pane3": {"3"}, "lists.pane4": {"4"}, "lists.pane0": {"0"}, "lists.pane1": {"1"}, "lists.pane2": {"2"}, "lists.pane3": {"3"}, "lists.pane4": {"4"}, "lists.pane0": {"0"},
"lists.enter": {"enter"}, "lists.back": {"esc", "backspace"}, "lists.enter": {"enter"}, "lists.back": {"esc", "backspace"},
"lists.filter": {"/"}, "lists.prevTab": {"["}, "lists.nextTab": {"]"}, "lists.sourcesView": {"`"}, "lists.filter": {"/"}, "lists.prevTab": {"["}, "lists.nextTab": {"]"}, "lists.sourcesView": {"`"},