Fix the behavior of F1 key

This commit is contained in:
c-bata 2018-12-19 13:31:44 +09:00
parent ffd2ba2f2c
commit ae591692bb
2 changed files with 51 additions and 61 deletions

@ -21,82 +21,72 @@ type KeyPress struct {
} }
type Parser struct { type Parser struct {
Input chan []byte Input chan rune
Out chan KeyPress Out chan KeyPress
} }
func (p *Parser) Feed(data []byte) { func (p *Parser) Feed(r rune) {
p.Input <- data p.Input <- r
} }
func (p *Parser) process(prefix []byte, retry bool, in []byte) ([]byte, bool) { func (p *Parser) Start() {
prefix := bytes.NewBuffer(nil)
retry := false
for {
if retry { if retry {
retry = false retry = false
} else { } else {
prefix = append(prefix, in...) in, ok := <-p.Input
if !ok {
break
} }
if len(prefix) > 0 { prefix.WriteRune(in)
}
if prefix.Len() > 0 {
isPrefixOfLongerMatch := false isPrefixOfLongerMatch := false
for _, s := range prompt.ASCIISequences { for _, s := range prompt.ASCIISequences {
if bytes.HasPrefix(s.ASCIICode, prefix) && bytes.Compare(s.ASCIICode, prefix) != 0 { if bytes.HasPrefix(s.ASCIICode, prefix.Bytes()) && bytes.Compare(s.ASCIICode, prefix.Bytes()) != 0 {
isPrefixOfLongerMatch = true isPrefixOfLongerMatch = true
break break
} }
} }
match := false match := prompt.GetKey(prefix.Bytes())
matchedKey := prompt.GetKey(prefix) if !isPrefixOfLongerMatch && match != prompt.NotDefined {
if matchedKey != prompt.NotDefined { p.Out <- KeyPress{Key: match, Bytes: prefix.Bytes()}
match = true prefix.Reset()
} } else if !isPrefixOfLongerMatch && match == prompt.NotDefined {
if !isPrefixOfLongerMatch && match {
p.Out <- KeyPress{Key: matchedKey, Bytes: prefix}
prefix = make([]byte, 0, 5)
} else if !isPrefixOfLongerMatch && !match {
found := false found := false
retry = true retry = true
for i := len(prefix); i > 0; i-- { prefixRunes := []rune(prefix.String())
matchedKey = prompt.GetKey(prefix[:i]) for i := len(prefixRunes); i > 0; i-- {
if matchedKey != prompt.NotDefined { prefixBytes := []byte(string(prefixRunes[:i]))
match = true match = prompt.GetKey(prefixBytes)
break if match != prompt.NotDefined {
p.Out <- KeyPress{Key: match, Bytes: prefixBytes}
for j := 0; j < i; j++ {
_, _, _ = prefix.ReadRune()
} }
if match {
p.Out <- KeyPress{Key: matchedKey, Bytes: prefix}
prefix = prefix[i:]
found = true found = true
} }
} }
if !found { if !found {
p.Out <- KeyPress{Key: matchedKey, Bytes: prefix} r, _, err := prefix.ReadRune()
prefix = prefix[1:] if err == io.EOF {
continue // don't reach here.
} }
p.Out <- KeyPress{Key: match, Bytes: []byte(string(r))}
_, _, _ = prefix.ReadRune()
} }
} }
return prefix, retry
}
func (p *Parser) Start() {
prefix := make([]byte, 0, 5)
retry := false
for {
select {
case in, ok := <-p.Input:
if !ok {
return
}
prefix, retry = p.process(prefix, retry, in)
if retry {
prefix, retry = p.process(prefix, retry, in)
}
} }
} }
} }
func NewParser() *Parser { func NewParser() *Parser {
return &Parser{ return &Parser{
Input: make(chan []byte, 1), Input: make(chan rune, 1),
Out: make(chan KeyPress, 1), Out: make(chan KeyPress, 1),
} }
} }
@ -125,7 +115,7 @@ func main() {
break break
} }
} }
p.Feed([]byte(string(c))) p.Feed(c)
} }
close(p.Input) close(p.Input)
}() }()

@ -96,7 +96,7 @@ var ASCIISequences = []*ASCIICode{
{Key: F3, ASCIICode: []byte{0x1b, 0x4f, 0x52}}, {Key: F3, ASCIICode: []byte{0x1b, 0x4f, 0x52}},
{Key: F4, ASCIICode: []byte{0x1b, 0x4f, 0x53}}, {Key: F4, ASCIICode: []byte{0x1b, 0x4f, 0x53}},
{Key: F1, ASCIICode: []byte{0x1b, 0x4f, 0x50, 0x41}}, // Linux console {Key: F1, ASCIICode: []byte{0x1b, 0x4f, 0x5b, 0x41}}, // Linux console
{Key: F2, ASCIICode: []byte{0x1b, 0x5b, 0x5b, 0x42}}, // Linux console {Key: F2, ASCIICode: []byte{0x1b, 0x5b, 0x5b, 0x42}}, // Linux console
{Key: F3, ASCIICode: []byte{0x1b, 0x5b, 0x5b, 0x43}}, // Linux console {Key: F3, ASCIICode: []byte{0x1b, 0x5b, 0x5b, 0x43}}, // Linux console
{Key: F4, ASCIICode: []byte{0x1b, 0x5b, 0x5b, 0x44}}, // Linux console {Key: F4, ASCIICode: []byte{0x1b, 0x5b, 0x5b, 0x44}}, // Linux console