github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/utils/virtualterm/write.go (about) 1 package virtualterm 2 3 const ( 4 charEsc = 27 5 charBackspaceIso = 8 6 charBackspaceAnsi = 127 7 ) 8 9 func (term *Term) writeCell(r rune) { 10 term.cell().char = r 11 term.cell().sgr = term.sgr 12 term.wrapCursorForwards() 13 } 14 15 // Write multiple characters to the virtual terminal 16 func (term *Term) Write(text []rune) { 17 var ( 18 escape bool 19 ) 20 21 term.mutex.Lock() 22 23 for i := 0; i < len(text); i++ { 24 switch text[i] { 25 case charBackspaceIso, charBackspaceAnsi: 26 panic("TODO: backspace") 27 28 case charEsc: 29 escape = true 30 31 case '[': 32 if escape { 33 i += parseSgr(term, text[i-1:]) 34 continue 35 } 36 term.writeCell(text[i]) 37 38 case '\r': 39 //if grid.LfIncCr { 40 // continue 41 //} 42 term.curPos.X = 0 43 44 case '\n': 45 if term.state.LfIncCr { 46 term.curPos.X = 0 47 } 48 if term.moveCursorDownwards(1) > 0 { 49 term.moveContentsUp() 50 term.moveCursorDownwards(1) 51 } 52 53 default: 54 term.writeCell(text[i]) 55 56 } 57 } 58 59 term.mutex.Unlock() 60 } 61 62 func parseSgr(term *Term, text []rune) int { 63 i := 2 64 65 var n rune 66 67 for ; i < len(text); i++ { 68 switch { 69 case text[i] >= '0' && '9' >= text[i]: 70 n = (n * 10) + (text[i] - 48) 71 72 case text[i] == 'm': // SGR 73 lookupSgr(term, n) 74 return i - 1 75 76 case text[i] == 'A': // moveCursorUp 77 term.moveCursorUpwards(int(n)) 78 return i - 1 79 80 case text[i] == 'B': // moveCursorDown 81 term.moveCursorDownwards(int(n)) 82 return i - 1 83 84 case text[i] == 'C': // moveCursorForwards 85 term.moveCursorForwards(int(n)) 86 return i - 1 87 88 case text[i] == 'D': // moveCursorBackwards 89 term.moveCursorBackwards(int(n)) 90 return i - 1 91 92 case text[i] == 'J': // eraseDisplay... 93 if n == 0 { 94 term.eraseDisplayAfter() 95 } 96 97 default: 98 return i - 1 99 } 100 } 101 return i 102 } 103 104 func lookupSgr(term *Term, n rune) { 105 switch n { 106 case 0: // reset / normal 107 term.sgrReset() 108 109 case 1: // bold 110 term.sgrEffect(sgrBold) 111 112 case 4: // underscore 113 term.sgrEffect(sgrUnderscore) 114 115 case 5: // blink 116 term.sgrEffect(sgrBlink) 117 118 // 119 // 4bit foreground colour: 120 // 121 122 case 30: // fg black 123 term.sgrEffect(sgrFgColour4) 124 term.sgr.fg.Red = sgrColour4Black 125 126 case 31: // fg red 127 term.sgrEffect(sgrFgColour4) 128 term.sgr.fg.Red = sgrColour4Red 129 130 case 32: // fg green 131 term.sgrEffect(sgrFgColour4) 132 term.sgr.fg.Red = sgrColour4Green 133 134 case 33: // fg yellow 135 term.sgrEffect(sgrFgColour4) 136 term.sgr.fg.Red = sgrColour4Yellow 137 138 case 34: // fg blue 139 term.sgrEffect(sgrFgColour4) 140 term.sgr.fg.Red = sgrColour4Blue 141 142 case 35: // fg magenta 143 term.sgrEffect(sgrFgColour4) 144 term.sgr.fg.Red = sgrColour4Magenta 145 146 case 36: // fg cyan 147 term.sgrEffect(sgrFgColour4) 148 term.sgr.fg.Red = sgrColour4Cyan 149 150 case 37: // fg white 151 term.sgrEffect(sgrFgColour4) 152 term.sgr.fg.Red = sgrColour4White 153 } 154 }