forked from toolshed/abra
build: go 1.24
We were running behind and there were quite some deprecations to update. This was mostly in the upstream copy/pasta package but seems quite minimal.
This commit is contained in:
159
vendor/github.com/charmbracelet/x/ansi/parser_decode.go
generated
vendored
159
vendor/github.com/charmbracelet/x/ansi/parser_decode.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/charmbracelet/x/ansi/parser"
|
||||
"github.com/mattn/go-runewidth"
|
||||
"github.com/rivo/uniseg"
|
||||
)
|
||||
|
||||
@ -14,7 +15,7 @@ type State = byte
|
||||
// ANSI escape sequence states used by [DecodeSequence].
|
||||
const (
|
||||
NormalState State = iota
|
||||
MarkerState
|
||||
PrefixState
|
||||
ParamsState
|
||||
IntermedState
|
||||
EscapeState
|
||||
@ -33,25 +34,25 @@ const (
|
||||
//
|
||||
// Passing a non-nil [*Parser] as the last argument will allow the decoder to
|
||||
// collect sequence parameters, data, and commands. The parser cmd will have
|
||||
// the packed command value that contains intermediate and marker characters.
|
||||
// the packed command value that contains intermediate and prefix characters.
|
||||
// In the case of a OSC sequence, the cmd will be the OSC command number. Use
|
||||
// [Command] and [Parameter] types to unpack command intermediates and markers as well
|
||||
// [Cmd] and [Param] types to unpack command intermediates and prefixes as well
|
||||
// as parameters.
|
||||
//
|
||||
// Zero [Command] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the
|
||||
// Zero [Cmd] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the
|
||||
// validity of other data sequences, OSC, DCS, etc, will require checking for
|
||||
// the returned sequence terminator bytes such as ST (ESC \\) and BEL).
|
||||
//
|
||||
// We store the command byte in [Command] in the most significant byte, the
|
||||
// marker byte in the next byte, and the intermediate byte in the least
|
||||
// We store the command byte in [Cmd] in the most significant byte, the
|
||||
// prefix byte in the next byte, and the intermediate byte in the least
|
||||
// significant byte. This is done to avoid using a struct to store the command
|
||||
// and its intermediates and markers. The command byte is always the least
|
||||
// significant byte i.e. [Cmd & 0xff]. Use the [Command] type to unpack the
|
||||
// command, intermediate, and marker bytes. Note that we only collect the last
|
||||
// marker character and intermediate byte.
|
||||
// and its intermediates and prefixes. The command byte is always the least
|
||||
// significant byte i.e. [Cmd & 0xff]. Use the [Cmd] type to unpack the
|
||||
// command, intermediate, and prefix bytes. Note that we only collect the last
|
||||
// prefix character and intermediate byte.
|
||||
//
|
||||
// The [p.Params] slice will contain the parameters of the sequence. Any
|
||||
// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Parameter] type
|
||||
// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Param] type
|
||||
// to unpack the parameters.
|
||||
//
|
||||
// Example:
|
||||
@ -65,7 +66,63 @@ const (
|
||||
// state = newState
|
||||
// input = input[n:]
|
||||
// }
|
||||
//
|
||||
// This function treats the text as a sequence of grapheme clusters.
|
||||
func DecodeSequence[T string | []byte](b T, state byte, p *Parser) (seq T, width int, n int, newState byte) {
|
||||
return decodeSequence(GraphemeWidth, b, state, p)
|
||||
}
|
||||
|
||||
// DecodeSequenceWc decodes the first ANSI escape sequence or a printable
|
||||
// grapheme from the given data. It returns the sequence slice, the number of
|
||||
// bytes read, the cell width for each sequence, and the new state.
|
||||
//
|
||||
// The cell width will always be 0 for control and escape sequences, 1 for
|
||||
// ASCII printable characters, and the number of cells other Unicode characters
|
||||
// occupy. It uses the uniseg package to calculate the width of Unicode
|
||||
// graphemes and characters. This means it will always do grapheme clustering
|
||||
// (mode 2027).
|
||||
//
|
||||
// Passing a non-nil [*Parser] as the last argument will allow the decoder to
|
||||
// collect sequence parameters, data, and commands. The parser cmd will have
|
||||
// the packed command value that contains intermediate and prefix characters.
|
||||
// In the case of a OSC sequence, the cmd will be the OSC command number. Use
|
||||
// [Cmd] and [Param] types to unpack command intermediates and prefixes as well
|
||||
// as parameters.
|
||||
//
|
||||
// Zero [Cmd] means the CSI, DCS, or ESC sequence is invalid. Moreover, checking the
|
||||
// validity of other data sequences, OSC, DCS, etc, will require checking for
|
||||
// the returned sequence terminator bytes such as ST (ESC \\) and BEL).
|
||||
//
|
||||
// We store the command byte in [Cmd] in the most significant byte, the
|
||||
// prefix byte in the next byte, and the intermediate byte in the least
|
||||
// significant byte. This is done to avoid using a struct to store the command
|
||||
// and its intermediates and prefixes. The command byte is always the least
|
||||
// significant byte i.e. [Cmd & 0xff]. Use the [Cmd] type to unpack the
|
||||
// command, intermediate, and prefix bytes. Note that we only collect the last
|
||||
// prefix character and intermediate byte.
|
||||
//
|
||||
// The [p.Params] slice will contain the parameters of the sequence. Any
|
||||
// sub-parameter will have the [parser.HasMoreFlag] set. Use the [Param] type
|
||||
// to unpack the parameters.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var state byte // the initial state is always zero [NormalState]
|
||||
// p := NewParser(32, 1024) // create a new parser with a 32 params buffer and 1024 data buffer (optional)
|
||||
// input := []byte("\x1b[31mHello, World!\x1b[0m")
|
||||
// for len(input) > 0 {
|
||||
// seq, width, n, newState := DecodeSequenceWc(input, state, p)
|
||||
// log.Printf("seq: %q, width: %d", seq, width)
|
||||
// state = newState
|
||||
// input = input[n:]
|
||||
// }
|
||||
//
|
||||
// This function treats the text as a sequence of wide characters and runes.
|
||||
func DecodeSequenceWc[T string | []byte](b T, state byte, p *Parser) (seq T, width int, n int, newState byte) {
|
||||
return decodeSequence(WcWidth, b, state, p)
|
||||
}
|
||||
|
||||
func decodeSequence[T string | []byte](m Method, b T, state State, p *Parser) (seq T, width int, n int, newState byte) {
|
||||
for i := 0; i < len(b); i++ {
|
||||
c := b[i]
|
||||
|
||||
@ -92,7 +149,7 @@ func DecodeSequence[T string | []byte](b T, state byte, p *Parser) (seq T, width
|
||||
p.paramsLen = 0
|
||||
p.dataLen = 0
|
||||
}
|
||||
state = MarkerState
|
||||
state = PrefixState
|
||||
continue
|
||||
case OSC, APC, SOS, PM:
|
||||
if p != nil {
|
||||
@ -120,18 +177,21 @@ func DecodeSequence[T string | []byte](b T, state byte, p *Parser) (seq T, width
|
||||
|
||||
if utf8.RuneStart(c) {
|
||||
seq, _, width, _ = FirstGraphemeCluster(b, -1)
|
||||
if m == WcWidth {
|
||||
width = runewidth.StringWidth(string(seq))
|
||||
}
|
||||
i += len(seq)
|
||||
return b[:i], width, i, NormalState
|
||||
}
|
||||
|
||||
// Invalid UTF-8 sequence
|
||||
return b[:i], 0, i, NormalState
|
||||
case MarkerState:
|
||||
case PrefixState:
|
||||
if c >= '<' && c <= '?' {
|
||||
if p != nil {
|
||||
// We only collect the last marker character.
|
||||
p.cmd &^= 0xff << parser.MarkerShift
|
||||
p.cmd |= int(c) << parser.MarkerShift
|
||||
// We only collect the last prefix character.
|
||||
p.cmd &^= 0xff << parser.PrefixShift
|
||||
p.cmd |= int(c) << parser.PrefixShift
|
||||
}
|
||||
break
|
||||
}
|
||||
@ -216,7 +276,7 @@ func DecodeSequence[T string | []byte](b T, state byte, p *Parser) (seq T, width
|
||||
p.paramsLen = 0
|
||||
p.cmd = 0
|
||||
}
|
||||
state = MarkerState
|
||||
state = PrefixState
|
||||
continue
|
||||
case ']', 'X', '^', '_':
|
||||
if p != nil {
|
||||
@ -389,17 +449,17 @@ func FirstGraphemeCluster[T string | []byte](b T, state int) (T, T, int, int) {
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// Command represents a sequence command. This is used to pack/unpack a sequence
|
||||
// command with its intermediate and marker characters. Those are commonly
|
||||
// Cmd represents a sequence command. This is used to pack/unpack a sequence
|
||||
// command with its intermediate and prefix characters. Those are commonly
|
||||
// found in CSI and DCS sequences.
|
||||
type Command int
|
||||
type Cmd int
|
||||
|
||||
// Marker returns the unpacked marker byte of the CSI sequence.
|
||||
// Prefix returns the unpacked prefix byte of the CSI sequence.
|
||||
// This is always gonna be one of the following '<' '=' '>' '?' and in the
|
||||
// range of 0x3C-0x3F.
|
||||
// Zero is returned if the sequence does not have a marker.
|
||||
func (c Command) Marker() int {
|
||||
return parser.Marker(int(c))
|
||||
// Zero is returned if the sequence does not have a prefix.
|
||||
func (c Cmd) Prefix() byte {
|
||||
return byte(parser.Prefix(int(c)))
|
||||
}
|
||||
|
||||
// Intermediate returns the unpacked intermediate byte of the CSI sequence.
|
||||
@ -407,37 +467,40 @@ func (c Command) Marker() int {
|
||||
// characters from ' ', '!', '"', '#', '$', '%', '&', ”', '(', ')', '*', '+',
|
||||
// ',', '-', '.', '/'.
|
||||
// Zero is returned if the sequence does not have an intermediate byte.
|
||||
func (c Command) Intermediate() int {
|
||||
return parser.Intermediate(int(c))
|
||||
func (c Cmd) Intermediate() byte {
|
||||
return byte(parser.Intermediate(int(c)))
|
||||
}
|
||||
|
||||
// Command returns the unpacked command byte of the CSI sequence.
|
||||
func (c Command) Command() int {
|
||||
return parser.Command(int(c))
|
||||
// Final returns the unpacked command byte of the CSI sequence.
|
||||
func (c Cmd) Final() byte {
|
||||
return byte(parser.Command(int(c)))
|
||||
}
|
||||
|
||||
// Cmd returns a packed [Command] with the given command, marker, and
|
||||
// intermediate.
|
||||
// The first byte is the command, the next shift is the marker, and the next
|
||||
// shift is the intermediate.
|
||||
// Command packs a command with the given prefix, intermediate, and final. A
|
||||
// zero byte means the sequence does not have a prefix or intermediate.
|
||||
//
|
||||
// Even though this function takes integers, it only uses the lower 8 bits of
|
||||
// each integer.
|
||||
func Cmd(marker, inter, cmd int) (c Command) {
|
||||
c = Command(cmd & parser.CommandMask)
|
||||
c |= Command(marker&parser.CommandMask) << parser.MarkerShift
|
||||
c |= Command(inter&parser.CommandMask) << parser.IntermedShift
|
||||
// Prefixes are in the range of 0x3C-0x3F that is one of `<=>?`.
|
||||
//
|
||||
// Intermediates are in the range of 0x20-0x2F that is anything in
|
||||
// `!"#$%&'()*+,-./`.
|
||||
//
|
||||
// Final bytes are in the range of 0x40-0x7E that is anything in the range
|
||||
// `@A–Z[\]^_`a–z{|}~`.
|
||||
func Command(prefix, inter, final byte) (c int) {
|
||||
c = int(final)
|
||||
c |= int(prefix) << parser.PrefixShift
|
||||
c |= int(inter) << parser.IntermedShift
|
||||
return
|
||||
}
|
||||
|
||||
// Parameter represents a sequence parameter. Sequence parameters with
|
||||
// Param represents a sequence parameter. Sequence parameters with
|
||||
// sub-parameters are packed with the HasMoreFlag set. This is used to unpack
|
||||
// the parameters from a CSI and DCS sequences.
|
||||
type Parameter int
|
||||
type Param int
|
||||
|
||||
// Param returns the unpacked parameter at the given index.
|
||||
// It returns the default value if the parameter is missing.
|
||||
func (s Parameter) Param(def int) int {
|
||||
func (s Param) Param(def int) int {
|
||||
p := int(s) & parser.ParamMask
|
||||
if p == parser.MissingParam {
|
||||
return def
|
||||
@ -446,16 +509,16 @@ func (s Parameter) Param(def int) int {
|
||||
}
|
||||
|
||||
// HasMore unpacks the HasMoreFlag from the parameter.
|
||||
func (s Parameter) HasMore() bool {
|
||||
func (s Param) HasMore() bool {
|
||||
return s&parser.HasMoreFlag != 0
|
||||
}
|
||||
|
||||
// Param returns a packed [Parameter] with the given parameter and whether this
|
||||
// parameter has following sub-parameters.
|
||||
func Param(p int, hasMore bool) (s Parameter) {
|
||||
s = Parameter(p & parser.ParamMask)
|
||||
// Parameter packs an escape code parameter with the given parameter and
|
||||
// whether this parameter has following sub-parameters.
|
||||
func Parameter(p int, hasMore bool) (s int) {
|
||||
s = p & parser.ParamMask
|
||||
if hasMore {
|
||||
s |= Parameter(parser.HasMoreFlag)
|
||||
s |= parser.HasMoreFlag
|
||||
}
|
||||
return
|
||||
}
|
||||
|
Reference in New Issue
Block a user