add ansi writer

This commit is contained in:
Cheney 2015-09-29 00:26:49 +08:00
parent 03d201ab65
commit d4826eb059
5 changed files with 116 additions and 40 deletions

View File

@ -20,12 +20,18 @@ type wrapWriter struct {
}
func (w *wrapWriter) Write(b []byte) (int, error) {
buf := w.r.buf
buf.Clean()
n, err := w.target.Write(b)
if w.t.IsReading() {
w.r.buf.Refresh(nil)
if !w.t.IsReading() {
return w.target.Write(b)
}
var (
n int
err error
)
w.r.buf.Refresh(func() {
n, err = w.target.Write(b)
})
if w.r.IsSearchMode() {
w.r.SearchRefresh(-1)
}

View File

@ -1,9 +1,6 @@
package readline
import (
"io"
"os"
)
import "io"
type Instance struct {
t *Terminal
@ -26,10 +23,10 @@ func (c *Config) Init() error {
}
c.inited = true
if c.Stdout == nil {
c.Stdout = os.Stdout
c.Stdout = Stdout
}
if c.Stderr == nil {
c.Stderr = os.Stderr
c.Stderr = Stderr
}
return nil
}

View File

@ -22,10 +22,6 @@ func NewRuneBuffer(w io.Writer, prompt string) *RuneBuffer {
return rb
}
func (r *RuneBuffer) SetPrompt(prompt string) {
r.prompt = []rune(prompt)
}
func (r *RuneBuffer) CurrentWidth(x int) int {
return RunesWidth(r.buf[:x])
}
@ -280,31 +276,6 @@ func (r *RuneBuffer) output() []byte {
return buf.Bytes()
}
func (r *RuneBuffer) CleanOutput() []byte {
buf := bytes.NewBuffer(nil)
buf.Write([]byte("\033[J")) // just like ^k :)
idxLine := r.IdxLine()
if idxLine == 0 {
buf.WriteString("\033[2K\r")
return buf.Bytes()
}
for i := 0; i < idxLine; i++ {
buf.WriteString("\033[2K\r\b")
}
buf.WriteString("\033[2K\r")
return buf.Bytes()
}
func (r *RuneBuffer) Clean() {
if r.cleanInScreen {
return
}
r.cleanInScreen = true
r.w.Write(r.CleanOutput())
}
func (r *RuneBuffer) Reset() []rune {
ret := r.buf
r.buf = r.buf[:0]
@ -347,3 +318,32 @@ func (r *RuneBuffer) SetWithIdx(idx int, buf []rune) {
func (r *RuneBuffer) Set(buf []rune) {
r.SetWithIdx(len(buf), buf)
}
func (r *RuneBuffer) SetPrompt(prompt string) {
r.prompt = []rune(prompt)
}
func (r *RuneBuffer) cleanOutput() []byte {
buf := bytes.NewBuffer(nil)
buf.Write([]byte("\033[J")) // just like ^k :)
idxLine := r.IdxLine()
if idxLine == 0 {
buf.WriteString("\033[2K\r")
return buf.Bytes()
}
for i := 0; i < idxLine; i++ {
buf.WriteString("\033[2K\r\b")
}
buf.WriteString("\033[2K\r")
return buf.Bytes()
}
func (r *RuneBuffer) Clean() {
if r.cleanInScreen {
return
}
r.cleanInScreen = true
r.w.Write(r.cleanOutput())
}

11
std.go Normal file
View File

@ -0,0 +1,11 @@
package readline
import (
"io"
"os"
)
var (
Stdout io.Writer = os.Stdout
Stderr io.Writer = os.Stderr
)

62
std_windows.go Normal file
View File

@ -0,0 +1,62 @@
// +build windows
package readline
import (
"io"
"gopkg.in/bufio.v1"
)
func init() {
Stdout = NewANSIWriter(Stdout)
Stderr = NewANSIWriter(Stderr)
}
type ANSIWriter struct {
io.Writer
}
func NewANSIWriter(w io.Writer) *ANSIWriter {
a := &ANSIWriter{
Writer: w,
}
return a
}
func (a *ANSIWriter) Write(b []byte) (int, error) {
var (
isEsc bool
isEscSeq bool
)
buf := bufio.NewBuffer(nil)
for i := 0; i < len(b); i++ {
if isEscSeq {
isEsc = false
isEscSeq = false
continue
}
if isEsc {
isEsc = false
continue
}
switch b[i] {
case CharEsc:
isEsc = true
continue
case '[':
if isEsc {
isEscSeq = true
continue
}
fallthrough
default:
}
}
n, err := buf.WriteTo(a.Writer)
if err != nil {
return n, err
}
return len(b), nil
}