refactor: tidy up sharing after the round of tweaks
- Go to's picker settings are one picker struct, set while picking.
- Opening a share link plans the save, then asks or saves; no more
offerWrite doing either by a flag.
- Closing the picker while it encrypts cancels the share, and a
second pick meanwhile is ignored.
- Favourites and Recent leave out plain env values as keys too.
- share.key in the config is checked with share.ParseKey, so
{{secrets/…}} is refused there already.
- A key that can't be read reads the same opening as sharing
("can't use …"); KeyError moved to share.go, maxFiles is
maxUnpacked (bytes), and a stray comment is gone.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
9 files changed
+218
-118
No files matched your search
@@ -53,16 +53,8 @@ type searchView struct {
|
||||
res int // cursor in shown
|
||||
here string // the scope of the source Go to was opened from, if any
|
||||
|
||||
// pick, if set, makes Go to a picker of secrets, for title: it lists
|
||||
// secrets only, and enter gives the selected one's link to pick
|
||||
// instead of going there.
|
||||
pick func(m *Model, r ref.Ref) tea.Cmd
|
||||
pickTitle string // the popup's
|
||||
pickLines []string // what picking is for, above the picker
|
||||
pickHeading string // the picker's title, on its border
|
||||
pickHelp []string // inside it, above the tabs
|
||||
pickBusy string // what picking is doing, under the help
|
||||
pickErr string // why the key picked can't be used
|
||||
// picker, if set, makes Go to pick a secret instead of going to it.
|
||||
picker *picker
|
||||
|
||||
// loaded are the scopes a search has loaded since the popup opened:
|
||||
// typing loads the scope once, so lists that fail aren't asked for
|
||||
@@ -279,7 +271,7 @@ func (v *searchView) match() []option {
|
||||
}
|
||||
}
|
||||
}
|
||||
if v.pick != nil {
|
||||
if v.picker != nil {
|
||||
cand = slices.DeleteFunc(slices.Clone(cand), func(o option) bool { _, ok := pickable(o); return !ok })
|
||||
}
|
||||
q := v.input.Value()
|
||||
@@ -438,13 +430,13 @@ func (m *Model) handleSearch(msg tea.KeyPressMsg) tea.Cmd {
|
||||
return nil
|
||||
case key.Matches(msg, k.sel):
|
||||
switch {
|
||||
case v.results && v.res < len(v.shown) && v.pick != nil:
|
||||
case v.results && v.res < len(v.shown) && v.picker != nil:
|
||||
r, _ := pickable(v.shown[v.res])
|
||||
return v.pick(m, r) // the picker closes when it's done
|
||||
return v.picker.choose(m, r)
|
||||
case v.results && v.res < len(v.shown):
|
||||
m.search = nil
|
||||
return v.shown[v.res].run(m)
|
||||
case !v.results && v.pick != nil:
|
||||
case !v.results && v.picker != nil:
|
||||
v.results = true // a picker only narrows to the scope
|
||||
case !v.results && v.onSource():
|
||||
m.search = nil
|
||||
@@ -662,15 +654,14 @@ func (m Model) searchViewBox() string {
|
||||
focused := !m.termBlurred
|
||||
w := searchWidth(m.w)
|
||||
popupW := w
|
||||
if v.pick != nil {
|
||||
if v.picker != nil {
|
||||
w -= 4 // inside the picker's border, in the popup
|
||||
}
|
||||
listH := max(5, min(m.h-10, 14))
|
||||
if v.pick != nil {
|
||||
// What it's for, the help, the tabs and a border more.
|
||||
if v.picker != nil {
|
||||
// What it's for, the help, a line or two on the key picked, the
|
||||
// tabs and a border more.
|
||||
listH = max(5, min(m.h-10-len(v.pickLines)-len(v.pickHelp)-8, 14))
|
||||
listH = max(5, min(m.h-10-len(v.picker.lines)-len(v.picker.help)-8, 14))
|
||||
}
|
||||
|
||||
srcW := 10
|
||||
@@ -765,16 +756,16 @@ func (m Model) searchViewBox() string {
|
||||
|
||||
ts := panes.TitleStyle(m.st, focused)
|
||||
var body []string
|
||||
if v.pick != nil {
|
||||
for _, l := range v.pickHelp {
|
||||
if p := v.picker; p != nil {
|
||||
for _, l := range p.help {
|
||||
body = append(body, " "+l)
|
||||
}
|
||||
switch {
|
||||
case v.pickBusy != "":
|
||||
body = append(body, "", " "+m.st.Notice.Render(v.pickBusy))
|
||||
case v.pickErr != "":
|
||||
case p.busy != "":
|
||||
body = append(body, "", " "+m.st.Notice.Render(p.busy))
|
||||
case p.err != "":
|
||||
body = append(body, "")
|
||||
for _, l := range strings.Split(ansi.Wordwrap(v.pickErr, w-4, " "), "\n") {
|
||||
for _, l := range strings.Split(ansi.Wordwrap(p.err, w-4, " "), "\n") {
|
||||
body = append(body, " "+m.st.Error.Render(l))
|
||||
}
|
||||
}
|
||||
@@ -810,25 +801,46 @@ func (m Model) searchViewBox() string {
|
||||
}
|
||||
// Tabs in the title, the current one underlined, like the panes; a
|
||||
// picker has its own title, and the tabs over the input.
|
||||
head := ts.Render(goToTitle+" ") + m.goToTabs(ts)
|
||||
if v.pick == nil {
|
||||
if v.picker == nil {
|
||||
head := ts.Render(goToTitle+" ") + m.goToTabs(ts)
|
||||
return panes.Box(m.st, head, foot, body, w, len(body)+2, focused)
|
||||
}
|
||||
// A picker: in its own border, under what it's for.
|
||||
var outer []string
|
||||
for _, l := range v.pickLines {
|
||||
for _, l := range v.picker.lines {
|
||||
outer = append(outer, " "+l)
|
||||
}
|
||||
outer = append(outer, "")
|
||||
for _, l := range strings.Split(panes.Box(m.st, ts.Render(v.pickHeading), "", body, w, len(body)+2, focused), "\n") {
|
||||
for _, l := range strings.Split(panes.Box(m.st, ts.Render(v.picker.heading), "", body, w, len(body)+2, focused), "\n") {
|
||||
outer = append(outer, " "+l)
|
||||
}
|
||||
return panes.Box(m.st, ts.Render(v.pickTitle), foot, outer, popupW, len(outer)+2, focused)
|
||||
return panes.Box(m.st, ts.Render(v.picker.title), foot, outer, popupW, len(outer)+2, focused)
|
||||
}
|
||||
|
||||
// picker is Go to picking a secret for something (the key to share
|
||||
// with): it lists secrets only, and enter hands the selected one's link
|
||||
// to pick, which closes Go to when it's done with it.
|
||||
type picker struct {
|
||||
pick func(m *Model, r ref.Ref) tea.Cmd
|
||||
title string // the popup's
|
||||
lines []string // what picking is for, above the picker
|
||||
heading string // the picker's title, on its border
|
||||
help []string // inside it, above the tabs
|
||||
busy string // what the pick is doing (picks wait meanwhile)
|
||||
err string // why the secret picked can't be used
|
||||
}
|
||||
|
||||
// choose hands r to the picker, unless it's still busy with one.
|
||||
func (p *picker) choose(m *Model, r ref.Ref) tea.Cmd {
|
||||
if p.busy != "" {
|
||||
return nil
|
||||
}
|
||||
return p.pick(m, r)
|
||||
}
|
||||
|
||||
// selectLabel names what enter does with the selected entry.
|
||||
func (v *searchView) selectLabel() string {
|
||||
if v.pick != nil {
|
||||
if v.picker != nil {
|
||||
return "pick"
|
||||
}
|
||||
return "go"
|
||||
|
||||
Reference in new issue
Block a user