mirror of https://github.com/chzyer/readline.git
Merge pull request #24 from DanCripe/master
An extended prefix completion implementation
This commit is contained in:
commit
cbab1f1566
|
@ -7,9 +7,16 @@ import (
|
||||||
"github.com/chzyer/readline/runes"
|
"github.com/chzyer/readline/runes"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PrefixCompleterInterface interface {
|
||||||
|
Print(prefix string, level int, buf *bytes.Buffer)
|
||||||
|
Do(line []rune, pos int) (newLine [][]rune, length int)
|
||||||
|
GetName() []rune
|
||||||
|
GetChildren() []PrefixCompleterInterface
|
||||||
|
}
|
||||||
|
|
||||||
type PrefixCompleter struct {
|
type PrefixCompleter struct {
|
||||||
Name []rune
|
Name []rune
|
||||||
Children []*PrefixCompleter
|
Children []PrefixCompleterInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PrefixCompleter) Tree(prefix string) string {
|
func (p *PrefixCompleter) Tree(prefix string) string {
|
||||||
|
@ -18,27 +25,39 @@ func (p *PrefixCompleter) Tree(prefix string) string {
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PrefixCompleter) Print(prefix string, level int, buf *bytes.Buffer) {
|
func Print(p PrefixCompleterInterface, prefix string, level int, buf *bytes.Buffer) {
|
||||||
if strings.TrimSpace(string(p.Name)) != "" {
|
if strings.TrimSpace(string(p.GetName())) != "" {
|
||||||
buf.WriteString(prefix)
|
buf.WriteString(prefix)
|
||||||
if level > 0 {
|
if level > 0 {
|
||||||
buf.WriteString("├")
|
buf.WriteString("├")
|
||||||
buf.WriteString(strings.Repeat("─", (level*4)-2))
|
buf.WriteString(strings.Repeat("─", (level*4)-2))
|
||||||
buf.WriteString(" ")
|
buf.WriteString(" ")
|
||||||
}
|
}
|
||||||
buf.WriteString(string(p.Name) + "\n")
|
buf.WriteString(string(p.GetName()) + "\n")
|
||||||
level++
|
level++
|
||||||
}
|
}
|
||||||
for _, ch := range p.Children {
|
for _, ch := range p.GetChildren() {
|
||||||
ch.Print(prefix, level, buf)
|
ch.Print(prefix, level, buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPrefixCompleter(pc ...*PrefixCompleter) *PrefixCompleter {
|
func (p *PrefixCompleter) Print(prefix string, level int, buf *bytes.Buffer) {
|
||||||
|
Print(p, prefix, level, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrefixCompleter) GetName() []rune {
|
||||||
|
return p.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PrefixCompleter) GetChildren() []PrefixCompleterInterface {
|
||||||
|
return p.Children
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPrefixCompleter(pc ...PrefixCompleterInterface) *PrefixCompleter {
|
||||||
return PcItem("", pc...)
|
return PcItem("", pc...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PcItem(name string, pc ...*PrefixCompleter) *PrefixCompleter {
|
func PcItem(name string, pc ...PrefixCompleterInterface) *PrefixCompleter {
|
||||||
name += " "
|
name += " "
|
||||||
return &PrefixCompleter{
|
return &PrefixCompleter{
|
||||||
Name: []rune(name),
|
Name: []rune(name),
|
||||||
|
@ -47,24 +66,29 @@ func PcItem(name string, pc ...*PrefixCompleter) *PrefixCompleter {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PrefixCompleter) Do(line []rune, pos int) (newLine [][]rune, offset int) {
|
func (p *PrefixCompleter) Do(line []rune, pos int) (newLine [][]rune, offset int) {
|
||||||
|
return Do(p, line, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Do(p PrefixCompleterInterface, line []rune, pos int) (newLine [][]rune, offset int) {
|
||||||
line = line[:pos]
|
line = line[:pos]
|
||||||
goNext := false
|
goNext := false
|
||||||
var lineCompleter *PrefixCompleter
|
var lineCompleter PrefixCompleterInterface
|
||||||
for _, child := range p.Children {
|
for _, child := range p.GetChildren() {
|
||||||
if len(line) >= len(child.Name) {
|
childName := child.GetName()
|
||||||
if runes.HasPrefix(line, child.Name) {
|
if len(line) >= len(childName) {
|
||||||
if len(line) == len(child.Name) {
|
if runes.HasPrefix(line, childName) {
|
||||||
|
if len(line) == len(childName) {
|
||||||
newLine = append(newLine, []rune{' '})
|
newLine = append(newLine, []rune{' '})
|
||||||
} else {
|
} else {
|
||||||
newLine = append(newLine, child.Name)
|
newLine = append(newLine, childName)
|
||||||
}
|
}
|
||||||
offset = len(child.Name)
|
offset = len(childName)
|
||||||
lineCompleter = child
|
lineCompleter = child
|
||||||
goNext = true
|
goNext = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if runes.HasPrefix(child.Name, line) {
|
if runes.HasPrefix(childName, line) {
|
||||||
newLine = append(newLine, child.Name[len(line):])
|
newLine = append(newLine, childName[len(line):])
|
||||||
offset = len(line)
|
offset = len(line)
|
||||||
lineCompleter = child
|
lineCompleter = child
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue