From 4c97b1b5de316321762c20ab69fdb3498a00c9bb Mon Sep 17 00:00:00 2001 From: tjblackheart Date: Tue, 9 Sep 2025 15:33:42 +0200 Subject: [PATCH 1/7] add clipboard check, notification & additional key binding --- README.md | 12 +++++------ internal/model/model.go | 45 +++++++++++++++++------------------------ 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index e70fb64..f5abf92 100644 --- a/README.md +++ b/README.md @@ -34,13 +34,13 @@ Since v2.1.3 it is possible to pipe the password from stdin and skip the input q ## Keys ```text -↑/k up -↓/j down -/ filter +↑/k up +↓/j down +/ filter enter show/hide token -u show/hide usernames -c copy -q quit +u show/hide usernames +c/y copy to system clipboard +q quit ``` ## Clipboard config diff --git a/internal/model/model.go b/internal/model/model.go index c9b1537..23a200f 100644 --- a/internal/model/model.go +++ b/internal/model/model.go @@ -33,30 +33,28 @@ type ( ) var ( - style *defaultStyle - state *appState - cb *clipboard.Clipboard + style = newDefaultStyle() + state = new(appState) + cb = new(clipboard.Clipboard) + copyOK = ns().Foreground(green).Render("✓") + copyErr = ns().Foreground(red).Render("✕") ) func New(entries []vaults.Entry, cfg *config.Config) Model { + state.showToken = cfg.Options.ShowTokens + state.showUsernames = cfg.Options.ShowUsernames + items := make([]list.Item, 0) for _, e := range entries { items = append(items, e) } cb = clipboard.New(cfg.ClipboardCmd) - state = &appState{ - showToken: cfg.Options.ShowTokens, - showUsernames: cfg.Options.ShowUsernames, - } - style = newDefaultStyle() title := fmt.Sprintf("%s: %s", buildinfo.AppName, filepath.Base(cfg.File)) - keys := initKeys() - d := &itemDelegate{style} - list := initList(items, d, keys, title) + dlg := &itemDelegate{style} - return Model{list: list} + return Model{list: initList(items, dlg, keys, title)} } func (m Model) Init() tea.Cmd { @@ -78,16 +76,16 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { state.showToken = !state.showToken case "u": state.showUsernames = !state.showUsernames - case "c": + case "c", "y": if !cb.IsInitialized() { - break + msg := fmt.Sprintf("%s No clipboard command available", copyErr) + return m, m.list.NewStatusMessage(msg) } - msg := "Token copied to clipboard" + msg := fmt.Sprintf("%s Token copied to clipboard", copyOK) if err := cb.Set([]byte(state.currentOTP)); err != nil { - msg = fmt.Sprintf("%s: %s", cb.String(), err) + msg = fmt.Sprintf("%s %s: %s", copyErr, cb.String(), err) } - return m, m.list.NewStatusMessage(msg) } @@ -115,16 +113,11 @@ func tick() tea.Cmd { } func initKeys() []key.Binding { - keys := []key.Binding{ - key.NewBinding(key.WithKeys("enter"), key.WithHelp("enter", "show/hide token")), - key.NewBinding(key.WithKeys("u"), key.WithHelp("u", "show/hide usernames")), + return []key.Binding{ + key.NewBinding(key.WithKeys("enter"), key.WithHelp("enter", "toggle token")), + key.NewBinding(key.WithKeys("u"), key.WithHelp("u", "toggle usernames")), + key.NewBinding(key.WithKeys("c", "y"), key.WithHelp("c/y", "yank to clipboard")), } - - if cb != nil && cb.IsInitialized() { - keys = append(keys, key.NewBinding(key.WithKeys("c"), key.WithHelp("c", "copy"))) - } - - return keys } func initList(i []list.Item, d *itemDelegate, k []key.Binding, title string) list.Model { From 2a7276a53358e19a89e745c1cecca776ccbb8b88 Mon Sep 17 00:00:00 2001 From: tjblackheart Date: Tue, 9 Sep 2025 15:37:19 +0200 Subject: [PATCH 2/7] update config stuff --- internal/config/config.go | 23 +++++------------------ internal/config/config_test.go | 30 ------------------------------ 2 files changed, 5 insertions(+), 48 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index b411c65..c3f3c7d 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -33,18 +33,16 @@ type ( // plus given flags into a current app config. Missing dirs apart // from the default system config directory will be created in the process. func Create() (*Config, error) { - - userDir, err := os.UserConfigDir() + dir, err := os.UserConfigDir() if err != nil { - return nil, fmt.Errorf("can not read directory: %s", err) + return nil, fmt.Errorf("unable to read user directory: %s", err) } - - return create(userDir) + return create(dir) } func create(dir string) (*Config, error) { - path, err := createDirectories(filepath.Join(dir, buildinfo.AppName)) - if err != nil { + path := filepath.Join(dir, buildinfo.AppName) + if err := os.MkdirAll(path, os.ModePerm); err != nil { return nil, err } @@ -151,14 +149,3 @@ func (c *Config) validate() error { return nil } - -func createDirectories(path string) (string, error) { - - if _, err := os.Stat(path); os.IsNotExist(err) { - if err := os.MkdirAll(path, os.ModePerm); err != nil { - return "", err - } - } - - return path, nil -} diff --git a/internal/config/config_test.go b/internal/config/config_test.go index aba3ea8..70c3bc5 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -11,36 +11,6 @@ import ( "github.com/tjblackheart/andcli/v2/internal/buildinfo" ) -func Test_createDirectories(t *testing.T) { - wantDir := filepath.Join(os.TempDir(), "andcli_test", "config", buildinfo.AppName) - - tests := []struct { - name string - dir string - fails bool - }{ - {"creates directories", wantDir, false}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := createDirectories(tt.dir) - if (err != nil) != tt.fails { - t.Errorf("createDirectories() error = %v, wantErr %v", err, tt.fails) - return - } - - if _, err := os.Stat(tt.dir); err != nil { - t.Errorf("createDirectories() = %v, want %v", got, tt.dir) - } - - if err := os.RemoveAll(tt.dir); err != nil { - t.Error(err) - } - }) - } -} - func TestConfig_mergeExisting(t *testing.T) { path := filepath.Join(os.TempDir(), "andcli_test_config.yaml") From d55171e261386565b97e07c97308c3fbdb4fa4d7 Mon Sep 17 00:00:00 2001 From: tjblackheart Date: Tue, 9 Sep 2025 15:38:46 +0200 Subject: [PATCH 3/7] clean up --- internal/model/style.go | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/internal/model/style.go b/internal/model/style.go index 672242a..544509d 100644 --- a/internal/model/style.go +++ b/internal/model/style.go @@ -23,10 +23,13 @@ var ns = lipgloss.NewStyle func newDefaultStyle() *defaultStyle { return &defaultStyle{ - title: ns().Background(base).Padding(0, 1), - - listItem: ns().PaddingLeft(2).Faint(true), - + title: ns().Background(base).Padding(0, 1), + listItem: ns().PaddingLeft(2).Faint(true), + username: ns().Background(grey), + filterPrompt: ns().Foreground(base), + filterCursor: ns().Background(base), + token: ns().Bold(true).Padding(0, 1, 0, 1), + until: ns().Bold(true), activeItem: ns(). Padding(0, 1). Bold(true). @@ -34,15 +37,5 @@ func newDefaultStyle() *defaultStyle { Border(lipgloss.ThickBorder(), false, false, false, true). BorderForeground(base). Faint(false), - - username: ns().Background(grey), - - filterPrompt: ns().Foreground(base), - - filterCursor: ns().Background(base), - - token: ns().Bold(true).Padding(0, 1, 0, 1), - - until: ns().Bold(true), } } From 011a43b3a74aa171346872d0745b172b6429ec84 Mon Sep 17 00:00:00 2001 From: tjblackheart Date: Tue, 9 Sep 2025 15:41:03 +0200 Subject: [PATCH 4/7] add test --- internal/vaults/stratum/stratum_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/internal/vaults/stratum/stratum_test.go b/internal/vaults/stratum/stratum_test.go index f416029..f9f213c 100644 --- a/internal/vaults/stratum/stratum_test.go +++ b/internal/vaults/stratum/stratum_test.go @@ -82,3 +82,25 @@ func TestEntries(t *testing.T) { }) } } + +func Test_entry_typeToString(t *testing.T) { + tests := []struct { + name string + e entry + want string + }{ + {"hotp", entry{Type: 1}, "HOTP"}, + {"totp", entry{Type: 2}, "TOTP"}, + {"mobile", entry{Type: 3}, "MOBILE"}, + {"steam", entry{Type: 4}, "STEAM"}, + {"yandex", entry{Type: 5}, "YANDEX"}, + {"unknown", entry{Type: 0}, "UNKNOWN"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.e.typeToString(); got != tt.want { + t.Errorf("entry.typeToString() = %v, want %v", got, tt.want) + } + }) + } +} From 73de356cef21cd221e1799755d778b3b11a30b9f Mon Sep 17 00:00:00 2001 From: tjblackheart Date: Tue, 9 Sep 2025 15:41:43 +0200 Subject: [PATCH 5/7] bump packages --- go.mod | 22 +++++++++++----------- go.sum | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 80b3043..efdd9aa 100644 --- a/go.mod +++ b/go.mod @@ -1,32 +1,32 @@ module github.com/tjblackheart/andcli/v2 -go 1.24 +go 1.25 require ( github.com/ProtonMail/gopenpgp/v3 v3.3.0 github.com/charmbracelet/bubbles v0.21.0 - github.com/charmbracelet/bubbletea v1.3.6 + github.com/charmbracelet/bubbletea v1.3.8 github.com/charmbracelet/lipgloss v1.1.0 github.com/goccy/go-yaml v1.18.0 github.com/grijul/go-andotp v1.0.23 - github.com/spf13/pflag v1.0.7 + github.com/spf13/pflag v1.0.10 github.com/tobischo/gokeepasslib/v3 v3.6.1 github.com/xlzd/gotp v0.1.0 - golang.org/x/crypto v0.40.0 - golang.org/x/term v0.33.0 + golang.org/x/crypto v0.42.0 + golang.org/x/term v0.35.0 ) require ( github.com/ProtonMail/go-crypto v1.3.0 // indirect github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/charmbracelet/colorprofile v0.3.1 // indirect - github.com/charmbracelet/x/ansi v0.9.3 // indirect + github.com/charmbracelet/colorprofile v0.3.2 // indirect + github.com/charmbracelet/x/ansi v0.10.1 // indirect github.com/charmbracelet/x/cellbuf v0.0.13 // indirect github.com/charmbracelet/x/term v0.2.1 // indirect github.com/cloudflare/circl v1.6.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect @@ -37,7 +37,7 @@ require ( github.com/sahilm/fuzzy v0.1.1 // indirect github.com/tobischo/argon2 v0.1.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - golang.org/x/sync v0.16.0 // indirect - golang.org/x/sys v0.34.0 // indirect - golang.org/x/text v0.27.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/text v0.29.0 // indirect ) diff --git a/go.sum b/go.sum index d5516eb..f9ed2ac 100644 --- a/go.sum +++ b/go.sum @@ -12,12 +12,18 @@ github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg= github.com/charmbracelet/bubbletea v1.3.6 h1:VkHIxPJQeDt0aFJIsVxw8BQdh/F/L2KKZGsK6et5taU= github.com/charmbracelet/bubbletea v1.3.6/go.mod h1:oQD9VCRQFF8KplacJLo28/jofOI2ToOfGYeFgBBxHOc= +github.com/charmbracelet/bubbletea v1.3.8 h1:DJlh6UUPhobzomqCtnLJRmhBSxwUJoPPi6iCToUDr4g= +github.com/charmbracelet/bubbletea v1.3.8/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40= github.com/charmbracelet/colorprofile v0.3.1/go.mod h1:/GkGusxNs8VB/RSOh3fu0TJmQ4ICMMPApIIVn0KszZ0= +github.com/charmbracelet/colorprofile v0.3.2 h1:9J27WdztfJQVAQKX2WOlSSRB+5gaKqqITmrvb1uTIiI= +github.com/charmbracelet/colorprofile v0.3.2/go.mod h1:mTD5XzNeWHj8oqHb+S1bssQb7vIHbepiebQ2kPKVKbI= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= github.com/charmbracelet/x/ansi v0.9.3 h1:BXt5DHS/MKF+LjuK4huWrC6NCvHtexww7dMayh6GXd0= github.com/charmbracelet/x/ansi v0.9.3/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= +github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ= +github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k= github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ= @@ -40,6 +46,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= +github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= @@ -61,6 +69,8 @@ github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M= github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tobischo/argon2 v0.1.0 h1:mwAx/9DK/4rP0xzNifb/XMAf43dU3eG1B3aeF88qu4Y= @@ -74,24 +84,34 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJu golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= golang.org/x/exp v0.0.0-20230105202349-8879d0199aa3 h1:fJwx88sMf5RXwDwziL0/Mn9Wqs+efMSo/RYcL+37W9c= golang.org/x/exp v0.0.0-20230105202349-8879d0199aa3/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210601080250-7ecdf8ef093b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg= golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 97d7e402f455fd1becdfbf884e6bdc1ade6e0912 Mon Sep 17 00:00:00 2001 From: tjblackheart Date: Tue, 9 Sep 2025 15:45:41 +0200 Subject: [PATCH 6/7] update README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f5abf92..95fc6f4 100644 --- a/README.md +++ b/README.md @@ -37,9 +37,9 @@ Since v2.1.3 it is possible to pipe the password from stdin and skip the input q ↑/k up ↓/j down / filter -enter show/hide token -u show/hide usernames -c/y copy to system clipboard +enter toggle token visibility +u toggle usernames visibility +c/y yank token to system clipboard q quit ``` From edab6ee0e0ecbea96f8f85eb97d52ab969ad3b21 Mon Sep 17 00:00:00 2001 From: tjblackheart Date: Tue, 9 Sep 2025 15:51:04 +0200 Subject: [PATCH 7/7] remove unneeded file --- internal/model/model_test.go | 48 ------------------------------------ 1 file changed, 48 deletions(-) delete mode 100644 internal/model/model_test.go diff --git a/internal/model/model_test.go b/internal/model/model_test.go deleted file mode 100644 index b64b27f..0000000 --- a/internal/model/model_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package model - -import ( - "reflect" - "testing" - - "github.com/charmbracelet/bubbles/key" - "github.com/tjblackheart/andcli/v2/internal/clipboard" -) - -func Test_initKeys(t *testing.T) { - tests := []struct { - name string - useClipboard bool - want []key.Binding - }{ - { - "inits keys without clipboard", - false, - []key.Binding{ - key.NewBinding(key.WithKeys("enter"), key.WithHelp("enter", "show/hide token")), - key.NewBinding(key.WithKeys("u"), key.WithHelp("u", "show/hide usernames")), - }, - }, - { - "inits keys with clipboard", - true, - []key.Binding{ - key.NewBinding(key.WithKeys("enter"), key.WithHelp("enter", "show/hide token")), - key.NewBinding(key.WithKeys("u"), key.WithHelp("u", "show/hide usernames")), - key.NewBinding(key.WithKeys("c"), key.WithHelp("c", "copy")), - }, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - cb = nil - if tt.useClipboard { - cb = clipboard.New("test") - } - - if got := initKeys(); !reflect.DeepEqual(got, tt.want) { - t.Errorf("initKeys() = %v, want %v", got, tt.want) - } - }) - } -}