feat: ui.recentIcon marks items used lately with ◷, and lazysecrets list --recent

This commit is contained in:
keb committed 2026-10-14 21:24:01 +02:00
1 parent 33a9b0864d
commit 33fa064104
9 files changed
+87 -22

No files matched your search

+3
View File
@@ -44,6 +44,9 @@ type Config struct {
type UI struct {
Icons *bool `yaml:"icons"`
// RecentIcon marks items used lately (Recent, R) with ◷, in the lists
// and in lazysecrets list. Defaults to false.
RecentIcon *bool `yaml:"recentIcon"`
// SourcesView is "grouped" (default) or "flat"; ` + "`" + ` toggles it.
SourcesView string `yaml:"sourcesView"`
// CollapseGroups starts the Sources pane with its groups folded;
+6 -1
View File
@@ -131,6 +131,9 @@ type Options struct {
HandlerSetup *HandlerSetup
// NoHistory stops counting uses of items for the Recent list.
NoHistory bool
// RecentIcon marks items used lately with ◷ in the lists
// (ui.recentIcon).
RecentIcon bool
// Open is a reference to open at startup (lazysecrets open <ref>).
Open *ref.Ref
// OpenAction, if set, is what to do with Open, rather than asking:
@@ -287,6 +290,7 @@ type Model struct {
prompt *modal // popup that has the keyboard
linked []provider.Container // vaults opened from links, this session
open *ref.Ref // reference to open at startup
recentIcon bool // mark items used lately (◷)
openAction string // and what to do with it, or ask
shareKey string // the config's sharing.key
@@ -420,7 +424,8 @@ func New(providers []provider.Provider, opts Options) Model {
if m.store == nil {
m.store, _ = store.Load("")
}
m.sources = newSourcesList(iconSet, m.store)
m.recentIcon = opts.RecentIcon
m.sources = newSourcesList(iconSet, m.store, m.recentIcon)
m.sources.Empty = "no sources found"
m.collapsed = map[string]bool{}
m.flatSources = opts.FlatSources
+18 -6
View File
@@ -19,6 +19,22 @@ import (
const star = "★ "
// recentMark marks items used lately (Recent), with ui.recentIcon.
const recentMark = "◷ "
// marks is what goes before a list row's name: ★ when it's starred for
// account and, with recent, ◷ when it was used lately.
func marks(st styles.Styles, n store.Node, account string, recent bool) string {
var s string
if n.StarredFor(account) {
s = st.Favourite.Render(star)
}
if recent && !n.LastUsed.IsZero() {
s += st.Muted.Render(recentMark)
}
return s
}
func sourceKey(s provider.Source) string {
if r, err := ref.ForSource(s); err == nil {
return r.String()
@@ -94,9 +110,7 @@ func (m Model) containerRender(withSource bool) func(styles.Styles, provider.Con
}
line += sty.Muted.Render(" " + c.Detail)
}
if n.StarredFor(c.Source.Provider) {
line = sty.Favourite.Render(star) + line
}
line = marks(sty, n, c.Source.Provider, m.recentIcon) + line
if withSource {
src := c.Source.Name
if account, ok := strings.CutPrefix(c.Source.ProviderLabel, string(c.Source.Kind)+" · "); ok {
@@ -116,9 +130,7 @@ func (m Model) objectRender() func(styles.Styles, provider.Object, int) string {
if o.Enabled != nil && !*o.Enabled {
line = sty.Muted.Render(o.Name + " (disabled)")
}
if n.StarredFor(o.Container.Source.Provider) {
line = sty.Favourite.Render(star) + line
}
line = marks(sty, n, o.Container.Source.Provider, m.recentIcon) + line
switch state, left := m.expiry(o); state {
case expired:
line += " " + sty.Error.Render("✗ expired")
+18
View File
@@ -6,6 +6,7 @@ import (
"slices"
"strings"
"testing"
"time"
tea "charm.land/bubbletea/v2"
"charm.land/lipgloss/v2"
@@ -434,3 +435,20 @@ func TestStarIsPerAccount(t *testing.T) {
t.Errorf("favourites should list alice's star only: %q", labels)
}
}
func TestRecentIcon(t *testing.T) {
t.Parallel()
mem, _ := store.Load("")
_ = mem.Use("lazysecrets://azure/"+kv+"/secrets/api-key", time.Now(), func(*store.Node) {})
d := newDriverOpts(t, Options{Store: mem, RecentIcon: true})
d.keys("3")
scr := d.screen()
if !strings.Contains(scr, "◷ api-key") || strings.Contains(scr, "◷ db-password") {
t.Errorf("want ◷ on api-key only:\n%s", scr)
}
off := newDriverOpts(t, Options{Store: mem})
off.keys("3")
if strings.Contains(off.screen(), "◷") {
t.Errorf("◷ without ui.recentIcon:\n%s", off.screen())
}
}
+3 -3
View File
@@ -57,7 +57,7 @@ func sourceRowID(r sourceRow) string {
return sourceRowKey(r.provider, r.source.ID)
}
func newSourcesList(iconSet icons.Set, mem *store.Store) panes.List[sourceRow] {
func newSourcesList(iconSet icons.Set, mem *store.Store, recent bool) panes.List[sourceRow] {
return panes.NewList("[1] Sources", panes.Item[sourceRow]{
ID: sourceRowID,
// Headers have no filter text, so filtering shows just sources.
@@ -79,8 +79,8 @@ func newSourcesList(iconSet icons.Set, mem *store.Store) panes.List[sourceRow] {
node := mem.Node(sourceKey(r.source))
kind := st.Kind(r.group)
starred := ""
if r.kind == rowSource && node.StarredFor(r.source.Provider) {
starred = st.Favourite.Render(star)
if r.kind == rowSource {
starred = marks(st, node, r.source.Provider, recent)
}
switch {
case r.kind == rowLinks: