diff --git a/docs/links.md b/docs/links.md index 4f7e629..d6429d5 100644 --- a/docs/links.md +++ b/docs/links.md @@ -118,9 +118,9 @@ read the clipboard over SSH. lazysecrets finds the vault in your accounts (one Resource Graph query per account) and jumps to it, asking which account to use when several can see -it. Links say what, not what to do: opening a link to a secret asks whether -to just go to it, also copy or show its value, or (`y`) copy its value -without going there. +it, ending on a secret's details as `enter` on it would. Links say what, +not what to do: opening a link to a secret asks whether to just go to it, +also copy or show its value, or (`y`) copy its value without going there. ## In scripts diff --git a/internal/ui/app/jump.go b/internal/ui/app/jump.go index 495ecd9..905cbec 100644 --- a/internal/ui/app/jump.go +++ b/internal/ui/app/jump.go @@ -217,7 +217,7 @@ func (m *Model) jumpTo(r ref.Ref, n store.Node) tea.Cmd { case 1: m.startNav(r, actGo, choices[0].sourceRow) default: - m.chooseSource("Several accounts can see "+r.ContainerName(), r, actGo, choices) + m.chooseSource("Several accounts can see "+r.ContainerName(), r, actGo, choices, false) } return nil } diff --git a/internal/ui/app/links.go b/internal/ui/app/links.go index 9899b95..21bfae4 100644 --- a/internal/ui/app/links.go +++ b/internal/ui/app/links.go @@ -46,6 +46,9 @@ type nav struct { // quiet gives up without a word: going back to where lazysecrets // was left, which may be gone. quiet bool + // link ends on the object's details, as enter on it would: opening + // a link to it opens it, rather than just finding it in its list. + link bool } type resolvedMsg struct { @@ -401,23 +404,30 @@ func (m *Model) handleResolved(msg resolvedMsg) { for i := range msg.choices { msg.choices[i].label = "Open in " + msg.choices[i].label } - m.chooseSource("Scope "+msg.ref.Scope+" is in several workspaces", msg.ref, msg.act, msg.choices) + m.chooseSource("Scope "+msg.ref.Scope+" is in several workspaces", msg.ref, msg.act, msg.choices, true) case len(msg.others) > 0: var choices []choice for _, row := range append([]string{msg.sourceRow}, msg.others...) { choices = append(choices, choice{label: "Open with " + m.sourceLabel(row), sourceRow: row}) } - m.chooseSource("Several accounts can see "+msg.ref.ContainerName(), msg.ref, msg.act, choices) + m.chooseSource("Several accounts can see "+msg.ref.ContainerName(), msg.ref, msg.act, choices, true) case msg.linked != nil: m.addLinked(*msg.linked) - m.startNav(msg.ref, msg.act, linksRowID) + m.startLinkNav(msg.ref, msg.act, linksRowID) default: - m.startNav(msg.ref, msg.act, msg.sourceRow) + m.startLinkNav(msg.ref, msg.act, msg.sourceRow) } } +// startLinkNav opens a link: like startNav, ending on its object's +// details. +func (m *Model) startLinkNav(r ref.Ref, act linkAction, sourceRow string) { + m.startNav(r, act, sourceRow) + m.nav.link = true +} + // chooseSource asks where to open r. -func (m *Model) chooseSource(title string, r ref.Ref, act linkAction, choices []choice) { +func (m *Model) chooseSource(title string, r ref.Ref, act linkAction, choices []choice, link bool) { var opts []option for i, c := range choices { key := "" @@ -427,6 +437,7 @@ func (m *Model) chooseSource(title string, r ref.Ref, act linkAction, choices [] row := c.sourceRow opts = append(opts, option{key: key, label: c.label, run: func(m *Model) tea.Cmd { m.startNav(r, act, row) + m.nav.link = link return nil }}) } @@ -577,6 +588,9 @@ func (m *Model) advanceNav() bool { m.pendingCmd = m.toggleReveal() } } + if n.link { + m.focus = paneDetail // after: copying acts on the focused pane + } return true } return false diff --git a/internal/ui/app/links_test.go b/internal/ui/app/links_test.go index 2fc0492..2ae1846 100644 --- a/internal/ui/app/links_test.go +++ b/internal/ui/app/links_test.go @@ -40,7 +40,8 @@ func TestOpenSecretLink(t *testing.T) { if src, c, s := d.selected(); src != "platform-prod" || c != "kv-app-prod" || s != "api-key" { t.Fatalf("opened %s/%s/%s", src, c, s) } - if d.m.focus != paneSecrets || d.m.detail.State() != panes.ValueHidden { + // Opened: on its details, as enter on it would; its value hidden. + if d.m.focus != paneDetail || d.m.detail.State() != panes.ValueHidden { t.Errorf("focus %d, value state %d", d.m.focus, d.m.detail.State()) } }