Skip to content

Commit

Permalink
Improve termwiz selection (#385)
Browse files Browse the repository at this point in the history
This commit fixes some useability issues with the termwiz selection
wizard, makes it more flexible and add a sync hotkey to the selection.

Fixes #320
  • Loading branch information
dominikschulz authored Oct 9, 2017
1 parent b661226 commit e8e06e9
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 8 deletions.
8 changes: 7 additions & 1 deletion action/find.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")
}
Expand Down
4 changes: 2 additions & 2 deletions action/recipients.go
Original file line number Diff line number Diff line change
Expand Up @@ -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, <ESC> to quit", choices)
switch act {
case "show":
recipients = []string{choices[sel]}
Expand Down Expand Up @@ -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, <ESC> to quit", choices)
switch act {
case "show":
recipients = []string{choices[sel]}
Expand Down
29 changes: 24 additions & 5 deletions utils/termwiz/selection.go
Original file line number Diff line number Diff line change
@@ -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"
)
Expand All @@ -16,33 +18,45 @@ 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)

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 {
mark = ">"
}
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, <ESC> to quit")
usageLine := usage
if usageLine == "" {
usageLine = "<↑/↓> to change the selection, <→> to show, <←> to copy, <s> to sync, <ESC> 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:
Expand All @@ -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 {
Expand All @@ -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
}
}
}
Expand Down

0 comments on commit e8e06e9

Please sign in to comment.