| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- package ansi
- // Method is a type that represents the how the renderer should calculate the
- // display width of cells.
- type Method uint8
- // Display width modes.
- const (
- WcWidth Method = iota
- GraphemeWidth
- )
- // StringWidth returns the width of a string in cells. This is the number of
- // cells that the string will occupy when printed in a terminal. ANSI escape
- // codes are ignored and wide characters (such as East Asians and emojis) are
- // accounted for.
- func (m Method) StringWidth(s string) int {
- return stringWidth(m, s)
- }
- // Truncate truncates a string to a given length, adding a tail to the end if
- // the string is longer than the given length. This function is aware of ANSI
- // escape codes and will not break them, and accounts for wide-characters (such
- // as East-Asian characters and emojis).
- func (m Method) Truncate(s string, length int, tail string) string {
- return truncate(m, s, length, tail)
- }
- // TruncateLeft truncates a string to a given length, adding a prefix to the
- // beginning if the string is longer than the given length. This function is
- // aware of ANSI escape codes and will not break them, and accounts for
- // wide-characters (such as East-Asian characters and emojis).
- func (m Method) TruncateLeft(s string, length int, prefix string) string {
- return truncateLeft(m, s, length, prefix)
- }
- // Cut the string, without adding any prefix or tail strings. This function is
- // aware of ANSI escape codes and will not break them, and accounts for
- // wide-characters (such as East-Asian characters and emojis). Note that the
- // [left] parameter is inclusive, while [right] isn't.
- func (m Method) Cut(s string, left, right int) string {
- return cut(m, s, left, right)
- }
- // Hardwrap wraps a string or a block of text to a given line length, breaking
- // word boundaries. This will preserve ANSI escape codes and will account for
- // wide-characters in the string.
- // When preserveSpace is true, spaces at the beginning of a line will be
- // preserved.
- // This treats the text as a sequence of graphemes.
- func (m Method) Hardwrap(s string, length int, preserveSpace bool) string {
- return hardwrap(m, s, length, preserveSpace)
- }
- // Wordwrap wraps a string or a block of text to a given line length, not
- // breaking word boundaries. This will preserve ANSI escape codes and will
- // account for wide-characters in the string.
- // The breakpoints string is a list of characters that are considered
- // breakpoints for word wrapping. A hyphen (-) is always considered a
- // breakpoint.
- //
- // Note: breakpoints must be a string of 1-cell wide rune characters.
- func (m Method) Wordwrap(s string, length int, breakpoints string) string {
- return wordwrap(m, s, length, breakpoints)
- }
- // Wrap wraps a string or a block of text to a given line length, breaking word
- // boundaries if necessary. This will preserve ANSI escape codes and will
- // account for wide-characters in the string. The breakpoints string is a list
- // of characters that are considered breakpoints for word wrapping. A hyphen
- // (-) is always considered a breakpoint.
- //
- // Note: breakpoints must be a string of 1-cell wide rune characters.
- func (m Method) Wrap(s string, length int, breakpoints string) string {
- return wrap(m, s, length, breakpoints)
- }
- // DecodeSequence 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 := DecodeSequence(input, state, p)
- // log.Printf("seq: %q, width: %d", seq, width)
- // state = newState
- // input = input[n:]
- // }
- func (m Method) DecodeSequence(data []byte, state byte, p *Parser) (seq []byte, width, n int, newState byte) {
- return decodeSequence(m, data, state, p)
- }
- // DecodeSequenceInString 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 := DecodeSequenceInString(input, state, p)
- // log.Printf("seq: %q, width: %d", seq, width)
- // state = newState
- // input = input[n:]
- // }
- func (m Method) DecodeSequenceInString(data string, state byte, p *Parser) (seq string, width, n int, newState byte) {
- return decodeSequence(m, data, state, p)
- }
|