forked from toolshed/abra
		
	
		
			
				
	
	
		
			77 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package ansi
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"io"
 | 
						|
	"unicode/utf8"
 | 
						|
)
 | 
						|
 | 
						|
type Writer struct {
 | 
						|
	Forward io.Writer
 | 
						|
 | 
						|
	ansi       bool
 | 
						|
	ansiseq    bytes.Buffer
 | 
						|
	lastseq    bytes.Buffer
 | 
						|
	seqchanged bool
 | 
						|
	runeBuf    []byte
 | 
						|
}
 | 
						|
 | 
						|
// Write is used to write content to the ANSI buffer.
 | 
						|
func (w *Writer) Write(b []byte) (int, error) {
 | 
						|
	for _, c := range string(b) {
 | 
						|
		if c == Marker {
 | 
						|
			// ANSI escape sequence
 | 
						|
			w.ansi = true
 | 
						|
			w.seqchanged = true
 | 
						|
			_, _ = w.ansiseq.WriteRune(c)
 | 
						|
		} else if w.ansi {
 | 
						|
			_, _ = w.ansiseq.WriteRune(c)
 | 
						|
			if IsTerminator(c) {
 | 
						|
				// ANSI sequence terminated
 | 
						|
				w.ansi = false
 | 
						|
 | 
						|
				if bytes.HasSuffix(w.ansiseq.Bytes(), []byte("[0m")) {
 | 
						|
					// reset sequence
 | 
						|
					w.lastseq.Reset()
 | 
						|
					w.seqchanged = false
 | 
						|
				} else if c == 'm' {
 | 
						|
					// color code
 | 
						|
					_, _ = w.lastseq.Write(w.ansiseq.Bytes())
 | 
						|
				}
 | 
						|
 | 
						|
				_, _ = w.ansiseq.WriteTo(w.Forward)
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			_, err := w.writeRune(c)
 | 
						|
			if err != nil {
 | 
						|
				return 0, err
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return len(b), nil
 | 
						|
}
 | 
						|
 | 
						|
func (w *Writer) writeRune(r rune) (int, error) {
 | 
						|
	if w.runeBuf == nil {
 | 
						|
		w.runeBuf = make([]byte, utf8.UTFMax)
 | 
						|
	}
 | 
						|
	n := utf8.EncodeRune(w.runeBuf, r)
 | 
						|
	return w.Forward.Write(w.runeBuf[:n])
 | 
						|
}
 | 
						|
 | 
						|
func (w *Writer) LastSequence() string {
 | 
						|
	return w.lastseq.String()
 | 
						|
}
 | 
						|
 | 
						|
func (w *Writer) ResetAnsi() {
 | 
						|
	if !w.seqchanged {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	_, _ = w.Forward.Write([]byte("\x1b[0m"))
 | 
						|
}
 | 
						|
 | 
						|
func (w *Writer) RestoreAnsi() {
 | 
						|
	_, _ = w.Forward.Write(w.lastseq.Bytes())
 | 
						|
}
 |