func startCompletion(ed *Editor, k Key) *leReturn { c := &completion{} ctx, err := parse.Complete("<completion>", ed.line[:ed.dot]) if err != nil { ed.pushTip("parser error") return nil } compound, start, err := peekCurrentCompound(ctx, ed.dot) if err != nil { ed.pushTip("cannot complete :(") return nil } switch ctx.Typ { case parse.CommandContext: // BUG(xiaq): When completing, CommandContext is not supported ed.pushTip("command context not yet supported :(") case parse.NewArgContext, parse.ArgContext: // BUG(xiaq): When completing, [New]ArgContext is treated like RedirFilenameContext fallthrough case parse.RedirFilenameContext: // BUG(xiaq): When completing, only plain expressions are supported names, err := fileNames(".") if err != nil { ed.pushTip(err.Error()) return nil } c.start = start c.end = ed.dot // BUG(xiaq) When completing, completion.typ is always ItemBare c.typ = parse.ItemBare c.candidates = findCandidates(compound, names) if len(c.candidates) > 0 { // TODO(xiaq): Support completions other than filename completion for _, c := range c.candidates { c.attr = defaultLsColor.determineAttr(c.text) } ed.completion = c ed.mode = modeCompletion } else { ed.pushTip(fmt.Sprintf("No completion for %s", compound)) } } return nil }
func startCompletion(ed *Editor, k Key) *leReturn { c := &completion{} ctx, err := parse.Complete("<completion>", ed.line[:ed.dot]) if err != nil { ed.pushTip("parser error: " + err.Error()) return nil } compound, start, err := peekCurrentCompound(ctx, ed.dot) if err != nil { ed.pushTip("cannot complete: " + err.Error()) return nil } var findAll func() ([]string, error) var makeCandidates func([]string) []*candidate switch ctx.Typ { case parse.CommandContext: // BUG(xiaq): When completing commands, only builtins are searched findAll = func() ([]string, error) { return builtins, nil } makeCandidates = func(all []string) (cands []*candidate) { return prefixMatchCandidates(compound, all) } case parse.NewArgContext, parse.ArgContext: // BUG(xiaq): When completing, [New]ArgContext is treated like RedirFilenameContext fallthrough case parse.RedirFilenameContext: // BUG(xiaq): File name completion does not deal with meta characters. // Assume that compound is an incomplete filename dir, file := path.Split(compound) findAll = func() ([]string, error) { if dir == "" { return fileNames(".") } return fileNames(dir) } makeCandidates = func(all []string) (cands []*candidate) { // Make candidates out of elements that match the file component. for _, s := range all { if strings.HasPrefix(s, file) { cand := newCandidate() cand.push(tokenPart{compound, false}) cand.push(tokenPart{s[len(file):], true}) cand.attr = defaultLsColor.determineAttr(cand.text) cands = append(cands, cand) } } return } } // BUG(xiaq): When completing, only plain expressions are supported all, err := findAll() if err != nil { ed.pushTip(err.Error()) return nil } c.start = start c.end = ed.dot // BUG(xiaq) When completing, completion.typ is always ItemBare c.typ = parse.ItemBare c.candidates = makeCandidates(all) if len(c.candidates) > 0 { ed.completion = c ed.mode = modeCompletion } else { ed.pushTip(fmt.Sprintf("No completion for %s", compound)) } return nil }