diff --git a/demo/256.sh b/demo/256.sh new file mode 100755 index 0000000..43e485e --- /dev/null +++ b/demo/256.sh @@ -0,0 +1,12 @@ + +#!/bin/bash + +for i in {0..255} ; do + printf "\x1b[48;5;%sm%3d\e[0m " "$i" "$i" + if (( i == 15 )) || (( i > 15 )) && (( (i-15) % 6 == 0 )); then + printf "\n"; + fi + done + + + diff --git a/terminal/csi.go b/terminal/csi.go index 2ea40b2..96fa116 100644 --- a/terminal/csi.go +++ b/terminal/csi.go @@ -52,8 +52,7 @@ func csiInsertLinesHandler(params []string, intermediate string, terminal *Termi } } terminal.logger.Debugf("Inserting %d lines", count) - panic("Not supported") - return nil + return fmt.Errorf("Not supported") } func csiScrollDownHandler(params []string, intermediate string, terminal *Terminal) error { diff --git a/terminal/sgr.go b/terminal/sgr.go index e438062..c6c8c90 100644 --- a/terminal/sgr.go +++ b/terminal/sgr.go @@ -2,118 +2,203 @@ package terminal import ( "fmt" + "strconv" "github.com/liamg/aminal/buffer" ) func sgrSequenceHandler(params []string, intermediate string, terminal *Terminal) error { - for i := range params { - param := params[i] - switch param { - case "00", "0", "": - attr := terminal.ActiveBuffer().CursorAttr() - *attr = buffer.CellAttributes{ - FgColour: terminal.config.ColourScheme.Foreground, - BgColour: terminal.config.ColourScheme.Background, - } - case "1", "01": - terminal.ActiveBuffer().CursorAttr().Bold = true - case "2", "02": - terminal.ActiveBuffer().CursorAttr().Dim = true - case "4", "04": - terminal.ActiveBuffer().CursorAttr().Underline = true - case "5", "05": - terminal.ActiveBuffer().CursorAttr().Blink = true - case "7", "07": - terminal.ActiveBuffer().CursorAttr().Reverse = true - case "8", "08": - terminal.ActiveBuffer().CursorAttr().Hidden = true - case "21": - terminal.ActiveBuffer().CursorAttr().Bold = false - case "22": - terminal.ActiveBuffer().CursorAttr().Dim = false - case "24": - terminal.ActiveBuffer().CursorAttr().Underline = false - case "25": - terminal.ActiveBuffer().CursorAttr().Blink = false - case "27": - terminal.ActiveBuffer().CursorAttr().Reverse = false - case "28": - terminal.ActiveBuffer().CursorAttr().Hidden = false - case "39": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Foreground - case "30": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Black - case "31": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Red - case "32": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Green - case "33": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Yellow - case "34": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Blue - case "35": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Magenta - case "36": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Cyan - case "37": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.White - case "90": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.DarkGrey - case "91": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightRed - case "92": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightGreen - case "93": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightYellow - case "94": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightBlue - case "95": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightMagenta - case "96": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightCyan - case "97": - terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.White - case "49": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Background - case "40": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Black - case "41": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Red - case "42": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Green - case "43": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Yellow - case "44": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Blue - case "45": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Magenta - case "46": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Cyan - case "47": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.White - case "100": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.DarkGrey - case "101": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightRed - case "102": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightGreen - case "103": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightYellow - case "104": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightBlue - case "105": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightMagenta - case "106": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightCyan - case "107": - terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.White - default: - return fmt.Errorf("Unknown SGR control sequence: (ESC[%s%sm)", param, intermediate) - } - - //terminal.logger.Debugf("SGR control sequence: (ESC[%s%sm)", param, intermediate) + if len(params) == 0 { + return nil } + + param := params[0] + + switch param { + case "00", "0", "": + attr := terminal.ActiveBuffer().CursorAttr() + *attr = buffer.CellAttributes{ + FgColour: terminal.config.ColourScheme.Foreground, + BgColour: terminal.config.ColourScheme.Background, + } + case "1", "01": + terminal.ActiveBuffer().CursorAttr().Bold = true + case "2", "02": + terminal.ActiveBuffer().CursorAttr().Dim = true + case "4", "04": + terminal.ActiveBuffer().CursorAttr().Underline = true + case "5", "05": + terminal.ActiveBuffer().CursorAttr().Blink = true + case "7", "07": + terminal.ActiveBuffer().CursorAttr().Reverse = true + case "8", "08": + terminal.ActiveBuffer().CursorAttr().Hidden = true + case "21": + terminal.ActiveBuffer().CursorAttr().Bold = false + case "22": + terminal.ActiveBuffer().CursorAttr().Dim = false + case "24": + terminal.ActiveBuffer().CursorAttr().Underline = false + case "25": + terminal.ActiveBuffer().CursorAttr().Blink = false + case "27": + terminal.ActiveBuffer().CursorAttr().Reverse = false + case "28": + terminal.ActiveBuffer().CursorAttr().Hidden = false + case "39": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Foreground + case "30": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Black + case "31": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Red + case "32": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Green + case "33": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Yellow + case "34": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Blue + case "35": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Magenta + case "36": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Cyan + case "37": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.White + case "90": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.DarkGrey + case "91": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightRed + case "92": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightGreen + case "93": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightYellow + case "94": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightBlue + case "95": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightMagenta + case "96": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightCyan + case "97": + terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.White + case "49": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Background + case "40": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Black + case "41": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Red + case "42": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Green + case "43": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Yellow + case "44": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Blue + case "45": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Magenta + case "46": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Cyan + case "47": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.White + case "100": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.DarkGrey + case "101": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightRed + case "102": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightGreen + case "103": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightYellow + case "104": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightBlue + case "105": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightMagenta + case "106": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightCyan + case "107": + terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.White + case "38": // set foreground + if len(params) > 2 { + switch params[1] { + case "5": + // 8 bit colour + colNum, err := strconv.Atoi(params[2]) + if err == nil && colNum < 256 && colNum >= 0 { + terminal.ActiveBuffer().CursorAttr().FgColour = get8BitSGRColour(uint8(colNum), terminal) + } + case "2": + // 24 bit colour + } + } + case "48": // set background + if len(params) > 2 { + switch params[1] { + case "5": + // 8 bit colour + colNum, err := strconv.Atoi(params[2]) + if err == nil && colNum < 256 && colNum >= 0 { + terminal.ActiveBuffer().CursorAttr().BgColour = get8BitSGRColour(uint8(colNum), terminal) + } + case "2": + // 24 bit colour + } + } + default: + return fmt.Errorf("Unknown SGR control sequence: (ESC[%s%sm)", param, intermediate) + } + + //terminal.logger.Debugf("SGR control sequence: (ESC[%s%sm)", param, intermediate) + return nil } + +func get8BitSGRColour(colNum uint8, terminal *Terminal) [3]float32 { + + // https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit + + switch colNum { + case 0: + return terminal.config.ColourScheme.Black + case 1: + return terminal.config.ColourScheme.Red + case 2: + return terminal.config.ColourScheme.Green + case 3: + return terminal.config.ColourScheme.Yellow + case 4: + return terminal.config.ColourScheme.Blue + case 5: + return terminal.config.ColourScheme.Magenta + case 6: + return terminal.config.ColourScheme.Cyan + case 7: + return terminal.config.ColourScheme.White + case 8: + return terminal.config.ColourScheme.DarkGrey + case 9: + return terminal.config.ColourScheme.LightRed + case 10: + return terminal.config.ColourScheme.LightGreen + case 11: + return terminal.config.ColourScheme.LightYellow + case 12: + return terminal.config.ColourScheme.LightBlue + case 13: + return terminal.config.ColourScheme.LightMagenta + case 14: + return terminal.config.ColourScheme.LightCyan + case 15: + return terminal.config.ColourScheme.White + } + + if colNum < 232 { + + index := int(colNum - 16) // 0-216 + rgb := (index * 0xffffff) / 216 + r := float32((rgb&0xff0000)>>16) / 0xff + g := float32((rgb&0xff00)>>8) / 0xff + b := float32(rgb&0xff) / 0xff + + return [3]float32{r, g, b} + } + + c := float32(colNum-232) / 0x18 + return [3]float32{c, c, c} +}