| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- 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())
- }
|