Path: blob/main/vendor/github.com/chzyer/readline/complete_helper.go
2875 views
package readline12import (3"bytes"4"strings"5)67// Caller type for dynamic completion8type DynamicCompleteFunc func(string) []string910type PrefixCompleterInterface interface {11Print(prefix string, level int, buf *bytes.Buffer)12Do(line []rune, pos int) (newLine [][]rune, length int)13GetName() []rune14GetChildren() []PrefixCompleterInterface15SetChildren(children []PrefixCompleterInterface)16}1718type DynamicPrefixCompleterInterface interface {19PrefixCompleterInterface20IsDynamic() bool21GetDynamicNames(line []rune) [][]rune22}2324type PrefixCompleter struct {25Name []rune26Dynamic bool27Callback DynamicCompleteFunc28Children []PrefixCompleterInterface29}3031func (p *PrefixCompleter) Tree(prefix string) string {32buf := bytes.NewBuffer(nil)33p.Print(prefix, 0, buf)34return buf.String()35}3637func Print(p PrefixCompleterInterface, prefix string, level int, buf *bytes.Buffer) {38if strings.TrimSpace(string(p.GetName())) != "" {39buf.WriteString(prefix)40if level > 0 {41buf.WriteString("├")42buf.WriteString(strings.Repeat("─", (level*4)-2))43buf.WriteString(" ")44}45buf.WriteString(string(p.GetName()) + "\n")46level++47}48for _, ch := range p.GetChildren() {49ch.Print(prefix, level, buf)50}51}5253func (p *PrefixCompleter) Print(prefix string, level int, buf *bytes.Buffer) {54Print(p, prefix, level, buf)55}5657func (p *PrefixCompleter) IsDynamic() bool {58return p.Dynamic59}6061func (p *PrefixCompleter) GetName() []rune {62return p.Name63}6465func (p *PrefixCompleter) GetDynamicNames(line []rune) [][]rune {66var names = [][]rune{}67for _, name := range p.Callback(string(line)) {68names = append(names, []rune(name+" "))69}70return names71}7273func (p *PrefixCompleter) GetChildren() []PrefixCompleterInterface {74return p.Children75}7677func (p *PrefixCompleter) SetChildren(children []PrefixCompleterInterface) {78p.Children = children79}8081func NewPrefixCompleter(pc ...PrefixCompleterInterface) *PrefixCompleter {82return PcItem("", pc...)83}8485func PcItem(name string, pc ...PrefixCompleterInterface) *PrefixCompleter {86name += " "87return &PrefixCompleter{88Name: []rune(name),89Dynamic: false,90Children: pc,91}92}9394func PcItemDynamic(callback DynamicCompleteFunc, pc ...PrefixCompleterInterface) *PrefixCompleter {95return &PrefixCompleter{96Callback: callback,97Dynamic: true,98Children: pc,99}100}101102func (p *PrefixCompleter) Do(line []rune, pos int) (newLine [][]rune, offset int) {103return doInternal(p, line, pos, line)104}105106func Do(p PrefixCompleterInterface, line []rune, pos int) (newLine [][]rune, offset int) {107return doInternal(p, line, pos, line)108}109110func doInternal(p PrefixCompleterInterface, line []rune, pos int, origLine []rune) (newLine [][]rune, offset int) {111line = runes.TrimSpaceLeft(line[:pos])112goNext := false113var lineCompleter PrefixCompleterInterface114for _, child := range p.GetChildren() {115childNames := make([][]rune, 1)116117childDynamic, ok := child.(DynamicPrefixCompleterInterface)118if ok && childDynamic.IsDynamic() {119childNames = childDynamic.GetDynamicNames(origLine)120} else {121childNames[0] = child.GetName()122}123124for _, childName := range childNames {125if len(line) >= len(childName) {126if runes.HasPrefix(line, childName) {127if len(line) == len(childName) {128newLine = append(newLine, []rune{' '})129} else {130newLine = append(newLine, childName)131}132offset = len(childName)133lineCompleter = child134goNext = true135}136} else {137if runes.HasPrefix(childName, line) {138newLine = append(newLine, childName[len(line):])139offset = len(line)140lineCompleter = child141}142}143}144}145146if len(newLine) != 1 {147return148}149150tmpLine := make([]rune, 0, len(line))151for i := offset; i < len(line); i++ {152if line[i] == ' ' {153continue154}155156tmpLine = append(tmpLine, line[i:]...)157return doInternal(lineCompleter, tmpLine, len(tmpLine), origLine)158}159160if goNext {161return doInternal(lineCompleter, nil, 0, origLine)162}163return164}165166167