forked from mirror/readline
add ansi writer
This commit is contained in:
parent
03d201ab65
commit
d4826eb059
16
operation.go
16
operation.go
|
@ -20,12 +20,18 @@ type wrapWriter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *wrapWriter) Write(b []byte) (int, error) {
|
func (w *wrapWriter) Write(b []byte) (int, error) {
|
||||||
buf := w.r.buf
|
if !w.t.IsReading() {
|
||||||
buf.Clean()
|
return w.target.Write(b)
|
||||||
n, err := w.target.Write(b)
|
|
||||||
if w.t.IsReading() {
|
|
||||||
w.r.buf.Refresh(nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
n int
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
w.r.buf.Refresh(func() {
|
||||||
|
n, err = w.target.Write(b)
|
||||||
|
})
|
||||||
|
|
||||||
if w.r.IsSearchMode() {
|
if w.r.IsSearchMode() {
|
||||||
w.r.SearchRefresh(-1)
|
w.r.SearchRefresh(-1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package readline
|
package readline
|
||||||
|
|
||||||
import (
|
import "io"
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Instance struct {
|
type Instance struct {
|
||||||
t *Terminal
|
t *Terminal
|
||||||
|
@ -26,10 +23,10 @@ func (c *Config) Init() error {
|
||||||
}
|
}
|
||||||
c.inited = true
|
c.inited = true
|
||||||
if c.Stdout == nil {
|
if c.Stdout == nil {
|
||||||
c.Stdout = os.Stdout
|
c.Stdout = Stdout
|
||||||
}
|
}
|
||||||
if c.Stderr == nil {
|
if c.Stderr == nil {
|
||||||
c.Stderr = os.Stderr
|
c.Stderr = Stderr
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
58
runebuf.go
58
runebuf.go
|
@ -22,10 +22,6 @@ func NewRuneBuffer(w io.Writer, prompt string) *RuneBuffer {
|
||||||
return rb
|
return rb
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RuneBuffer) SetPrompt(prompt string) {
|
|
||||||
r.prompt = []rune(prompt)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *RuneBuffer) CurrentWidth(x int) int {
|
func (r *RuneBuffer) CurrentWidth(x int) int {
|
||||||
return RunesWidth(r.buf[:x])
|
return RunesWidth(r.buf[:x])
|
||||||
}
|
}
|
||||||
|
@ -280,31 +276,6 @@ func (r *RuneBuffer) output() []byte {
|
||||||
return buf.Bytes()
|
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 {
|
func (r *RuneBuffer) Reset() []rune {
|
||||||
ret := r.buf
|
ret := r.buf
|
||||||
r.buf = r.buf[:0]
|
r.buf = r.buf[:0]
|
||||||
|
@ -347,3 +318,32 @@ func (r *RuneBuffer) SetWithIdx(idx int, buf []rune) {
|
||||||
func (r *RuneBuffer) Set(buf []rune) {
|
func (r *RuneBuffer) Set(buf []rune) {
|
||||||
r.SetWithIdx(len(buf), buf)
|
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())
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package readline
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Stdout io.Writer = os.Stdout
|
||||||
|
Stderr io.Writer = os.Stderr
|
||||||
|
)
|
|
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue