Skip to content

Commit

Permalink
feat(term): add ansi sequences support
Browse files Browse the repository at this point in the history
This package define common ansi sequences and control codes used in a
terminal session.

For example, `style.String` to style a string using
the SGR escape sequence. `style.String("Foobar", style.Bold,
style.ForegrondColor(style.Red))` will produce a sequence that wraps the
word "Foobar" in two SGR sequences to display the word in bold and red
foreground color, and then reset SGR styles.

Another example is using the `mode` package to enable/disable/request
various terminal modes. E.g. to enable alternate screen buffer mode
`fmt.Fprint(os.Stderr, mode.EnableAltScreenBuffer)`.
  • Loading branch information
aymanbagabas committed Jan 12, 2024
1 parent 464260e commit 7a278ef
Show file tree
Hide file tree
Showing 23 changed files with 1,158 additions and 0 deletions.
8 changes: 8 additions & 0 deletions exp/term/ansi/ascii.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package ansi

const (
// SP is the space character (Char: \x20).
SP byte = 0x20
// DEL is the delete character (Caret: ^?, Char: \x7f).
DEL byte = 0x7F
)
72 changes: 72 additions & 0 deletions exp/term/ansi/c0.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package ansi

// C0 is a control character ranges from (0x00-0x1F) as defined in ISO 646 (ASCII).
// See: https://en.wikipedia.org/wiki/C0_and_C1_control_codes
type C0 = byte

const (
// NUL is the null character (Caret: ^@, Char: \0).
NUL C0 = 0x00
// SOH is the start of heading character (Caret: ^A).
SOH C0 = 0x01
// STX is the start of text character (Caret: ^B).
STX C0 = 0x02
// ETX is the end of text character (Caret: ^C).
ETX C0 = 0x03
// EOT is the end of transmission character (Caret: ^D).
EOT C0 = 0x04
// ENQ is the enquiry character (Caret: ^E).
ENQ C0 = 0x05
// ACK is the acknowledge character (Caret: ^F).
ACK C0 = 0x06
// BEL is the bell character (Caret: ^G, Char: \a).
BEL C0 = 0x07
// BS is the backspace character (Caret: ^H, Char: \b).
BS C0 = 0x08
// HT is the horizontal tab character (Caret: ^I, Char: \t).
HT C0 = 0x09
// LF is the line feed character (Caret: ^J, Char: \n).
LF C0 = 0x0A
// VT is the vertical tab character (Caret: ^K, Char: \v).
VT C0 = 0x0B
// FF is the form feed character (Caret: ^L, Char: \f).
FF C0 = 0x0C
// CR is the carriage return character (Caret: ^M, Char: \r).
CR C0 = 0x0D
// SO is the shift out character (Caret: ^N).
SO C0 = 0x0E
// SI is the shift in character (Caret: ^O).
SI C0 = 0x0F
// DLE is the data link escape character (Caret: ^P).
DLE C0 = 0x10
// DC1 is the device control 1 character (Caret: ^Q).
DC1 C0 = 0x11
// DC2 is the device control 2 character (Caret: ^R).
DC2 C0 = 0x12
// DC3 is the device control 3 character (Caret: ^S).
DC3 C0 = 0x13
// DC4 is the device control 4 character (Caret: ^T).
DC4 C0 = 0x14
// NAK is the negative acknowledge character (Caret: ^U).
NAK C0 = 0x15
// SYN is the synchronous idle character (Caret: ^V).
SYN C0 = 0x16
// ETB is the end of transmission block character (Caret: ^W).
ETB C0 = 0x17
// CAN is the cancel character (Caret: ^X).
CAN C0 = 0x18
// EM is the end of medium character (Caret: ^Y).
EM C0 = 0x19
// SUB is the substitute character (Caret: ^Z).
SUB C0 = 0x1A
// ESC is the escape character (Caret: ^[, Char: \e).
ESC C0 = 0x1B
// FS is the file separator character (Caret: ^\).
FS C0 = 0x1C
// GS is the group separator character (Caret: ^]).
GS C0 = 0x1D
// RS is the record separator character (Caret: ^^).
RS C0 = 0x1E
// US is the unit separator character (Caret: ^_).
US C0 = 0x1F
)
73 changes: 73 additions & 0 deletions exp/term/ansi/c1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package ansi

// C1 is a control character ranges from (0x80-0x9F) as defined in ISO 6429 (ECMA-48).
// See: https://en.wikipedia.org/wiki/C0_and_C1_control_codes
type C1 = byte

// C1 control characters.
const (
// PAD is the padding character.
PAD C1 = 0x80
// HOP is the high octet preset character.
HOP C1 = 0x81
// BPH is the break permitted here character.
BPH C1 = 0x82
// NBH is the no break here character.
NBH C1 = 0x83
// IND is the index character.
IND C1 = 0x84
// NEL is the next line character.
NEL C1 = 0x85
// SSA is the start of selected area character.
SSA C1 = 0x86
// ESA is the end of selected area character.
ESA C1 = 0x87
// HTS is the horizontal tab set character.
HTS C1 = 0x88
// HTJ is the horizontal tab with justification character.
HTJ C1 = 0x89
// VTS is the vertical tab set character.
VTS C1 = 0x8A
// PLD is the partial line forward character.
PLD C1 = 0x8B
// PLU is the partial line backward character.
PLU C1 = 0x8C
// RI is the reverse index character.
RI C1 = 0x8D
// SS2 is the single shift 2 character.
SS2 C1 = 0x8E
// SS3 is the single shift 3 character.
SS3 C1 = 0x8F
// DCS is the device control string character.
DCS C1 = 0x90
// PU1 is the private use 1 character.
PU1 C1 = 0x91
// PU2 is the private use 2 character.
PU2 C1 = 0x92
// STS is the set transmit state character.
STS C1 = 0x93
// CCH is the cancel character.
CCH C1 = 0x94
// MW is the message waiting character.
MW C1 = 0x95
// SPA is the start of guarded area character.
SPA C1 = 0x96
// EPA is the end of guarded area character.
EPA C1 = 0x97
// SOS is the start of string character.
SOS C1 = 0x98
// SGCI is the single graphic character introducer character.
SGCI C1 = 0x99
// SCI is the single character introducer character.
SCI C1 = 0x9A
// CSI is the control sequence introducer character.
CSI C1 = 0x9B
// ST is the string terminator character.
ST C1 = 0x9C
// OSC is the operating system command character.
OSC C1 = 0x9D
// PM is the privacy message character.
PM C1 = 0x9E
// APC is the application program command character.
APC C1 = 0x9F
)
110 changes: 110 additions & 0 deletions exp/term/ansi/cursor/cursor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package cursor

import "strconv"

// Save (DECSC) is an escape sequence that saves the current cursor position.
const Save = "\x1b" + "7"

// Restore (DECRC) is an escape sequence that restores the cursor position.
const Restore = "\x1b" + "8"

// Up (CUU) returns a sequence for moving the cursor up n cells.
//
// CSI n A
func Up(n int) string {
var s string
if n > 1 {
s = strconv.Itoa(n)
}
return "\x1b" + "[" + s + "A"
}

// Down (CUD) returns a sequence for moving the cursor down n cells.
//
// CSI n B
func Down(n int) string {
var s string
if n > 1 {
s = strconv.Itoa(n)
}
return "\x1b" + "[" + s + "B"
}

// Right (CUF) returns a sequence for moving the cursor right n cells.
//
// CSI n C
func Right(n int) string {
var s string
if n > 1 {
s = strconv.Itoa(n)
}
return "\x1b" + "[" + s + "C"
}

// Left (CUB) returns a sequence for moving the cursor left n cells.
//
// CSI n D
func Left(n int) string {
var s string
if n > 1 {
s = strconv.Itoa(n)
}
return "\x1b" + "[" + s + "D"
}

// NextLine (CNL) returns a sequence for moving the cursor to the beginning of
// the next line n times.
//
// CSI n E
func NextLine(n int) string {
var s string
if n > 1 {
s = strconv.Itoa(n)
}
return "\x1b" + "[" + s + "E"
}

// PreviousLine (CPL) returns a sequence for moving the cursor to the beginning
// of the previous line n times.
//
// CSI n F
func PreviousLine(n int) string {
var s string
if n > 1 {
s = strconv.Itoa(n)
}
return "\x1b" + "[" + s + "F"
}

// Position (CUP) returns a sequence for positioning the cursor to the given
// row and column.
//
// CSI n ; m H
func Position(row, col int) string {
var r, c string
if row > 1 {
r = strconv.Itoa(row)
}
if col > 1 {
c = strconv.Itoa(col)
}
return "\x1b" + "[" + r + ";" + c + "H"
}

// SavePosition (SCP or SCOSC) is a sequence for saving the cursor position.
//
// CSI s
//
// This acts like Save, except the page number where the cursor is located is
// not saved.
// See: https://vt100.net/docs/vt510-rm/SCOSC.html
const SavePosition = "\x1b" + "[" + "s"

// RestorePosition (RCP or SCORC) is a sequence for restoring the cursor position.
//
// CSI u
//
// This acts like Restore, except the cursor stays on the same page where the
// cursor was saved.
// See: https://vt100.net/docs/vt510-rm/SCORC.html
const RestorePosition = "\x1b" + "[" + "u"
6 changes: 6 additions & 0 deletions exp/term/ansi/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// This package defines common ANSI escape sequences.
//
// All sequences use 7-bit C1 control codes, which are supported by most
// terminal emulators. Osc sequences are terminated by a BEL for wider
// compatibility with terminals.
package ansi
22 changes: 22 additions & 0 deletions exp/term/ansi/internal/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package internal

import (
"fmt"
"image/color"
)

// ColorToHexString returns a hex string representation of a color.
func ColorToHexString(c color.Color) string {
if c == nil {
return ""
}
r, g, b, _ := c.RGBA()
return fmt.Sprintf("#%02x%02x%02x", r, g, b)
}

// RgbToHex converts red, green, and blue values to a hexadecimal value.
//
// hex := RgbToHex(0, 0, 255) // 0x0000FF
func RgbToHex(r, g, b uint32) uint32 {
return r<<16 + g<<8 + b
}
1 change: 1 addition & 0 deletions exp/term/ansi/mode/ansi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package mode
Loading

0 comments on commit 7a278ef

Please sign in to comment.