[complete] fix doSegment

This commit is contained in:
chzyer 2016-04-02 02:00:16 +08:00
parent 4606bfd979
commit 9d26a3bde6
2 changed files with 33 additions and 17 deletions

View File

@ -1,5 +1,11 @@
package readline package readline
import (
"strconv"
"github.com/chzyer/readline/runes"
)
type SegmentCompleter interface { type SegmentCompleter interface {
// a // a
// |- a1 // |- a1
@ -37,6 +43,9 @@ func RetSegment(segments [][]rune, cands [][]rune, idx int) ([][]rune, int) {
ret := make([][]rune, 0, len(cands)) ret := make([][]rune, 0, len(cands))
lastSegment := segments[len(segments)-1] lastSegment := segments[len(segments)-1]
for _, cand := range cands { for _, cand := range cands {
if !runes.HasPrefix(cand, lastSegment) {
continue
}
ret = append(ret, cand[len(lastSegment):]) ret = append(ret, cand[len(lastSegment):])
} }
return ret, idx return ret, idx
@ -61,6 +70,11 @@ func SplitSegment(line []rune, pos int) ([][]rune, int) {
} }
func (c *SegmentComplete) Do(line []rune, pos int) (newLine [][]rune, offset int) { func (c *SegmentComplete) Do(line []rune, pos int) (newLine [][]rune, offset int) {
segment, idx := SplitSegment(line, pos) segment, idx := SplitSegment(line, pos)
return RetSegment(segment, c.DoSegment(segment, idx), idx)
cands := c.DoSegment(segment, idx)
newLine, offset = RetSegment(segment, cands, idx)
Debug(strconv.Quote(string(line)), cands)
return newLine, offset
} }

View File

@ -4,8 +4,6 @@ import (
"fmt" "fmt"
"testing" "testing"
"gopkg.in/logex.v1"
"github.com/chzyer/test" "github.com/chzyer/test"
) )
@ -34,6 +32,8 @@ func TestRetSegment(t *testing.T) {
// |- a2 // |- a2
// |--- a21 // |--- a21
// b // b
// add
// adddomain
ret := []struct { ret := []struct {
Segments [][]rune Segments [][]rune
Cands [][]rune Cands [][]rune
@ -41,11 +41,12 @@ func TestRetSegment(t *testing.T) {
Ret [][]rune Ret [][]rune
pos int pos int
}{ }{
{sr(""), sr("a", "b"), 0, sr("a", "b"), 0}, {sr(""), sr("a", "b", "add", "adddomain"), 0, sr("a", "b", "add", "adddomain"), 0},
{sr("a"), sr("a"), 1, sr(""), 1}, {sr("a"), sr("a", "add", "adddomain"), 1, sr("", "dd", "dddomain"), 1},
{sr("a", ""), sr("a1", "a2"), 0, sr("a1", "a2"), 0}, {sr("a", ""), sr("a1", "a2"), 0, sr("a1", "a2"), 0},
{sr("a", "a"), sr("a1", "a2"), 1, sr("1", "2"), 1}, {sr("a", "a"), sr("a1", "a2"), 1, sr("1", "2"), 1},
{sr("a", "a1"), sr("a1"), 2, sr(""), 2}, {sr("a", "a1"), sr("a1"), 2, sr(""), 2},
{sr("add"), sr("add", "adddomain"), 2, sr("", "domain"), 2},
} }
for idx, r := range ret { for idx, r := range ret {
ret, pos := RetSegment(r.Segments, r.Cands, r.idx) ret, pos := RetSegment(r.Segments, r.Cands, r.idx)
@ -103,12 +104,15 @@ func TestSegmentCompleter(t *testing.T) {
}}, }},
}}, }},
{"b", nil}, {"b", nil},
{"route", []Tree{
{"add", nil},
{"adddomain", nil},
}},
}} }}
s := SegmentFunc(func(ret [][]rune, n int) [][]rune { s := SegmentFunc(func(ret [][]rune, n int) [][]rune {
tree := tree tree := tree
main: main:
for level := 0; level < len(ret); { for level := 0; level < len(ret)-1; {
name := string(ret[level]) name := string(ret[level])
for _, t := range tree.Children { for _, t := range tree.Children {
if t.Name == name { if t.Name == name {
@ -117,16 +121,13 @@ func TestSegmentCompleter(t *testing.T) {
continue main continue main
} }
} }
ret = make([][]rune, len(tree.Children))
for idx, r := range tree.Children {
ret[idx] = []rune(r.Name)
}
return ret
} }
logex.Info(rs(ret), n, tree) ret = make([][]rune, len(tree.Children))
return [][]rune{[]rune(tree.Name)} for idx, r := range tree.Children {
ret[idx] = []rune(r.Name)
}
return ret
}) })
// a // a
@ -142,7 +143,7 @@ func TestSegmentCompleter(t *testing.T) {
Ret [][]rune Ret [][]rune
Share int Share int
}{ }{
{"", 0, sr("a", "b"), 0}, {"", 0, sr("a", "b", "route"), 0},
{"a", 1, sr(""), 1}, {"a", 1, sr(""), 1},
{"a ", 2, sr("a1", "a2"), 0}, {"a ", 2, sr("a1", "a2"), 0},
{"a a", 3, sr("1", "2"), 1}, {"a a", 3, sr("1", "2"), 1},
@ -151,10 +152,11 @@ func TestSegmentCompleter(t *testing.T) {
{"a a1 a", 6, sr("11", "12"), 1}, {"a a1 a", 6, sr("11", "12"), 1},
{"a a1 a1", 7, sr("1", "2"), 2}, {"a a1 a1", 7, sr("1", "2"), 2},
{"a a1 a11", 8, sr(""), 3}, {"a a1 a11", 8, sr(""), 3},
{"route add", 9, sr("", "domain"), 3},
} }
for i, r := range ret { for i, r := range ret {
newLine, length := s.Do([]rune(r.Line), r.Pos) newLine, length := s.Do([]rune(r.Line), r.Pos)
test.Equal(newLine, r.Ret, fmt.Errorf("%v", i)) test.Equal(rs(newLine), rs(r.Ret), fmt.Errorf("%v", i))
test.Equal(length, r.Share, fmt.Errorf("%v", i)) test.Equal(length, r.Share, fmt.Errorf("%v", i))
} }
} }