2023-10-07 19:13:39 +00:00
|
|
|
package atom
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"io"
|
|
|
|
"strconv"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
func timeout() <-chan time.Time {
|
|
|
|
return time.After(50 * time.Millisecond)
|
|
|
|
}
|
|
|
|
|
|
|
|
type input struct {
|
|
|
|
buf *bufio.Reader
|
|
|
|
next <-chan nchar
|
|
|
|
pending []Char
|
|
|
|
}
|
|
|
|
|
|
|
|
func (in *input) shift() (r Char) {
|
|
|
|
if len(in.pending) > 0 {
|
|
|
|
r, in.pending = in.pending[0], in.pending[1:]
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (in *input) push(r Char) Char {
|
|
|
|
in.pending = append(in.pending, r)
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
func (in *input) clear() {
|
|
|
|
in.pending = in.pending[:0]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (in *input) readRune() nchar {
|
|
|
|
if r, _, err := in.buf.ReadRune(); err != nil {
|
|
|
|
return ec(err)
|
|
|
|
} else {
|
|
|
|
return nc(r)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func newInput(r io.Reader) *input {
|
|
|
|
return &input{
|
|
|
|
buf: bufio.NewReader(r),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (in *input) restart() {
|
|
|
|
next := make(chan nchar, 200)
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
n := in.readRune()
|
|
|
|
next <- n
|
|
|
|
|
2024-02-21 09:12:23 +00:00
|
|
|
r, ok := n.Ok()
|
|
|
|
needClose := !ok || r == Lf || r == Cr || r == C_C || r == C_D
|
2023-10-07 19:13:39 +00:00
|
|
|
|
|
|
|
if needClose {
|
|
|
|
close(next)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
in.next = next
|
|
|
|
}
|
|
|
|
|
|
|
|
func (in *input) isWaiting() bool {
|
|
|
|
return len(in.next) > 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func (in *input) nextc() (n nchar) {
|
|
|
|
var ok bool
|
|
|
|
|
|
|
|
select {
|
|
|
|
case n, ok = <-in.next:
|
|
|
|
if !ok {
|
|
|
|
return ec(ErrInternal)
|
|
|
|
}
|
|
|
|
if r, ok := n.Ok(); ok {
|
|
|
|
in.push(r)
|
|
|
|
return nc(r)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (in *input) nextt() (n nchar) {
|
|
|
|
var ok bool
|
|
|
|
|
|
|
|
select {
|
|
|
|
case n, ok = <-in.next:
|
|
|
|
if !ok {
|
|
|
|
return ec(ErrInternal)
|
|
|
|
if r, ok := n.Ok(); ok {
|
|
|
|
in.push(r)
|
|
|
|
return nc(r)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case <-timeout():
|
|
|
|
return ec(ErrTimeout)
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (in *input) escO() (key nkey) {
|
|
|
|
key = nk(KeyNil)
|
|
|
|
n := in.nextt()
|
|
|
|
|
|
|
|
if err, ok := n.Err(); ok {
|
|
|
|
if err == ErrTimeout {
|
|
|
|
return nk(keyS(AS_O))
|
|
|
|
}
|
|
|
|
return ek(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
r, ok := n.Ok()
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var s Sequence
|
|
|
|
if r >= '0' && r < '9' {
|
|
|
|
s = Sequence(r << 8)
|
|
|
|
n = in.nextt()
|
|
|
|
if err, ok := n.Err(); ok {
|
|
|
|
if err == ErrTimeout {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
return ek(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
r, _ = n.Ok()
|
|
|
|
}
|
|
|
|
|
|
|
|
s |= Sequence(r)
|
|
|
|
|
|
|
|
return nk(keyS(s))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (in *input) escBracket() (key nkey) {
|
|
|
|
key = nk(KeyNil)
|
|
|
|
n := in.nextt()
|
|
|
|
|
|
|
|
if err, ok := n.Err(); ok {
|
|
|
|
if err == ErrTimeout {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
return ek(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
r, ok := n.Ok()
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var s Sequence
|
|
|
|
switch r {
|
|
|
|
case 'A':
|
|
|
|
s = Up
|
|
|
|
case 'B':
|
|
|
|
s = Down
|
|
|
|
case 'C':
|
|
|
|
s = Right
|
|
|
|
case 'D':
|
|
|
|
s = Left
|
|
|
|
case 'F':
|
|
|
|
s = End
|
|
|
|
case 'H':
|
|
|
|
s = Home
|
|
|
|
case 'Z':
|
|
|
|
s = S_Tab
|
|
|
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
|
|
|
return in.escNumberBracket(r)
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
|
|
|
|
return nk(keyS(s))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (in *input) escNumberBracket(r Char) (key nkey) {
|
|
|
|
key = nk(KeyNil)
|
|
|
|
num := []Char{r}
|
|
|
|
|
|
|
|
for {
|
|
|
|
n := in.nextt()
|
|
|
|
if err, ok := n.Err(); ok {
|
|
|
|
if err == ErrTimeout {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
return ek(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
r, ok := n.Ok()
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
switch r {
|
|
|
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
|
|
|
num = append(num, r)
|
|
|
|
case '~':
|
|
|
|
return in.escTildeBracket(num)
|
|
|
|
case ';':
|
|
|
|
return in.escSemiColonBracket(num)
|
|
|
|
default:
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (in *input) escTildeBracket(num []Char) (key nkey) {
|
|
|
|
x, _ := strconv.ParseInt(string(num), 10, 32)
|
|
|
|
s := Sequence(x)
|
|
|
|
|
|
|
|
return nk(keyS(s))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (in *input) escSemiColonBracket(num []Char) (key nkey) {
|
|
|
|
key = nk(KeyNil)
|
|
|
|
x, _ := strconv.ParseInt(string(num), 10, 32)
|
|
|
|
seqn := x != 1
|
|
|
|
|
|
|
|
var s Sequence
|
|
|
|
if seqn {
|
|
|
|
s = Sequence(x)
|
|
|
|
}
|
|
|
|
|
|
|
|
n := in.nextt()
|
|
|
|
|
|
|
|
if err, ok := n.Err(); ok {
|
|
|
|
if err == ErrTimeout {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
return ek(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
r, ok := n.Ok()
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
s |= Sequence(r << 8)
|
|
|
|
n = in.nextt()
|
|
|
|
|
|
|
|
if err, ok := n.Err(); ok {
|
|
|
|
if err == ErrTimeout {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
return ek(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
r, ok = n.Ok()
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if r == '~' {
|
|
|
|
if !seqn {
|
|
|
|
return nk(KeyNil)
|
|
|
|
}
|
|
|
|
} else if !seqn {
|
|
|
|
s |= Sequence(r)
|
|
|
|
} else {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
return nk(keyS(s))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (in *input) nextChar() (key nkey) {
|
|
|
|
key = nk(KeyNil)
|
|
|
|
|
|
|
|
if len(in.pending) > 0 {
|
|
|
|
r := in.shift()
|
|
|
|
return nk(keyC(r))
|
|
|
|
}
|
|
|
|
|
|
|
|
n := in.nextc()
|
|
|
|
|
|
|
|
if err, ok := n.Err(); ok {
|
|
|
|
in.shift()
|
|
|
|
return ek(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
r, ok := n.Ok()
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if r != Esc {
|
|
|
|
in.shift()
|
|
|
|
return nk(keyC(r))
|
|
|
|
}
|
|
|
|
|
|
|
|
n = in.nextt()
|
|
|
|
if err, ok := n.Err(); ok {
|
|
|
|
if err == ErrTimeout {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
return ek(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
r, ok = n.Ok()
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
switch r {
|
|
|
|
case Bs:
|
2024-02-21 09:12:23 +00:00
|
|
|
key = nk(keyS(A_Bs))
|
2023-10-07 19:13:39 +00:00
|
|
|
case 'O':
|
2024-02-21 09:12:23 +00:00
|
|
|
key = in.escO()
|
2023-10-07 19:13:39 +00:00
|
|
|
case '[':
|
2024-02-21 09:12:23 +00:00
|
|
|
key = in.escBracket()
|
2023-10-07 19:13:39 +00:00
|
|
|
case 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
|
|
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z':
|
2024-02-21 09:12:23 +00:00
|
|
|
key = nk(keyS(Sequence(r << 16)))
|
|
|
|
//default:
|
|
|
|
// return
|
2023-10-07 19:13:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
in.clear()
|
|
|
|
|
2024-02-21 09:12:23 +00:00
|
|
|
return
|
2023-10-07 19:13:39 +00:00
|
|
|
}
|