mirror of
https://github.com/robertkrimen/otto
synced 2025-10-05 19:19:10 +08:00
add tab-complete to repl
This commit is contained in:
parent
6e7c8df250
commit
c3d9ea142b
57
repl/autocompleter.go
Normal file
57
repl/autocompleter.go
Normal file
|
@ -0,0 +1,57 @@
|
|||
package repl
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/robertkrimen/otto"
|
||||
)
|
||||
|
||||
type autoCompleter struct {
|
||||
vm *otto.Otto
|
||||
}
|
||||
|
||||
var lastExpressionRegex = regexp.MustCompile(`[a-zA-Z0-9]([a-zA-Z0-9\.]*[a-zA-Z0-9])?\.?$`)
|
||||
|
||||
func (a *autoCompleter) Do(line []rune, pos int) ([][]rune, int) {
|
||||
lastExpression := lastExpressionRegex.FindString(string(line))
|
||||
|
||||
bits := strings.Split(lastExpression, ".")
|
||||
|
||||
first := bits[:len(bits)-1]
|
||||
last := bits[len(bits)-1]
|
||||
|
||||
var l []string
|
||||
|
||||
if len(first) == 0 {
|
||||
c := a.vm.Context()
|
||||
|
||||
l = make([]string, len(c.Symbols))
|
||||
|
||||
i := 0
|
||||
for k := range c.Symbols {
|
||||
l[i] = k
|
||||
i++
|
||||
}
|
||||
} else {
|
||||
r, err := a.vm.Eval(strings.Join(bits[:len(bits)-1], "."))
|
||||
if err != nil {
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
if o := r.Object(); o != nil {
|
||||
for _, v := range o.KeysByParent() {
|
||||
l = append(l, v...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var r [][]rune
|
||||
for _, s := range l {
|
||||
if strings.HasPrefix(s, last) {
|
||||
r = append(r, []rune(strings.TrimPrefix(s, last)))
|
||||
}
|
||||
}
|
||||
|
||||
return r, len(last)
|
||||
}
|
|
@ -48,7 +48,12 @@ func RunWithPromptAndPrelude(vm *otto.Otto, prompt, prelude string) error {
|
|||
prompt = strings.Trim(prompt, " ")
|
||||
prompt += " "
|
||||
|
||||
rl, err := readline.New(prompt)
|
||||
c := &readline.Config{
|
||||
Prompt: prompt,
|
||||
AutoComplete: &autoCompleter{vm},
|
||||
}
|
||||
|
||||
rl, err := readline.NewEx(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user