package termutil func (t *Terminal) handleANSI(readChan chan MeasuredRune) (renderRequired bool) { // if the byte is an escape character, read the next byte to determine which one r := <-readChan t.log("ANSI SEQ %c 0x%X", r.Rune, r.Rune) t.mu.Lock() defer t.mu.Unlock() switch r.Rune { case '[': return t.handleCSI(readChan) case ']': return t.handleOSC(readChan) case '(': return t.handleSCS0(readChan) // select character set into G0 case ')': return t.handleSCS1(readChan) // select character set into G1 case '*': return swallowHandler(1)(readChan) // character set bullshit case '+': return swallowHandler(1)(readChan) // character set bullshit case '>': return swallowHandler(0)(readChan) // numeric char selection case '=': return swallowHandler(0)(readChan) // alt char selection case '7': t.GetActiveBuffer().saveCursor() case '8': t.GetActiveBuffer().restoreCursor() case 'D': t.GetActiveBuffer().index() case 'E': t.GetActiveBuffer().newLineEx(true) case 'H': t.GetActiveBuffer().tabSetAtCursor() case 'M': t.GetActiveBuffer().reverseIndex() case 'P': // sixel t.handleSixel(readChan) case 'c': t.GetActiveBuffer().clear() case '#': return t.handleScreenState(readChan) case '^': return t.handlePrivacyMessage(readChan) default: t.log("UNKNOWN ESCAPE SEQUENCE: 0x%X", r.Rune) return false } return true } func swallowHandler(size int) func(pty chan MeasuredRune) bool { return func(pty chan MeasuredRune) bool { for i := 0; i < size; i++ { <-pty } return false } } func (t *Terminal) handleScreenState(readChan chan MeasuredRune) bool { b := <-readChan switch b.Rune { case '8': // DECALN -- Screen Alignment Pattern // hide cursor? buffer := t.GetActiveBuffer() buffer.resetVerticalMargins(uint(buffer.viewHeight)) buffer.SetScrollOffset(0) // Fill the whole screen with E's count := buffer.ViewHeight() * buffer.ViewWidth() for count > 0 { buffer.write(MeasuredRune{Rune: 'E', Width: 1}) count-- if count > 0 && !buffer.modes.AutoWrap && count%buffer.ViewWidth() == 0 { buffer.index() buffer.carriageReturn() } } // restore cursor buffer.setPosition(0, 0) default: return false } return true } func (t *Terminal) handlePrivacyMessage(readChan chan MeasuredRune) bool { isEscaped := false for { b := <-readChan if b.Rune == 0x18 /*CAN*/ || b.Rune == 0x1a /*SUB*/ || (b.Rune == 0x5c /*backslash*/ && isEscaped) { break } if isEscaped { isEscaped = false } else if b.Rune == 0x1b { isEscaped = true continue } } return false }