v0.1.0 initial commit
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
package terminal
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
)
|
||||
|
||||
// Pre-allocated ANSI sequence fragments (avoid allocations during render)
|
||||
var (
|
||||
// CSI sequences
|
||||
csi = []byte("\x1b[")
|
||||
csiEnd = []byte("m")
|
||||
csiReset = []byte("\x1b[0m")
|
||||
csiClear = []byte("\x1b[2J\x1b[H")
|
||||
csiHome = []byte("\x1b[H")
|
||||
csiRIS = []byte("\x1bc") // Reset to Initial GameState (emergency)
|
||||
csiSGR0 = []byte("\x1b[0m")
|
||||
|
||||
// Cursor control
|
||||
csiCursorHide = []byte("\x1b[?25l")
|
||||
csiCursorShow = []byte("\x1b[?25h")
|
||||
csiCursorPos = []byte("\x1b[") // followed by row;colH
|
||||
|
||||
// Screen modes
|
||||
csiAltScreenEnter = []byte("\x1b[?1049h")
|
||||
csiAltScreenExit = []byte("\x1b[?1049l")
|
||||
// DECAWM: Auto-Wrap Mode
|
||||
// ?7l disables wrapping (cursor sticks at right edge), preventing scroll when writing to bottom-right corner
|
||||
csiAutoWrapOn = []byte("\x1b[?7h")
|
||||
csiAutoWrapOff = []byte("\x1b[?7l")
|
||||
|
||||
// Color prefixes
|
||||
csiFg256 = []byte("\x1b[38;5;") // followed by N;m
|
||||
csiBg256 = []byte("\x1b[48;5;") // followed by N;m
|
||||
csiFgRGB = []byte("\x1b[38;2;") // followed by R;G;B;m
|
||||
csiBgRGB = []byte("\x1b[48;2;") // followed by R;G;B;m
|
||||
csiDefaultFg = []byte("\x1b[39m")
|
||||
csiDefaultBg = []byte("\x1b[49m")
|
||||
|
||||
// Attribute sequences
|
||||
csiAttrBold = []byte("\x1b[1m")
|
||||
csiAttrDim = []byte("\x1b[2m")
|
||||
csiAttrItalic = []byte("\x1b[3m")
|
||||
csiAttrUnderline = []byte("\x1b[4m")
|
||||
csiAttrBlink = []byte("\x1b[5m")
|
||||
csiAttrReverse = []byte("\x1b[7m")
|
||||
|
||||
// Mouse mode sequences (SGR 1006 for extended coordinates)
|
||||
csiMouseClickOn = []byte("\x1b[?1000h") // Enable click reporting
|
||||
csiMouseClickOff = []byte("\x1b[?1000l")
|
||||
csiMouseDragOn = []byte("\x1b[?1002h") // Enable button-event (drag) tracking
|
||||
csiMouseDragOff = []byte("\x1b[?1002l")
|
||||
csiMouseMotionOn = []byte("\x1b[?1003h") // Enable any-event (all motion) tracking
|
||||
csiMouseMotionOff = []byte("\x1b[?1003l")
|
||||
csiMouseSGROn = []byte("\x1b[?1006h") // Enable SGR extended mode
|
||||
csiMouseSGROff = []byte("\x1b[?1006l")
|
||||
)
|
||||
|
||||
// writeInt writes an integer without allocation
|
||||
// Optimized for terminal values (0-255 common, 0-999 typical max)
|
||||
func writeInt(w *bufio.Writer, n int) {
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
if n < 10 {
|
||||
w.WriteByte(byte(n) + '0')
|
||||
return
|
||||
}
|
||||
if n < 100 {
|
||||
w.WriteByte(byte(n/10) + '0')
|
||||
w.WriteByte(byte(n%10) + '0')
|
||||
return
|
||||
}
|
||||
if n < 1000 {
|
||||
w.WriteByte(byte(n/100) + '0')
|
||||
w.WriteByte(byte(n/10%10) + '0')
|
||||
w.WriteByte(byte(n%10) + '0')
|
||||
return
|
||||
}
|
||||
// Fallback for >999 (rare)
|
||||
var buf [5]byte
|
||||
i := 4
|
||||
for n > 0 {
|
||||
buf[i] = byte(n%10) + '0'
|
||||
n /= 10
|
||||
i--
|
||||
}
|
||||
w.Write(buf[i+1:])
|
||||
}
|
||||
|
||||
// writeCursorPos writes cursor positioning sequence (0-indexed input)
|
||||
func writeCursorPos(w *bufio.Writer, x, y int) {
|
||||
w.Write(csiCursorPos)
|
||||
writeInt(w, y+1)
|
||||
w.WriteByte(';')
|
||||
writeInt(w, x+1)
|
||||
w.WriteByte('H')
|
||||
}
|
||||
|
||||
// writeCursorForward writes cursor forward N positions
|
||||
func writeCursorForward(w *bufio.Writer, n int) {
|
||||
if n <= 0 {
|
||||
return
|
||||
}
|
||||
if n == 1 {
|
||||
w.Write([]byte("\x1b[C"))
|
||||
return
|
||||
}
|
||||
w.Write(csi)
|
||||
writeInt(w, n)
|
||||
w.WriteByte('C')
|
||||
}
|
||||
Reference in New Issue
Block a user