Prechádzať zdrojové kódy

Merge branch 'master' of git://github.com/mattn/go-colorable

Yasuhiro Matsumoto 9 rokov pred
rodič
commit
d228849504
5 zmenil súbory, kde vykonal 75 pridanie a 28 odobranie
  1. 8 0
      .travis.yml
  2. 5 4
      _example2/main.go
  3. 30 0
      colorable_test.go
  4. 20 13
      colorable_windows.go
  5. 12 11
      noncolorable.go

+ 8 - 0
.travis.yml

@@ -0,0 +1,8 @@
+language: go
+go:
+  - tip
+
+sudo: false
+
+script:
+ - go test -v

+ 5 - 4
_example2/main.go

@@ -3,13 +3,14 @@ package main
 import (
 	"bufio"
 	"fmt"
-	".."
+
+	"github.com/mattn/go-colorable"
 )
 
-func main(){
+func main() {
 	stdOut := bufio.NewWriter(colorable.NewColorableStdout())
 
-	fmt.Fprint(stdOut,"\x1B[3GMove to 3rd Column\n")
-	fmt.Fprint(stdOut,"\x1B[1;2HMove to 2nd Column on 1st Line\n")
+	fmt.Fprint(stdOut, "\x1B[3GMove to 3rd Column\n")
+	fmt.Fprint(stdOut, "\x1B[1;2HMove to 2nd Column on 1st Line\n")
 	stdOut.Flush()
 }

+ 30 - 0
colorable_test.go

@@ -0,0 +1,30 @@
+package colorable
+
+import (
+	"bytes"
+	"testing"
+)
+
+// checkEncoding checks that colorable is output encoding agnostic as long as
+// the encoding is a superset of ASCII. This implies that one byte not part of
+// an ANSI sequence must give exactly one byte in output
+func checkEncoding(t *testing.T, data []byte) {
+	// Send non-UTF8 data to colorable
+	b := bytes.NewBuffer(make([]byte, 0, 10))
+	if b.Len() != 0 {
+		t.FailNow()
+	}
+	// TODO move colorable wrapping outside the test
+	c := NewNonColorable(b)
+	c.Write(data)
+	if b.Len() != len(data) {
+		t.Fatalf("%d bytes expected, got %d", len(data), b.Len())
+	}
+}
+
+func TestEncoding(t *testing.T) {
+	checkEncoding(t, []byte{})      // Empty
+	checkEncoding(t, []byte(`abc`)) // "abc"
+	checkEncoding(t, []byte(`é`))   // "é" in UTF-8
+	checkEncoding(t, []byte{233})   // 'é' in Latin-1
+}

+ 20 - 13
colorable_windows.go

@@ -2,7 +2,6 @@ package colorable
 
 import (
 	"bytes"
-	"fmt"
 	"io"
 	"math"
 	"os"
@@ -73,6 +72,7 @@ type Writer struct {
 	handle  syscall.Handle
 	lastbuf bytes.Buffer
 	oldattr word
+	oldpos  coord
 }
 
 // NewColorable return new instance of Writer which handle escape sequence from File.
@@ -85,7 +85,7 @@ func NewColorable(file *os.File) io.Writer {
 		var csbi consoleScreenBufferInfo
 		handle := syscall.Handle(file.Fd())
 		procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
-		return &Writer{out: file, handle: handle, oldattr: csbi.attributes}
+		return &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}}
 	} else {
 		return file
 	}
@@ -365,7 +365,8 @@ func (w *Writer) Write(data []byte) (n int, err error) {
 	var csbi consoleScreenBufferInfo
 	procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
 
-	er := bytes.NewBuffer(data)
+	er := bytes.NewReader(data)
+	var bw [1]byte
 loop:
 	for {
 		r1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
@@ -373,32 +374,33 @@ loop:
 			break loop
 		}
 
-		c1, _, err := er.ReadRune()
+		c1, err := er.ReadByte()
 		if err != nil {
 			break loop
 		}
 		if c1 != 0x1b {
-			fmt.Fprint(w.out, string(c1))
+			bw[0] = c1
+			w.out.Write(bw[:])
 			continue
 		}
-		c2, _, err := er.ReadRune()
+		c2, err := er.ReadByte()
 		if err != nil {
-			w.lastbuf.WriteRune(c1)
+			w.lastbuf.WriteByte(c1)
 			break loop
 		}
 		if c2 != 0x5b {
-			w.lastbuf.WriteRune(c1)
-			w.lastbuf.WriteRune(c2)
+			w.lastbuf.WriteByte(c1)
+			w.lastbuf.WriteByte(c2)
 			continue
 		}
 
 		var buf bytes.Buffer
-		var m rune
+		var m byte
 		for {
-			c, _, err := er.ReadRune()
+			c, err := er.ReadByte()
 			if err != nil {
-				w.lastbuf.WriteRune(c1)
-				w.lastbuf.WriteRune(c2)
+				w.lastbuf.WriteByte(c1)
+				w.lastbuf.WriteByte(c2)
 				w.lastbuf.Write(buf.Bytes())
 				break loop
 			}
@@ -647,6 +649,11 @@ loop:
 				ci.visible = 0
 				procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
 			}
+		case 's':
+			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+			w.oldpos = csbi.cursorPosition
+		case 'u':
+			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&w.oldpos)))
 		}
 	}
 	return len(data) - w.lastbuf.Len(), nil

+ 12 - 11
noncolorable.go

@@ -2,7 +2,6 @@ package colorable
 
 import (
 	"bytes"
-	"fmt"
 	"io"
 )
 
@@ -19,34 +18,36 @@ func NewNonColorable(w io.Writer) io.Writer {
 
 // Write write data on console
 func (w *NonColorable) Write(data []byte) (n int, err error) {
-	er := bytes.NewBuffer(data)
+	er := bytes.NewReader(data)
+	var bw [1]byte
 loop:
 	for {
-		c1, _, err := er.ReadRune()
+		c1, err := er.ReadByte()
 		if err != nil {
 			break loop
 		}
 		if c1 != 0x1b {
-			fmt.Fprint(w.out, string(c1))
+			bw[0] = c1
+			w.out.Write(bw[:])
 			continue
 		}
-		c2, _, err := er.ReadRune()
+		c2, err := er.ReadByte()
 		if err != nil {
-			w.lastbuf.WriteRune(c1)
+			w.lastbuf.WriteByte(c1)
 			break loop
 		}
 		if c2 != 0x5b {
-			w.lastbuf.WriteRune(c1)
-			w.lastbuf.WriteRune(c2)
+			w.lastbuf.WriteByte(c1)
+			w.lastbuf.WriteByte(c2)
 			continue
 		}
 
 		var buf bytes.Buffer
 		for {
-			c, _, err := er.ReadRune()
+			c, err := er.ReadByte()
 			if err != nil {
-				w.lastbuf.WriteRune(c1)
-				w.lastbuf.WriteRune(c2)
+				w.lastbuf.WriteByte(c1)
+				w.lastbuf.WriteByte(c2)
 				w.lastbuf.Write(buf.Bytes())
 				break loop
 			}