// Package complete implements the code completion algorithm for Elvish.
package complete import ( ) type item = mode.CompletionItem // An error returned by Complete if the config has not supplied a PureEvaler. var errNoPureEvaler = errors.New("no PureEvaler supplied") // An error returned by Complete as well as the completers if there is no // applicable completion. var errNoCompletion = errors.New("no completion") // Config stores the configuration required for code completion. type Config struct { // An interface to access the runtime. Complete will return an error if this // is nil. PureEvaler PureEvaler // A function for filtering raw candidates. If nil, no filtering is done. Filterer Filterer // Used to generate candidates for a command argument. Defaults to // Filenames. ArgGenerator ArgGenerator } // Filterer is the type of functions that filter raw candidates. type Filterer func(ctxName, seed string, rawItems []RawItem) []RawItem // ArgGenerator is the type of functions that generate raw candidates for a // command argument. It takes all the existing arguments, the last being the // argument to complete, and returns raw candidates or an error. type ArgGenerator func(args []string) ([]RawItem, error) // Result keeps the result of the completion algorithm. type Result struct { Name string Replace diag.Ranging Items []mode.CompletionItem } // RawItem represents completion items before the quoting pass. type RawItem interface { String() string Cook(parse.PrimaryType) mode.CompletionItem } // PureEvaler encapsulates the functionality the completion algorithm needs from // the language runtime. type PureEvaler interface { EachExternal(func(cmd string)) EachSpecial(func(special string)) EachNs(func(string)) EachVariableInNs(string, func(string)) PurelyEvalPrimary(pn *parse.Primary) interface{} PurelyEvalCompound(*parse.Compound) (string, bool) PurelyEvalPartialCompound(*parse.Compound, int) (string, bool) } // CodeBuffer is the same the type in src.elv.sh/pkg/el/codearea, // replicated here to avoid an unnecessary dependency. type CodeBuffer struct { Content string Dot int } // Complete runs the code completion algorithm in the given context, and returns // the completion type, items and any error encountered. func ( CodeBuffer, Config) (*Result, error) { if .PureEvaler == nil { return nil, errNoPureEvaler } if .Filterer == nil { .Filterer = FilterPrefix } if .ArgGenerator == nil { .ArgGenerator = GenerateFileNames } // Ignore the error; the function always returns a valid *ChunkNode. , := parse.Parse(parse.Source{Name: "[interactive]", Code: .Content}, parse.Config{}) := parseutil.FindLeafNode(.Root, .Dot) for , := range completers { , , := (, ) if == errNoCompletion { continue } = .Filterer(.name, .seed, ) := make([]mode.CompletionItem, len()) for , := range { [] = .Cook(.quote) } sort.Slice(, func(, int) bool { return [].ToShow < [].ToShow }) = dedup() return &Result{Name: .name, Items: , Replace: .interval}, nil } return nil, errNoCompletion } func ( []mode.CompletionItem) []mode.CompletionItem { var []mode.CompletionItem for , := range { if == 0 || .ToInsert != [-1].ToInsert { = append(, ) } } return }