/
completion.go
62 lines (54 loc) · 1.48 KB
/
completion.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// Copyright (c) 2018 The MATRIX Authors
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php
package jsre
import (
"sort"
"strings"
"github.com/robertkrimen/otto"
)
// CompleteKeywords returns potential continuations for the given line. Since line is
// evaluated, callers need to make sure that evaluating line does not have side effects.
func (jsre *JSRE) CompleteKeywords(line string) []string {
var results []string
jsre.Do(func(vm *otto.Otto) {
results = getCompletions(vm, line)
})
return results
}
func getCompletions(vm *otto.Otto, line string) (results []string) {
parts := strings.Split(line, ".")
objRef := "this"
prefix := line
if len(parts) > 1 {
objRef = strings.Join(parts[0:len(parts)-1], ".")
prefix = parts[len(parts)-1]
}
obj, _ := vm.Object(objRef)
if obj == nil {
return nil
}
iterOwnAndConstructorKeys(vm, obj, func(k string) {
if strings.HasPrefix(k, prefix) {
if objRef == "this" {
results = append(results, k)
} else {
results = append(results, strings.Join(parts[:len(parts)-1], ".")+"."+k)
}
}
})
// Append opening parenthesis (for functions) or dot (for objects)
// if the line itself is the only completion.
if len(results) == 1 && results[0] == line {
obj, _ := vm.Object(line)
if obj != nil {
if obj.Class() == "Function" {
results[0] += "("
} else {
results[0] += "."
}
}
}
sort.Strings(results)
return results
}