forked from toolshed/abra
116 lines
2.7 KiB
Go
116 lines
2.7 KiB
Go
package ansi
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// Status represents a terminal status report.
|
|
type Status interface {
|
|
// Status returns the status report identifier.
|
|
Status() int
|
|
}
|
|
|
|
// ANSIStatus represents an ANSI terminal status report.
|
|
type ANSIStatus int //nolint:revive
|
|
|
|
// Status returns the status report identifier.
|
|
func (s ANSIStatus) Status() int {
|
|
return int(s)
|
|
}
|
|
|
|
// DECStatus represents a DEC terminal status report.
|
|
type DECStatus int
|
|
|
|
// Status returns the status report identifier.
|
|
func (s DECStatus) Status() int {
|
|
return int(s)
|
|
}
|
|
|
|
// DeviceStatusReport (DSR) is a control sequence that reports the terminal's
|
|
// status.
|
|
// The terminal responds with a DSR sequence.
|
|
//
|
|
// CSI Ps n
|
|
// CSI ? Ps n
|
|
//
|
|
// If one of the statuses is a [DECStatus], the sequence will use the DEC
|
|
// format.
|
|
//
|
|
// See also https://vt100.net/docs/vt510-rm/DSR.html
|
|
func DeviceStatusReport(statues ...Status) string {
|
|
var dec bool
|
|
list := make([]string, len(statues))
|
|
seq := "\x1b["
|
|
for i, status := range statues {
|
|
list[i] = strconv.Itoa(status.Status())
|
|
switch status.(type) {
|
|
case DECStatus:
|
|
dec = true
|
|
}
|
|
}
|
|
if dec {
|
|
seq += "?"
|
|
}
|
|
return seq + strings.Join(list, ";") + "n"
|
|
}
|
|
|
|
// DSR is an alias for [DeviceStatusReport].
|
|
func DSR(status Status) string {
|
|
return DeviceStatusReport(status)
|
|
}
|
|
|
|
// CursorPositionReport (CPR) is a control sequence that reports the cursor's
|
|
// position.
|
|
//
|
|
// CSI Pl ; Pc R
|
|
//
|
|
// Where Pl is the line number and Pc is the column number.
|
|
//
|
|
// See also https://vt100.net/docs/vt510-rm/CPR.html
|
|
func CursorPositionReport(line, column int) string {
|
|
if line < 1 {
|
|
line = 1
|
|
}
|
|
if column < 1 {
|
|
column = 1
|
|
}
|
|
return "\x1b[" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + "R"
|
|
}
|
|
|
|
// CPR is an alias for [CursorPositionReport].
|
|
func CPR(line, column int) string {
|
|
return CursorPositionReport(line, column)
|
|
}
|
|
|
|
// ExtendedCursorPositionReport (DECXCPR) is a control sequence that reports the
|
|
// cursor's position along with the page number (optional).
|
|
//
|
|
// CSI ? Pl ; Pc R
|
|
// CSI ? Pl ; Pc ; Pv R
|
|
//
|
|
// Where Pl is the line number, Pc is the column number, and Pv is the page
|
|
// number.
|
|
//
|
|
// If the page number is zero or negative, the returned sequence won't include
|
|
// the page number.
|
|
//
|
|
// See also https://vt100.net/docs/vt510-rm/DECXCPR.html
|
|
func ExtendedCursorPositionReport(line, column, page int) string {
|
|
if line < 1 {
|
|
line = 1
|
|
}
|
|
if column < 1 {
|
|
column = 1
|
|
}
|
|
if page < 1 {
|
|
return "\x1b[?" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + "R"
|
|
}
|
|
return "\x1b[?" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + ";" + strconv.Itoa(page) + "R"
|
|
}
|
|
|
|
// DECXCPR is an alias for [ExtendedCursorPositionReport].
|
|
func DECXCPR(line, column, page int) string {
|
|
return ExtendedCursorPositionReport(line, column, page)
|
|
}
|