forked from mirror/readline
62 lines
1.2 KiB
Go
62 lines
1.2 KiB
Go
|
package readline
|
||
|
|
||
|
type PrefixCompleter struct {
|
||
|
Name []rune
|
||
|
Children []*PrefixCompleter
|
||
|
}
|
||
|
|
||
|
func NewPrefixCompleter(pc ...*PrefixCompleter) *PrefixCompleter {
|
||
|
return PcItem("", pc...)
|
||
|
}
|
||
|
|
||
|
func PcItem(name string, pc ...*PrefixCompleter) *PrefixCompleter {
|
||
|
if len(pc) != 0 {
|
||
|
name += " "
|
||
|
}
|
||
|
return &PrefixCompleter{
|
||
|
Name: []rune(name),
|
||
|
Children: pc,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (p *PrefixCompleter) Do(line []rune, pos int) (newLine [][]rune, offset int) {
|
||
|
line = line[:pos]
|
||
|
goNext := false
|
||
|
var lineCompleter *PrefixCompleter
|
||
|
for _, child := range p.Children {
|
||
|
if len(line) >= len(child.Name) {
|
||
|
if RunesHasPrefix(line, child.Name) {
|
||
|
newLine = append(newLine, child.Name)
|
||
|
offset = len(child.Name)
|
||
|
lineCompleter = child
|
||
|
goNext = true
|
||
|
}
|
||
|
} else {
|
||
|
if RunesHasPrefix(child.Name, line) {
|
||
|
newLine = append(newLine, child.Name[len(line):])
|
||
|
offset = len(line)
|
||
|
lineCompleter = child
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if len(newLine) != 1 {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
tmpLine := make([]rune, 0, len(line))
|
||
|
for i := offset; i < len(line); i++ {
|
||
|
if line[offset] == ' ' {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
tmpLine = append(tmpLine, line[i:]...)
|
||
|
return lineCompleter.Do(tmpLine, len(tmpLine))
|
||
|
}
|
||
|
|
||
|
if goNext {
|
||
|
return lineCompleter.Do(nil, 0)
|
||
|
}
|
||
|
return
|
||
|
}
|