218 lines
4.5 KiB
Go
218 lines
4.5 KiB
Go
package ansi
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
"github.com/charmbracelet/x/ansi/parser"
|
|
)
|
|
|
|
// Sequence represents an ANSI sequence. This can be a control sequence, escape
|
|
// sequence, a printable character, etc.
|
|
// A Sequence can be one of the following types:
|
|
// - [Rune]
|
|
// - [ControlCode]
|
|
// - [Grapheme]
|
|
// - [EscSequence]
|
|
// - [CsiSequence]
|
|
// - [OscSequence]
|
|
// - [DcsSequence]
|
|
// - [SosSequence]
|
|
// - [PmSequence]
|
|
// - [ApcSequence]
|
|
type Sequence interface {
|
|
// Clone returns a deep copy of the sequence.
|
|
Clone() Sequence
|
|
}
|
|
|
|
// Rune represents a printable character.
|
|
type Rune rune
|
|
|
|
var _ Sequence = Rune(0)
|
|
|
|
// Clone returns a deep copy of the rune.
|
|
func (r Rune) Clone() Sequence {
|
|
return r
|
|
}
|
|
|
|
// Grapheme represents a grapheme cluster.
|
|
type Grapheme struct {
|
|
Cluster string
|
|
Width int
|
|
}
|
|
|
|
var _ Sequence = Grapheme{}
|
|
|
|
// Clone returns a deep copy of the grapheme.
|
|
func (g Grapheme) Clone() Sequence {
|
|
return g
|
|
}
|
|
|
|
// ControlCode represents a control code character. This is a character that
|
|
// is not printable and is used to control the terminal. This would be a
|
|
// character in the C0 or C1 set in the range of 0x00-0x1F and 0x80-0x9F.
|
|
type ControlCode byte
|
|
|
|
var _ Sequence = ControlCode(0)
|
|
|
|
// Bytes implements Sequence.
|
|
func (c ControlCode) Bytes() []byte {
|
|
return []byte{byte(c)}
|
|
}
|
|
|
|
// String implements Sequence.
|
|
func (c ControlCode) String() string {
|
|
return string(c)
|
|
}
|
|
|
|
// Clone returns a deep copy of the control code.
|
|
func (c ControlCode) Clone() Sequence {
|
|
return c
|
|
}
|
|
|
|
// EscSequence represents an escape sequence.
|
|
type EscSequence Command
|
|
|
|
var _ Sequence = EscSequence(0)
|
|
|
|
// buffer returns the buffer of the escape sequence.
|
|
func (e EscSequence) buffer() *bytes.Buffer {
|
|
var b bytes.Buffer
|
|
b.WriteByte('\x1b')
|
|
if i := parser.Intermediate(int(e)); i != 0 {
|
|
b.WriteByte(byte(i))
|
|
}
|
|
if cmd := e.Command(); cmd != 0 {
|
|
b.WriteByte(byte(cmd))
|
|
}
|
|
return &b
|
|
}
|
|
|
|
// Bytes implements Sequence.
|
|
func (e EscSequence) Bytes() []byte {
|
|
return e.buffer().Bytes()
|
|
}
|
|
|
|
// String implements Sequence.
|
|
func (e EscSequence) String() string {
|
|
return e.buffer().String()
|
|
}
|
|
|
|
// Clone returns a deep copy of the escape sequence.
|
|
func (e EscSequence) Clone() Sequence {
|
|
return e
|
|
}
|
|
|
|
// Command returns the command byte of the escape sequence.
|
|
func (e EscSequence) Command() int {
|
|
return Command(e).Command()
|
|
}
|
|
|
|
// Intermediate returns the intermediate byte of the escape sequence.
|
|
func (e EscSequence) Intermediate() int {
|
|
return Command(e).Intermediate()
|
|
}
|
|
|
|
// SosSequence represents a SOS sequence.
|
|
type SosSequence struct {
|
|
// Data contains the raw data of the sequence.
|
|
Data []byte
|
|
}
|
|
|
|
var _ Sequence = SosSequence{}
|
|
|
|
// Bytes implements Sequence.
|
|
func (s SosSequence) Bytes() []byte {
|
|
return s.buffer().Bytes()
|
|
}
|
|
|
|
// String implements Sequence.
|
|
func (s SosSequence) String() string {
|
|
return s.buffer().String()
|
|
}
|
|
|
|
func (s SosSequence) buffer() *bytes.Buffer {
|
|
var b bytes.Buffer
|
|
b.WriteByte('\x1b')
|
|
b.WriteByte('X')
|
|
b.Write(s.Data)
|
|
b.WriteString("\x1b\\")
|
|
return &b
|
|
}
|
|
|
|
// Clone returns a deep copy of the SOS sequence.
|
|
func (s SosSequence) Clone() Sequence {
|
|
return SosSequence{
|
|
Data: append([]byte(nil), s.Data...),
|
|
}
|
|
}
|
|
|
|
// PmSequence represents a PM sequence.
|
|
type PmSequence struct {
|
|
// Data contains the raw data of the sequence.
|
|
Data []byte
|
|
}
|
|
|
|
var _ Sequence = PmSequence{}
|
|
|
|
// Bytes implements Sequence.
|
|
func (s PmSequence) Bytes() []byte {
|
|
return s.buffer().Bytes()
|
|
}
|
|
|
|
// String implements Sequence.
|
|
func (s PmSequence) String() string {
|
|
return s.buffer().String()
|
|
}
|
|
|
|
// buffer returns the buffer of the PM sequence.
|
|
func (s PmSequence) buffer() *bytes.Buffer {
|
|
var b bytes.Buffer
|
|
b.WriteByte('\x1b')
|
|
b.WriteByte('^')
|
|
b.Write(s.Data)
|
|
b.WriteString("\x1b\\")
|
|
return &b
|
|
}
|
|
|
|
// Clone returns a deep copy of the PM sequence.
|
|
func (p PmSequence) Clone() Sequence {
|
|
return PmSequence{
|
|
Data: append([]byte(nil), p.Data...),
|
|
}
|
|
}
|
|
|
|
// ApcSequence represents an APC sequence.
|
|
type ApcSequence struct {
|
|
// Data contains the raw data of the sequence.
|
|
Data []byte
|
|
}
|
|
|
|
var _ Sequence = ApcSequence{}
|
|
|
|
// Clone returns a deep copy of the APC sequence.
|
|
func (a ApcSequence) Clone() Sequence {
|
|
return ApcSequence{
|
|
Data: append([]byte(nil), a.Data...),
|
|
}
|
|
}
|
|
|
|
// Bytes implements Sequence.
|
|
func (s ApcSequence) Bytes() []byte {
|
|
return s.buffer().Bytes()
|
|
}
|
|
|
|
// String implements Sequence.
|
|
func (s ApcSequence) String() string {
|
|
return s.buffer().String()
|
|
}
|
|
|
|
// buffer returns the buffer of the APC sequence.
|
|
func (s ApcSequence) buffer() *bytes.Buffer {
|
|
var b bytes.Buffer
|
|
b.WriteByte('\x1b')
|
|
b.WriteByte('_')
|
|
b.Write(s.Data)
|
|
b.WriteString("\x1b\\")
|
|
return &b
|
|
}
|