diff options
Diffstat (limited to 'completer')
-rw-r--r-- | completer/completer.go | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/completer/completer.go b/completer/completer.go index 5a5dea10..670db34d 100644 --- a/completer/completer.go +++ b/completer/completer.go @@ -2,6 +2,7 @@ package completer import ( "bufio" + "context" "errors" "fmt" "io" @@ -13,7 +14,7 @@ import ( "git.sr.ht/~rjarry/aerc/lib/format" "git.sr.ht/~rjarry/aerc/lib/log" - "git.sr.ht/~rjarry/go-opt" + "git.sr.ht/~rjarry/go-opt/v2" ) // A Completer is used to autocomplete text inputs based on the configured @@ -31,7 +32,7 @@ type Completer struct { // A CompleteFunc accepts a string to be completed and returns a slice of // completions candidates with a prefix to prepend to the chosen candidate -type CompleteFunc func(string) ([]string, string) +type CompleteFunc func(context.Context, string) ([]opt.Completion, string) // New creates a new Completer with the specified address book command. func New(addressBookCmd string, errHandler func(error)) *Completer { @@ -51,11 +52,11 @@ func (c *Completer) ForHeader(h string) CompleteFunc { return nil } // wrap completeAddress in an error handler - return func(s string) ([]string, string) { - completions, prefix, err := c.completeAddress(s) + return func(ctx context.Context, s string) ([]opt.Completion, string) { + completions, prefix, err := c.completeAddress(ctx, s) if err != nil { c.handleErr(err) - return []string{}, "" + return []opt.Completion{}, "" } return completions, prefix } @@ -80,9 +81,9 @@ var tooManyLines = fmt.Errorf("returned more than %d lines", maxCompletionLines) // completeAddress uses the configured address book completion command to fetch // completions for the specified string, returning a slice of completions and // a prefix to be prepended to the selected completion, or an error. -func (c *Completer) completeAddress(s string) ([]string, string, error) { +func (c *Completer) completeAddress(ctx context.Context, s string) ([]opt.Completion, string, error) { prefix, candidate := c.parseAddress(s) - cmd, err := c.getAddressCmd(candidate) + cmd, err := c.getAddressCmd(ctx, candidate) if err != nil { return nil, "", err } @@ -137,7 +138,7 @@ func (c *Completer) parseAddress(s string) (string, string) { // getAddressCmd constructs an exec.Cmd based on the configured command and // specified query. -func (c *Completer) getAddressCmd(s string) (*exec.Cmd, error) { +func (c *Completer) getAddressCmd(ctx context.Context, s string) (*exec.Cmd, error) { if strings.TrimSpace(c.AddressBookCmd) == "" { return nil, fmt.Errorf("no command configured") } @@ -147,18 +148,18 @@ func (c *Completer) getAddressCmd(s string) (*exec.Cmd, error) { return nil, fmt.Errorf("empty command") } if len(parts) > 1 { - return exec.Command(parts[0], parts[1:]...), nil + return exec.CommandContext(ctx, parts[0], parts[1:]...), nil } - return exec.Command(parts[0]), nil + return exec.CommandContext(ctx, parts[0]), nil } // readCompletions reads a slice of completions from r line by line. Each line // must consist of tab-delimited fields. Only the first field (the email // address field) is required, the second field (the contact name) is optional, // and subsequent fields are ignored. -func readCompletions(r io.Reader) ([]string, error) { +func readCompletions(r io.Reader) ([]opt.Completion, error) { buf := bufio.NewReader(r) - completions := []string{} + var completions []opt.Completion for i := 0; i < maxCompletionLines; i++ { line, err := buf.ReadString('\n') if errors.Is(err, io.EOF) { @@ -180,7 +181,9 @@ func readCompletions(r io.Reader) ([]string, error) { if len(parts) > 1 { addr.Name = strings.TrimSpace(parts[1]) } - completions = append(completions, format.AddressForHumans(addr)) + completions = append(completions, opt.Completion{ + Value: format.AddressForHumans(addr), + }) } return completions, tooManyLines } |