diff --git a/action/find.go b/action/find.go index b860c1f6b9..ee54799fc2 100644 --- a/action/find.go +++ b/action/find.go @@ -54,7 +54,7 @@ func (s *Action) Find(ctx context.Context, c *cli.Context) error { return nil } - act, sel := termwiz.GetSelection(choices) + act, sel := termwiz.GetSelection(ctx, "Found secrets -", "", choices) switch act { case "copy": // display selected entry @@ -64,6 +64,12 @@ func (s *Action) Find(ctx context.Context, c *cli.Context) error { // display selected entry fmt.Println(choices[sel]) return s.show(ctx, c, choices[sel], "", clip, false, false, false) + case "sync": + // run sync and re-run show/find workflow + if err := s.Sync(ctx, c); err != nil { + return err + } + return s.show(ctx, c, needle, "", clip, false, false, true) default: return s.exitError(ctx, ExitAborted, nil, "user aborted") } diff --git a/action/recipients.go b/action/recipients.go index 77ce579228..756c072869 100644 --- a/action/recipients.go +++ b/action/recipients.go @@ -76,7 +76,7 @@ func (s *Action) RecipientsAdd(ctx context.Context, c *cli.Context) error { choices = append(choices, key.OneLine()) } if len(choices) > 0 { - act, sel := termwiz.GetSelection(choices) + act, sel := termwiz.GetSelection(ctx, "Add Recipient -", "<↑/↓> to change the selection, <→> to add this recipient, to quit", choices) switch act { case "show": recipients = []string{choices[sel]} @@ -135,7 +135,7 @@ func (s *Action) RecipientsRemove(ctx context.Context, c *cli.Context) error { } } if len(choices) > 0 { - act, sel := termwiz.GetSelection(choices) + act, sel := termwiz.GetSelection(ctx, "Remove recipient -", "<↑/↓> to change the selection, <→> to remove this recipient, to quit", choices) switch act { case "show": recipients = []string{choices[sel]} diff --git a/utils/termwiz/selection.go b/utils/termwiz/selection.go index a79b9a89aa..7f2ed870a2 100644 --- a/utils/termwiz/selection.go +++ b/utils/termwiz/selection.go @@ -1,8 +1,10 @@ package termwiz import ( + "context" "fmt" + "github.com/justwatchcom/gopass/utils/ctxutil" runewidth "github.com/mattn/go-runewidth" "github.com/nsf/termbox-go" ) @@ -16,11 +18,16 @@ func tbprint(x, y int, fg, bg termbox.Attribute, msg string) { // GetSelection show a navigateable multiple-choice list to the user // and returns the selected entry along with the action -func GetSelection(choices []string) (string, int) { +func GetSelection(ctx context.Context, prompt, usage string, choices []string) (string, int) { + if prompt != "" { + prompt += " " + } + if err := termbox.Init(); err != nil { panic(err) } defer termbox.Close() + termbox.SetInputMode(termbox.InputEsc) const coldef = termbox.ColorDefault _ = termbox.Clear(coldef, coldef) @@ -28,13 +35,13 @@ func GetSelection(choices []string) (string, int) { cur := 0 for { _ = termbox.Clear(coldef, coldef) - tbprint(0, 0, coldef, coldef, "Please select:") + tbprint(0, 0, coldef, coldef, prompt+"Please select:") _, h := termbox.Size() offset := 0 - if len(choices)+2 > h { + if len(choices)+2 > h && cur > h-3 { offset = cur } - for i := offset; i < len(choices) && i < h; i++ { + for i := offset; i < len(choices) && i-offset < h; i++ { c := choices[i] mark := " " if cur == i { @@ -42,7 +49,14 @@ func GetSelection(choices []string) (string, int) { } tbprint(0, 1+i-offset, coldef, coldef, fmt.Sprintf("%s %s\n", mark, c)) } - tbprint(0, h-1, coldef, coldef, "<↑/↓> to change the selection, <→> to show, <←> to copy, to quit") + usageLine := usage + if usageLine == "" { + usageLine = "<↑/↓> to change the selection, <→> to show, <←> to copy, to sync, to quit" + } + if ctxutil.IsDebug(ctx) { + usageLine += " - DEBUG: " + fmt.Sprintf("Offset: %d - Cur: %d - Choices: %d", offset, cur, len(choices)) + } + tbprint(0, h-1, coldef, coldef, usageLine) _ = termbox.Flush() switch ev := termbox.PollEvent(); ev.Type { case termbox.EventKey: @@ -64,6 +78,7 @@ func GetSelection(choices []string) (string, int) { if cur < 0 { cur = len(choices) - 1 } + continue default: if ev.Ch != 0 { switch ev.Ch { @@ -74,13 +89,17 @@ func GetSelection(choices []string) (string, int) { if cur >= len(choices) { cur = 0 } + continue case 'k': cur-- if cur < 0 { cur = len(choices) - 1 } + continue case 'l': return "show", cur + case 's': + return "sync", cur } } }