status.go

  1package ansi
  2
  3import (
  4	"strconv"
  5	"strings"
  6)
  7
  8// StatusReport represents a terminal status report.
  9type StatusReport interface {
 10	// StatusReport returns the status report identifier.
 11	StatusReport() int
 12}
 13
 14// ANSIReport represents an ANSI terminal status report.
 15type ANSIStatusReport int //nolint:revive
 16
 17// Report returns the status report identifier.
 18func (s ANSIStatusReport) StatusReport() int {
 19	return int(s)
 20}
 21
 22// DECStatusReport represents a DEC terminal status report.
 23type DECStatusReport int
 24
 25// Status returns the status report identifier.
 26func (s DECStatusReport) StatusReport() int {
 27	return int(s)
 28}
 29
 30// DeviceStatusReport (DSR) is a control sequence that reports the terminal's
 31// status.
 32// The terminal responds with a DSR sequence.
 33//
 34//	CSI Ps n
 35//	CSI ? Ps n
 36//
 37// If one of the statuses is a [DECStatus], the sequence will use the DEC
 38// format.
 39//
 40// See also https://vt100.net/docs/vt510-rm/DSR.html
 41func DeviceStatusReport(statues ...StatusReport) string {
 42	var dec bool
 43	list := make([]string, len(statues))
 44	seq := "\x1b["
 45	for i, status := range statues {
 46		list[i] = strconv.Itoa(status.StatusReport())
 47		switch status.(type) {
 48		case DECStatusReport:
 49			dec = true
 50		}
 51	}
 52	if dec {
 53		seq += "?"
 54	}
 55	return seq + strings.Join(list, ";") + "n"
 56}
 57
 58// DSR is an alias for [DeviceStatusReport].
 59func DSR(status StatusReport) string {
 60	return DeviceStatusReport(status)
 61}
 62
 63// RequestCursorPositionReport is an escape sequence that requests the current
 64// cursor position.
 65//
 66//	CSI 6 n
 67//
 68// The terminal will report the cursor position as a CSI sequence in the
 69// following format:
 70//
 71//	CSI Pl ; Pc R
 72//
 73// Where Pl is the line number and Pc is the column number.
 74// See: https://vt100.net/docs/vt510-rm/CPR.html
 75const RequestCursorPositionReport = "\x1b[6n"
 76
 77// RequestExtendedCursorPositionReport (DECXCPR) is a sequence for requesting
 78// the cursor position report including the current page number.
 79//
 80//	CSI ? 6 n
 81//
 82// The terminal will report the cursor position as a CSI sequence in the
 83// following format:
 84//
 85//	CSI ? Pl ; Pc ; Pp R
 86//
 87// Where Pl is the line number, Pc is the column number, and Pp is the page
 88// number.
 89// See: https://vt100.net/docs/vt510-rm/DECXCPR.html
 90const RequestExtendedCursorPositionReport = "\x1b[?6n"
 91
 92// CursorPositionReport (CPR) is a control sequence that reports the cursor's
 93// position.
 94//
 95//	CSI Pl ; Pc R
 96//
 97// Where Pl is the line number and Pc is the column number.
 98//
 99// See also https://vt100.net/docs/vt510-rm/CPR.html
100func CursorPositionReport(line, column int) string {
101	if line < 1 {
102		line = 1
103	}
104	if column < 1 {
105		column = 1
106	}
107	return "\x1b[" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + "R"
108}
109
110// CPR is an alias for [CursorPositionReport].
111func CPR(line, column int) string {
112	return CursorPositionReport(line, column)
113}
114
115// ExtendedCursorPositionReport (DECXCPR) is a control sequence that reports the
116// cursor's position along with the page number (optional).
117//
118//	CSI ? Pl ; Pc R
119//	CSI ? Pl ; Pc ; Pv R
120//
121// Where Pl is the line number, Pc is the column number, and Pv is the page
122// number.
123//
124// If the page number is zero or negative, the returned sequence won't include
125// the page number.
126//
127// See also https://vt100.net/docs/vt510-rm/DECXCPR.html
128func ExtendedCursorPositionReport(line, column, page int) string {
129	if line < 1 {
130		line = 1
131	}
132	if column < 1 {
133		column = 1
134	}
135	if page < 1 {
136		return "\x1b[?" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + "R"
137	}
138	return "\x1b[?" + strconv.Itoa(line) + ";" + strconv.Itoa(column) + ";" + strconv.Itoa(page) + "R"
139}
140
141// DECXCPR is an alias for [ExtendedCursorPositionReport].
142func DECXCPR(line, column, page int) string {
143	return ExtendedCursorPositionReport(line, column, page)
144}