feat: the right pane describes what's selected in the pane you're in
CI / Checks (pull_request) Successful in 25s
PR title / Conventional title (pull_request) Successful in 1s

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kebandClaude Opus 5.5 committed 2026-10-11 10:49:39 +02:00
1 parent c8abc1dc95
commit 411068ba43
9 files changed
+232 -67

No files matched your search

-11
View File
@@ -46,7 +46,6 @@ type Detail struct {
versions []provider.Object // newest first; nil while unknown
note string // the user's note on what's shown
message string // shown instead of the hint when nothing is selected: an error
offset int
w, h int
@@ -72,10 +71,6 @@ func (d *Detail) Clear() {
*d = Detail{Now: d.Now, Icons: d.Icons, RevealKey: d.RevealKey, VersionsKey: d.VersionsKey, CopyKey: d.CopyKey, w: d.w, h: d.h} // drops the note too
}
// SetMessage sets what's shown instead of the hint when nothing is
// selected, such as why an account has nothing to show; "" for the hint.
func (d *Detail) SetMessage(s string) { d.message = s }
// SetDescribing marks extra metadata as being fetched.
func (d *Detail) SetDescribing() { d.describing, d.describeErr = true, nil }
@@ -191,12 +186,6 @@ func (d Detail) lines(st styles.Styles) []string {
muted := st.Muted.Render
if d.container == nil {
if d.message != "" {
for _, l := range strings.Split(ansi.Hardwrap(d.message, max(1, inner-2), true), "\n") {
out = append(out, " "+st.Error.Render(l))
}
return out
}
return []string{muted(" Select a vault or scope to browse its secrets.")}
}
c := *d.container
+18 -12
View File
@@ -15,13 +15,14 @@ import (
// have Detail, for revealing and versions.
type Fields struct {
List[Field]
shown bool
}
// Field is a row: a value under a label. Info rows (loading, errors)
// can't be copied.
// can't be copied; Err ones are errors.
type Field struct {
Label, Value string
Info bool
Info, Err bool
}
func NewFields() Fields {
@@ -32,30 +33,35 @@ func NewFields() Fields {
FilterExtra: func(f Field) string { return f.Label },
Render: func(st styles.Styles, f Field, width int) string {
value := f.Value
if f.Info {
switch {
case f.Err:
value = st.Error.Render(value)
case f.Info:
value = st.Muted.Render(value)
}
return ansi.Truncate(st.Label.Render(fmt.Sprintf("%-10s", f.Label))+" "+value, width, "…")
},
})
l.Empty = "nothing to show"
return Fields{l}
return Fields{List: l}
}
// Set shows fields under title. Another title (another account or vault)
// starts over, without a filter.
func (s *Fields) Set(title string, fields []Field) {
// Show shows fields under title, instead of the secret pane. Another
// title (another account or vault) starts over, without a filter.
func (s *Fields) Show(title string, fields []Field) {
if title != s.Title {
s.Reset()
s.Title = title
}
if len(fields) > 0 || len(s.Items()) > 0 {
s.SetItems(fields)
}
s.shown = true
s.SetItems(fields)
}
// Shown reports whether there's anything to show.
func (s Fields) Shown() bool { return len(s.Items()) > 0 }
// Hide gives the fourth pane back to the secret pane.
func (s *Fields) Hide() { s.shown = false }
// Shown reports whether the fourth pane shows Fields.
func (s Fields) Shown() bool { return s.shown }
// Selected is the field under the cursor, unless it's an info row.
func (s Fields) Selected() (Field, bool) {