mirror of https://github.com/chzyer/readline.git
[windows] fix ansi parse by remove channel
This commit is contained in:
parent
4f0ff8f850
commit
f83f3269ca
|
@ -51,89 +51,73 @@ var ColorTableBg = []word{
|
||||||
|
|
||||||
type ANSIWriter struct {
|
type ANSIWriter struct {
|
||||||
target io.Writer
|
target io.Writer
|
||||||
ch chan rune
|
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
|
ctx *ANSIWriterCtx
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewANSIWriter(w io.Writer) *ANSIWriter {
|
func NewANSIWriter(w io.Writer) *ANSIWriter {
|
||||||
a := &ANSIWriter{
|
a := &ANSIWriter{
|
||||||
target: w,
|
target: w,
|
||||||
ch: make(chan rune),
|
ctx: NewANSIWriterCtx(w),
|
||||||
}
|
}
|
||||||
go a.ioloop()
|
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ANSIWriter) Close() error {
|
func (a *ANSIWriter) Close() error {
|
||||||
close(a.ch)
|
|
||||||
a.wg.Wait()
|
a.wg.Wait()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ANSIWriter) ioloop() {
|
type ANSIWriterCtx struct {
|
||||||
a.wg.Add(1)
|
|
||||||
defer a.wg.Done()
|
|
||||||
|
|
||||||
var (
|
|
||||||
ok bool
|
|
||||||
isEsc bool
|
isEsc bool
|
||||||
isEscSeq bool
|
isEscSeq bool
|
||||||
|
|
||||||
char rune
|
|
||||||
arg []string
|
arg []string
|
||||||
|
target *bufio.Writer
|
||||||
|
wantFlush bool
|
||||||
|
}
|
||||||
|
|
||||||
target = bufio.NewWriter(a.target)
|
func NewANSIWriterCtx(target io.Writer) *ANSIWriterCtx {
|
||||||
)
|
return &ANSIWriterCtx{
|
||||||
|
target: bufio.NewWriter(target),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
peek := func() rune {
|
func (a *ANSIWriterCtx) Flush() {
|
||||||
select {
|
a.target.Flush()
|
||||||
case ch := <-a.ch:
|
}
|
||||||
return ch
|
|
||||||
default:
|
func (a *ANSIWriterCtx) process(r rune) bool {
|
||||||
return 0
|
if a.wantFlush {
|
||||||
|
if r == 0 || r == CharEsc {
|
||||||
|
a.wantFlush = false
|
||||||
|
a.target.Flush()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if a.isEscSeq {
|
||||||
read:
|
a.isEscSeq = a.ioloopEscSeq(a.target, r, &a.arg)
|
||||||
r := char
|
return true
|
||||||
if char == 0 {
|
|
||||||
r, ok = <-a.ch
|
|
||||||
if !ok {
|
|
||||||
target.Flush()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
char = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if isEscSeq {
|
|
||||||
isEscSeq = a.ioloopEscSeq(target, r, &arg)
|
|
||||||
goto read
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch r {
|
switch r {
|
||||||
case CharEsc:
|
case CharEsc:
|
||||||
isEsc = true
|
a.isEsc = true
|
||||||
case '[':
|
case '[':
|
||||||
if isEsc {
|
if a.isEsc {
|
||||||
arg = nil
|
a.arg = nil
|
||||||
isEscSeq = true
|
a.isEscSeq = true
|
||||||
isEsc = false
|
a.isEsc = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
default:
|
default:
|
||||||
target.WriteRune(r)
|
a.target.WriteRune(r)
|
||||||
char = peek()
|
a.wantFlush = true
|
||||||
if char == 0 || char == CharEsc {
|
|
||||||
target.Flush()
|
|
||||||
}
|
}
|
||||||
}
|
return true
|
||||||
goto read
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ANSIWriter) ioloopEscSeq(w *bufio.Writer, r rune, argptr *[]string) bool {
|
func (a *ANSIWriterCtx) ioloopEscSeq(w *bufio.Writer, r rune, argptr *[]string) bool {
|
||||||
arg := *argptr
|
arg := *argptr
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -217,8 +201,9 @@ func (a *ANSIWriter) Write(b []byte) (int, error) {
|
||||||
return off, io.ErrShortWrite
|
return off, io.ErrShortWrite
|
||||||
}
|
}
|
||||||
off += size
|
off += size
|
||||||
a.ch <- r
|
a.ctx.process(r)
|
||||||
}
|
}
|
||||||
|
a.ctx.Flush()
|
||||||
return off, nil
|
return off, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue