Skip to content

Commit

Permalink
interp: Fix input completion regression in sub-REPLs
Browse files Browse the repository at this point in the history
readline Config was used to pass completer function per readline call,
was changed in #612 and caused regression. Now use our own member in
stdOS to pass it instead.

Add a test but test script completer is implemented differently.
  • Loading branch information
wader committed Mar 10, 2023
1 parent fcacd7e commit 3dd2c61
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 11 deletions.
27 changes: 17 additions & 10 deletions pkg/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func maybeLogFile() {
}
}

// function implementing readline.AutoComplete interface
type autoCompleterFn func(line []rune, pos int) (newLine [][]rune, length int)

func (a autoCompleterFn) Do(line []rune, pos int) (newLine [][]rune, length int) {
Expand All @@ -38,6 +39,7 @@ type stdOS struct {
historyFile string
closeChan chan struct{}
interruptChan chan struct{}
completerFn interp.CompleteFn
}

func newStandardOS() *stdOS {
Expand Down Expand Up @@ -174,24 +176,29 @@ func (o *stdOS) Readline(opts interp.ReadlineOpts) (string, error) {
HistoryFile: historyFile,
HistorySearchFold: true,
}
if opts.CompleteFn != nil {
cfg.AutoComplete = autoCompleterFn(func(line []rune, pos int) (newLine [][]rune, length int) {
names, shared := opts.CompleteFn(string(line), pos)
var runeNames [][]rune
for _, name := range names {
runeNames = append(runeNames, []rune(name[shared:]))
}
cfg.AutoComplete = autoCompleterFn(func(line []rune, pos int) (newLine [][]rune, length int) {
if o.completerFn != nil {
return nil, 0
}

return runeNames, shared
})
}
names, shared := o.completerFn(string(line), pos)
var runeNames [][]rune
for _, name := range names {
runeNames = append(runeNames, []rune(name[shared:]))
}

return runeNames, shared
})
o.rl, err = readline.NewEx(cfg)
if err != nil {
return "", err
}
o.historyFile = historyFile
}

// inject completer to autocompleter
o.completerFn = opts.CompleteFn

o.rl.SetPrompt(opts.Prompt)
line, err := o.rl.Readline()
if errors.Is(err, readline.ErrInterrupt) {
Expand Down
4 changes: 3 additions & 1 deletion pkg/interp/interp.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,11 @@ type Platform struct {
Arch string
}

type CompleteFn func(line string, pos int) (newLine []string, shared int)

type ReadlineOpts struct {
Prompt string
CompleteFn func(line string, pos int) (newLine []string, shared int)
CompleteFn CompleteFn
}

type OS interface {
Expand Down
4 changes: 4 additions & 0 deletions pkg/interp/testdata/completion.fqtest
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,8 @@ color
colors
compact
completion_timeout
mp3> .frames[0] | repl
> .frames[0] mp3_frame> .he\t
header
> .frames[0] mp3_frame> ^D
mp3> ^D

0 comments on commit 3dd2c61

Please sign in to comment.