package terminal import ( "context" "time" ) // Wish list here: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html type TerminalCharSet int type escapeSequenceHandler func(pty chan rune, terminal *Terminal) error var escapeSequenceMap = map[rune]escapeSequenceHandler{ 0x05: enqSequenceHandler, 0x07: bellSequenceHandler, 0x08: backspaceSequenceHandler, 0x09: tabSequenceHandler, 0x0a: newLineSequenceHandler, 0x0b: newLineSequenceHandler, 0x0c: newLineSequenceHandler, 0x0d: carriageReturnSequenceHandler, 0x0e: shiftOutSequenceHandler, 0x0f: shiftInSequenceHandler, 0x1b: ansiHandler, } func newLineSequenceHandler(pty chan rune, terminal *Terminal) error { terminal.logger.Debugf("New line!") terminal.ActiveBuffer().NewLine() return nil } func carriageReturnSequenceHandler(pty chan rune, terminal *Terminal) error { terminal.ActiveBuffer().CarriageReturn() return nil } func backspaceSequenceHandler(pty chan rune, terminal *Terminal) error { terminal.ActiveBuffer().Backspace() return nil } func bellSequenceHandler(pty chan rune, terminal *Terminal) error { // @todo ring bell - flash red or some shit? return nil } func enqSequenceHandler(pty chan rune, terminal *Terminal) error { terminal.logger.Errorf("Received ENQ!") return nil } func shiftOutSequenceHandler(pty chan rune, terminal *Terminal) error { terminal.logger.Errorf("Received shift out") return nil } func shiftInSequenceHandler(pty chan rune, terminal *Terminal) error { terminal.logger.Errorf("Received shift in") return nil } func tabSequenceHandler(pty chan rune, terminal *Terminal) error { terminal.logger.Errorf("Received tab") return nil } func (terminal *Terminal) processInput(ctx context.Context, pty chan rune) { // https://en.wikipedia.org/wiki/ANSI_escape_code for { select { case <-terminal.pauseChan: // @todo alert user when terminal is suspended terminal.logger.Debugf("Terminal suspended") <-terminal.resumeChan case <-ctx.Done(): break default: } if terminal.config.Slomo { time.Sleep(time.Millisecond * 100) } b := <-pty handler, ok := escapeSequenceMap[b] if ok { if err := handler(pty, terminal); err != nil { terminal.logger.Errorf("Error handling escape sequence: %s", err) } } else { //terminal.logger.Debugf("Received character 0x%X: %q", b, string(b)) if b >= 0x20 { terminal.ActiveBuffer().Write(b) } else { terminal.logger.Error("Non-readable rune received: 0x%X", b) } } terminal.isDirty = true } }