aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/ui/textinput.go54
1 files changed, 37 insertions, 17 deletions
diff --git a/lib/ui/textinput.go b/lib/ui/textinput.go
index d52859b7..08fc2c92 100644
--- a/lib/ui/textinput.go
+++ b/lib/ui/textinput.go
@@ -1,6 +1,7 @@
package ui
import (
+ "context"
"math"
"strings"
"sync"
@@ -28,7 +29,8 @@ type TextInput struct {
text []vaxis.Character
change []func(ti *TextInput)
focusLost []func(ti *TextInput)
- tabcomplete func(s string) ([]opt.Completion, string)
+ tabcomplete func(ctx context.Context, s string) ([]opt.Completion, string)
+ tabcompleteCancel context.CancelFunc
completions []opt.Completion
prefix string
completeIndex int
@@ -45,10 +47,11 @@ type TextInput struct {
func NewTextInput(text string, ui *config.UIConfig) *TextInput {
chars := vaxis.Characters(text)
return &TextInput{
- cells: -1,
- text: chars,
- index: len(chars),
- uiConfig: ui,
+ cells: -1,
+ text: chars,
+ index: len(chars),
+ uiConfig: ui,
+ tabcompleteCancel: func() {},
}
}
@@ -63,7 +66,7 @@ func (ti *TextInput) Prompt(prompt string) *TextInput {
}
func (ti *TextInput) TabComplete(
- tabcomplete func(s string) ([]opt.Completion, string),
+ tabcomplete func(ctx context.Context, s string) ([]opt.Completion, string),
d time.Duration, minChars int, key *config.KeyStroke,
) *TextInput {
ti.tabcomplete = tabcomplete
@@ -342,17 +345,34 @@ func (ti *TextInput) showCompletions(explicit bool) {
// no completer
return
}
- ti.completions, ti.prefix = ti.tabcomplete(ti.StringLeft())
-
- if explicit && len(ti.completions) == 1 {
- // automatically accept if there is only one choice
- ti.completeIndex = 0
- ti.executeCompletion()
- ti.invalidateCompletions()
- } else {
- ti.completeIndex = -1
- }
- Invalidate()
+ if ti.tabcompleteCancel != nil {
+ // Cancel any inflight completions we currently have
+ ti.tabcompleteCancel()
+ }
+ ctx, cancel := context.WithCancel(context.Background())
+ ti.tabcompleteCancel = cancel
+ go func() {
+ defer log.PanicHandler()
+ matches, prefix := ti.tabcomplete(ctx, ti.StringLeft())
+ select {
+ case <-ctx.Done():
+ return
+ default:
+ ti.Lock()
+ defer ti.Unlock()
+ ti.completions = matches
+ ti.prefix = prefix
+ if explicit && len(ti.completions) == 1 {
+ // automatically accept if there is only one choice
+ ti.completeIndex = 0
+ ti.executeCompletion()
+ ti.invalidateCompletions()
+ } else {
+ ti.completeIndex = -1
+ }
+ Invalidate()
+ }
+ }()
}
func (ti *TextInput) OnChange(onChange func(ti *TextInput)) {