Skip to content
Snippets Groups Projects
Select Git revision
  • f12fb351b0b4226d40ccc3d23b82b41187dcd2da
  • master default protected
  • 1.31
  • 4.25.3
  • 4.25.2
  • 4.25.1
  • 4.25.0
  • 4.24.3
  • 4.24.2
  • 4.24.1
  • 4.24.0
  • 4.23.6
  • 4.23.5
  • 4.23.4
  • 4.23.3
  • 4.23.2
  • 4.23.1
  • 4.23.0
  • 4.22.3
  • 4.22.2
  • 4.22.1
  • 4.22.0
  • 4.21.0
23 results

start-server.nix

Blame
  • csi.go 4.04 KiB
    package ansi
    
    import (
    	"bytes"
    	"strconv"
    
    	"github.com/charmbracelet/x/ansi/parser"
    )
    
    // CsiSequence represents a control sequence introducer (CSI) sequence.
    //
    // The sequence starts with a CSI sequence, CSI (0x9B) in a 8-bit environment
    // or ESC [ (0x1B 0x5B) in a 7-bit environment, followed by any number of
    // parameters in the range of 0x30-0x3F, then by any number of intermediate
    // byte in the range of 0x20-0x2F, then finally with a single final byte in the
    // range of 0x20-0x7E.
    //
    //	CSI P..P I..I F
    //
    // See ECMA-48 § 5.4.
    type CsiSequence struct {
    	// Params contains the raw parameters of the sequence.
    	// This is a slice of integers, where each integer is a 32-bit integer
    	// containing the parameter value in the lower 31 bits and a flag in the
    	// most significant bit indicating whether there are more sub-parameters.
    	Params []int
    
    	// Cmd contains the raw command of the sequence.
    	// The command is a 32-bit integer containing the CSI command byte in the
    	// lower 8 bits, the private marker in the next 8 bits, and the intermediate
    	// byte in the next 8 bits.
    	//
    	//  CSI ? u
    	//
    	// Is represented as:
    	//
    	//  'u' | '?' << 8
    	Cmd int
    }
    
    var _ Sequence = CsiSequence{}
    
    // Marker returns the marker 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 (s CsiSequence) Marker() int {
    	return parser.Marker(s.Cmd)
    }
    
    // Intermediate returns the intermediate byte of the CSI sequence.
    // An intermediate byte is in the range of 0x20-0x2F. This includes these
    // characters from ' ', '!', '"', '#', '$', '%', '&', ”', '(', ')', '*', '+',
    // ',', '-', '.', '/'.
    // Zero is returned if the sequence does not have an intermediate byte.
    func (s CsiSequence) Intermediate() int {
    	return parser.Intermediate(s.Cmd)
    }
    
    // Command returns the command byte of the CSI sequence.
    func (s CsiSequence) Command() int {
    	return parser.Command(s.Cmd)
    }
    
    // Param returns the parameter at the given index.
    // It returns -1 if the parameter does not exist.
    func (s CsiSequence) Param(i int) int {
    	return parser.Param(s.Params, i)
    }
    
    // HasMore returns true if the parameter has more sub-parameters.
    func (s CsiSequence) HasMore(i int) bool {
    	return parser.HasMore(s.Params, i)
    }
    
    // Subparams returns the sub-parameters of the given parameter.
    // It returns nil if the parameter does not exist.
    func (s CsiSequence) Subparams(i int) []int {
    	return parser.Subparams(s.Params, i)
    }
    
    // Len returns the number of parameters in the sequence.
    // This will return the number of parameters in the sequence, excluding any
    // sub-parameters.
    func (s CsiSequence) Len() int {
    	return parser.Len(s.Params)
    }
    
    // Range iterates over the parameters of the sequence and calls the given
    // function for each parameter.
    // The function should return false to stop the iteration.
    func (s CsiSequence) Range(fn func(i int, param int, hasMore bool) bool) {
    	parser.Range(s.Params, fn)
    }
    
    // Clone returns a copy of the CSI sequence.
    func (s CsiSequence) Clone() Sequence {
    	return CsiSequence{
    		Params: append([]int(nil), s.Params...),
    		Cmd:    s.Cmd,
    	}
    }
    
    // String returns a string representation of the sequence.
    // The string will always be in the 7-bit format i.e (ESC [ P..P I..I F).
    func (s CsiSequence) String() string {
    	return s.buffer().String()
    }
    
    // buffer returns a buffer containing the sequence.
    func (s CsiSequence) buffer() *bytes.Buffer {
    	var b bytes.Buffer
    	b.WriteString("\x1b[")
    	if m := s.Marker(); m != 0 {
    		b.WriteByte(byte(m))
    	}
    	s.Range(func(i, param int, hasMore bool) bool {
    		if param >= 0 {
    			b.WriteString(strconv.Itoa(param))
    		}
    		if i < len(s.Params)-1 {
    			if hasMore {
    				b.WriteByte(':')
    			} else {
    				b.WriteByte(';')
    			}
    		}
    		return true
    	})
    	if i := s.Intermediate(); i != 0 {
    		b.WriteByte(byte(i))
    	}
    	b.WriteByte(byte(s.Command()))
    	return &b
    }
    
    // Bytes returns the byte representation of the sequence.
    // The bytes will always be in the 7-bit format i.e (ESC [ P..P I..I F).
    func (s CsiSequence) Bytes() []byte {
    	return s.buffer().Bytes()
    }