From d3e7784b4d7ab31cfe85e041592876fb288606a6 Mon Sep 17 00:00:00 2001 From: Liam Galvin Date: Mon, 2 Jul 2018 22:17:12 +0100 Subject: [PATCH] fix stuff --- gui/gui.go | 20 +++++++++++++++----- terminal/cell.go | 2 ++ terminal/escapes.go | 44 ++++++++++++++++++++++++++++++++++---------- terminal/terminal.go | 30 +++++++++++++++++------------- 4 files changed, 68 insertions(+), 28 deletions(-) diff --git a/gui/gui.go b/gui/gui.go index c841386..06c6074 100644 --- a/gui/gui.go +++ b/gui/gui.go @@ -110,7 +110,7 @@ func (gui *GUI) updateTexts() { gui.cells[row][col].SetRune(c.GetRune()) gui.cells[row][col].Show() - if gui.terminal.GetPosition().Col == col && gui.terminal.GetPosition().Line == row { + if gui.terminal.IsCursorVisible() && gui.terminal.GetPosition().Col == col && gui.terminal.GetPosition().Line == row { gui.cells[row][col].SetBgColour( gui.config.ColourScheme.Cursor[0], gui.config.ColourScheme.Cursor[1], @@ -175,8 +175,8 @@ func (gui *GUI) Render() error { gl.BindFragDataLocation(program, 0, gl.Str("outColour\x00")) gui.logger.Debugf("Loading font...") - if err := gui.loadFont("/usr/share/fonts/nerd-fonts-complete/ttf/Roboto Mono Nerd Font Complete.ttf", 12); err != nil { - //if err := gui.loadFont("./fonts/CamingoCode-Regular.ttf", 12); err != nil { + //if err := gui.loadFont("/usr/share/fonts/nerd-fonts-complete/ttf/Roboto Mono Nerd Font Complete.ttf", 12); err != nil { + if err := gui.loadFont("./fonts/Roboto.ttf", 12); err != nil { return fmt.Errorf("Failed to load font: %s", err) } @@ -241,7 +241,17 @@ func (gui *GUI) Render() error { case <-updateChan: updateRequired = 2 case <-ticker.C: - text.SetString(fmt.Sprintf("%dx%d@%d,%d", gui.cols, gui.rows, gui.terminal.GetPosition().Col, gui.terminal.GetPosition().Line)) + ca := gui.terminal.GetCellAttributes() + text.SetString( + fmt.Sprintf( + "%dx%d@%d,%d reverse=%t", + gui.cols, + gui.rows, + gui.terminal.GetPosition().Col, + gui.terminal.GetPosition().Line, + ca.Reverse, + ), + ) updateRequired = 2 default: break CheckUpdate @@ -275,7 +285,7 @@ func (gui *GUI) Render() error { } // debug to show co-ords - //text.Draw() + text.Draw() } glfw.PollEvents() diff --git a/terminal/cell.go b/terminal/cell.go index 64df833..8a7ec8e 100644 --- a/terminal/cell.go +++ b/terminal/cell.go @@ -34,6 +34,7 @@ func (cell *Cell) IsHidden() bool { } func (cell *Cell) GetFgColour() (r float32, g float32, b float32) { + if cell.attr.Reverse { return cell.attr.BgColour[0], cell.attr.BgColour[1], cell.attr.BgColour[2] } @@ -41,6 +42,7 @@ func (cell *Cell) GetFgColour() (r float32, g float32, b float32) { } func (cell *Cell) GetBgColour() (r float32, g float32, b float32) { + if cell.attr.Reverse { return cell.attr.FgColour[0], cell.attr.FgColour[1], cell.attr.FgColour[2] } diff --git a/terminal/escapes.go b/terminal/escapes.go index b3d1823..133d422 100644 --- a/terminal/escapes.go +++ b/terminal/escapes.go @@ -2,6 +2,7 @@ package terminal import ( "strconv" + "strings" ) func (terminal *Terminal) processInput(buffer chan rune) { @@ -16,24 +17,25 @@ func (terminal *Terminal) processInput(buffer chan rune) { switch b { case 0x5b: // CSI: Control Sequence Introducer ] var final rune - params := []string{} + param := "" + intermediate := "" CSI: for { b = <-buffer - param := "" switch true { case b >= 0x30 && b <= 0x3F: param = param + string(b) case b >= 0x20 && b <= 0x2F: - params = append(params, param) - param = "" + //intermediate? useful? + intermediate += string(b) case b >= 0x40 && b <= 0x7e: - params = append(params, param) final = b break CSI } } + params := strings.Split(param, ";") + switch final { case 'A': distance := 1 @@ -156,6 +158,7 @@ func (terminal *Terminal) processInput(buffer chan rune) { terminal.position.Col = x - 1 terminal.position.Line = y - 1 } + case 'J': n := "0" @@ -215,7 +218,12 @@ func (terminal *Terminal) processInput(buffer chan rune) { switch n { case "0", "": - terminal.ClearToEndOfLine() + line := terminal.getBufferedLine(terminal.position.Line) + if line != nil { + if terminal.position.Col < len(line.Cells) { + line.Cells = line.Cells[:terminal.position.Col] + } + } case "1": line := terminal.getBufferedLine(terminal.position.Line) if line != nil { @@ -231,12 +239,13 @@ func (terminal *Terminal) processInput(buffer chan rune) { default: terminal.logger.Errorf("Unsupported EL: %s", n) } + case 'm': // SGR: colour and shit for i := range params { param := params[i] switch param { - case "0": + case "0", "": terminal.cellAttr = terminal.defaultCellAttr case "1": terminal.cellAttr.Bold = true @@ -330,13 +339,23 @@ func (terminal *Terminal) processInput(buffer chan rune) { terminal.cellAttr.BgColour = terminal.colourScheme.LightCyanBg case "107": terminal.cellAttr.BgColour = terminal.colourScheme.WhiteBg + default: + terminal.logger.Errorf("Unknown SGR control sequence: (ESC[%s%s%s)", param, intermediate, string(final)) } + + terminal.logger.Debugf("SGR control sequence: (ESC[%s%s%s)", param, intermediate, string(final)) } default: - b = <-buffer - terminal.logger.Errorf("Unknown CSI control sequence: 0x%02X (%s)", final, string(final)) + switch param + intermediate + string(final) { + case "?25h": + terminal.showCursor() + case "?25l": + terminal.hideCursor() + default: + terminal.logger.Errorf("Unknown CSI control sequence: 0x%02X (ESC[%s%s%s)", final, param, intermediate, string(final)) + } } case 0x5d: // OSC: Operating System Command b = <-buffer @@ -364,7 +383,12 @@ func (terminal *Terminal) processInput(buffer chan rune) { terminal.logger.Errorf("RIS not yet supported") case rune(')'), rune('('): b = <-buffer - terminal.logger.Debugf("Ignoring character set control code )%s", string(b)) + // todo charset changes + //terminal.logger.Debugf("Ignoring character set control code )%s", string(b)) + case '>': + // numeric char selection @todo + case '=': + //alternate char selection @todo default: terminal.logger.Errorf("Unknown control sequence: 0x%02X [%s]", b, string(b)) } diff --git a/terminal/terminal.go b/terminal/terminal.go index 9abe96b..e00189d 100644 --- a/terminal/terminal.go +++ b/terminal/terminal.go @@ -23,6 +23,7 @@ type Terminal struct { colourScheme ColourScheme cellAttr CellAttributes defaultCellAttr CellAttributes + cursorVisible bool } type Line struct { @@ -107,6 +108,10 @@ func New(pty *os.File, logger *zap.SugaredLogger, colourScheme ColourScheme) *Te } } +func (terminal *Terminal) GetCellAttributes() CellAttributes { + return terminal.cellAttr +} + func (terminal *Terminal) OnUpdate(handler func()) { terminal.onUpdate = append(terminal.onUpdate, handler) } @@ -121,6 +126,18 @@ func (terminal *Terminal) getPosition() Position { return terminal.position } +func (terminal *Terminal) IsCursorVisible() bool { + return terminal.cursorVisible +} + +func (terminal *Terminal) showCursor() { + terminal.cursorVisible = true +} + +func (terminal *Terminal) hideCursor() { + terminal.cursorVisible = false +} + func (terminal *Terminal) incrementPosition() { position := terminal.getPosition() if position.Col+1 >= int(terminal.size.Width) { @@ -154,19 +171,6 @@ func (terminal *Terminal) Write(data []byte) error { return err } -func (terminal *Terminal) ClearToEndOfLine() { - - position := terminal.getPosition() - - line := terminal.getBufferedLine(position.Line) - if line != nil { - if position.Col < len(line.Cells) { - line.Cells = line.Cells[:position.Col] - } - } - -} - // we have thousands of lines of output. if the terminal is X lines high, we just want to lookat the most recent X lines to render (unless scroll etc) func (terminal *Terminal) getBufferedLine(line int) *Line {