github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/internal/jsre/completion.go (about)

     1  // This file is part of the go-sberex library. The go-sberex library is 
     2  // free software: you can redistribute it and/or modify it under the terms 
     3  // of the GNU Lesser General Public License as published by the Free 
     4  // Software Foundation, either version 3 of the License, or (at your option)
     5  // any later version.
     6  //
     7  // The go-sberex library is distributed in the hope that it will be useful, 
     8  // but WITHOUT ANY WARRANTY; without even the implied warranty of
     9  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 
    10  // General Public License <http://www.gnu.org/licenses/> for more details.
    11  
    12  package jsre
    13  
    14  import (
    15  	"sort"
    16  	"strings"
    17  
    18  	"github.com/robertkrimen/otto"
    19  )
    20  
    21  // CompleteKeywords returns potential continuations for the given line. Since line is
    22  // evaluated, callers need to make sure that evaluating line does not have side effects.
    23  func (jsre *JSRE) CompleteKeywords(line string) []string {
    24  	var results []string
    25  	jsre.Do(func(vm *otto.Otto) {
    26  		results = getCompletions(vm, line)
    27  	})
    28  	return results
    29  }
    30  
    31  func getCompletions(vm *otto.Otto, line string) (results []string) {
    32  	parts := strings.Split(line, ".")
    33  	objRef := "this"
    34  	prefix := line
    35  	if len(parts) > 1 {
    36  		objRef = strings.Join(parts[0:len(parts)-1], ".")
    37  		prefix = parts[len(parts)-1]
    38  	}
    39  
    40  	obj, _ := vm.Object(objRef)
    41  	if obj == nil {
    42  		return nil
    43  	}
    44  	iterOwnAndConstructorKeys(vm, obj, func(k string) {
    45  		if strings.HasPrefix(k, prefix) {
    46  			if objRef == "this" {
    47  				results = append(results, k)
    48  			} else {
    49  				results = append(results, strings.Join(parts[:len(parts)-1], ".")+"."+k)
    50  			}
    51  		}
    52  	})
    53  
    54  	// Append opening parenthesis (for functions) or dot (for objects)
    55  	// if the line itself is the only completion.
    56  	if len(results) == 1 && results[0] == line {
    57  		obj, _ := vm.Object(line)
    58  		if obj != nil {
    59  			if obj.Class() == "Function" {
    60  				results[0] += "("
    61  			} else {
    62  				results[0] += "."
    63  			}
    64  		}
    65  	}
    66  
    67  	sort.Strings(results)
    68  	return results
    69  }