mirror of https://github.com/liamg/aminal.git
alt buffer
This commit is contained in:
parent
3ac0d62d72
commit
6d10ffd17c
|
@ -86,15 +86,15 @@ func (buffer *Buffer) CursorAttr() *CellAttributes {
|
|||
return &buffer.cursorAttr
|
||||
}
|
||||
|
||||
func (buffer *Buffer) GetCell(viewCol int, viewRow int) *Cell {
|
||||
func (buffer *Buffer) GetCell(viewCol uint16, viewRow uint16) *Cell {
|
||||
|
||||
rawLine := buffer.convertViewLineToRawLine(uint16(viewRow))
|
||||
rawLine := buffer.convertViewLineToRawLine(viewRow)
|
||||
|
||||
if viewCol < 0 || rawLine < 0 || int(rawLine) >= len(buffer.lines) {
|
||||
return nil
|
||||
}
|
||||
line := &buffer.lines[rawLine]
|
||||
if viewCol >= len(line.cells) {
|
||||
if int(viewCol) >= len(line.cells) {
|
||||
return nil
|
||||
}
|
||||
return &line.cells[viewCol]
|
||||
|
@ -245,6 +245,23 @@ func (buffer *Buffer) Backspace() {
|
|||
}
|
||||
}
|
||||
|
||||
func (buffer *Buffer) BackspaceDelete() {
|
||||
|
||||
if buffer.cursorX == 0 {
|
||||
line := buffer.getCurrentLine()
|
||||
if line.wrapped {
|
||||
buffer.MovePosition(int16(buffer.Width()-1), -1)
|
||||
buffer.GetCell(buffer.cursorX, buffer.cursorY).erase()
|
||||
} else {
|
||||
//@todo ring bell or whatever
|
||||
fmt.Println("BELL?")
|
||||
}
|
||||
} else {
|
||||
buffer.MovePosition(-1, 0)
|
||||
buffer.GetCell(buffer.cursorX, buffer.cursorY).erase()
|
||||
}
|
||||
}
|
||||
|
||||
func (buffer *Buffer) CarriageReturn() {
|
||||
defer buffer.emitDisplayChange()
|
||||
buffer.cursorX = 0
|
||||
|
@ -425,6 +442,7 @@ func (buffer *Buffer) EraseDisplayToCursor() {
|
|||
}
|
||||
|
||||
func (buffer *Buffer) ResizeView(width uint16, height uint16) {
|
||||
|
||||
defer buffer.emitDisplayChange()
|
||||
|
||||
if buffer.viewHeight == 0 {
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
mode: set
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:17.59,25.2 3 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:28.45,30.2 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:33.43,35.2 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:38.40,40.40 2 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:43.2,43.75 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:40.40,42.3 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:47.38,49.2 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:51.42,53.2 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:55.36,57.2 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:59.43,61.2 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:63.53,64.49 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:64.49,66.3 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:70.44,71.26 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:71.26,73.16 2 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:77.3,78.53 2 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:81.3,84.35 4 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:73.16,75.12 2 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:78.53,80.4 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:88.49,90.46 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:90.46,92.3 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:92.8,93.44 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:93.44,98.4 4 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:98.9,100.50 2 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:100.50,105.5 4 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:105.10,106.58 1 0
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:107.5,108.26 2 0
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:114.33,116.25 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:124.2,124.43 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:116.25,118.19 2 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:118.19,121.4 2 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:124.43,127.3 2 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:127.8,130.3 2 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:133.54,135.33 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:139.2,139.33 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:143.2,143.86 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:135.33,137.3 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:139.33,141.3 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:146.60,147.31 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:151.2,151.33 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:155.2,156.23 2 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:147.31,150.3 2 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:151.33,154.3 2 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:159.48,161.80 2 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:166.2,166.14 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:161.80,162.38 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:162.38,164.4 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:171.31,172.48 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:175.2,175.26 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:172.48,174.3 1 1
|
||||
gitlab.com/liamg/raft/buffer/buffer.go:178.63,183.2 2 1
|
||||
gitlab.com/liamg/raft/buffer/cell.go:20.21,22.2 1 1
|
||||
gitlab.com/liamg/raft/buffer/cell.go:24.35,27.2 2 1
|
||||
gitlab.com/liamg/raft/buffer/line.go:8.21,13.2 1 1
|
||||
gitlab.com/liamg/raft/buffer/line.go:15.44,17.2 1 1
|
||||
gitlab.com/liamg/raft/buffer/line.go:19.35,21.34 2 1
|
||||
gitlab.com/liamg/raft/buffer/line.go:24.2,24.22 1 1
|
||||
gitlab.com/liamg/raft/buffer/line.go:21.34,23.3 1 1
|
10
gui/gui.go
10
gui/gui.go
|
@ -75,7 +75,7 @@ func (gui *GUI) glfwScrollCallback(w *glfw.Window, xoff float64, yoff float64) {
|
|||
}
|
||||
}
|
||||
|
||||
func (gui *GUI) getTermSize() (int, int) {
|
||||
func (gui *GUI) getTermSize() (uint, uint) {
|
||||
if gui.renderer == nil {
|
||||
return 0, 0
|
||||
}
|
||||
|
@ -201,14 +201,14 @@ func (gui *GUI) Render() error {
|
|||
lines := gui.terminal.GetVisibleLines()
|
||||
for y := 0; y < len(lines); y++ {
|
||||
for x, cell := range lines[y].Cells() {
|
||||
gui.renderer.DrawCell(cell, x, y)
|
||||
gui.renderer.DrawCell(cell, uint(x), uint(y))
|
||||
}
|
||||
}
|
||||
|
||||
if gui.terminal.Modes().ShowCursor {
|
||||
cx := int(gui.terminal.GetLogicalCursorX())
|
||||
cy := int(gui.terminal.GetLogicalCursorY())
|
||||
cy = int(cy) + int(gui.terminal.GetScrollOffset())
|
||||
cx := uint(gui.terminal.GetLogicalCursorX())
|
||||
cy := uint(gui.terminal.GetLogicalCursorY())
|
||||
cy = cy + uint(gui.terminal.GetScrollOffset())
|
||||
gui.renderer.DrawCursor(cx, cy, gui.config.ColourScheme.Cursor)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,9 +12,9 @@ import (
|
|||
|
||||
type Renderer interface {
|
||||
SetArea(areaX int, areaY int, areaWidth int, areaHeight int)
|
||||
DrawCell(cell buffer.Cell, col int, row int)
|
||||
DrawCursor(col int, row int, colour config.Colour)
|
||||
GetTermSize() (int, int)
|
||||
DrawCell(cell buffer.Cell, col uint, row uint)
|
||||
DrawCursor(col uint, row uint, colour config.Colour)
|
||||
GetTermSize() (uint, uint)
|
||||
}
|
||||
|
||||
type OpenGLRenderer struct {
|
||||
|
@ -27,10 +27,10 @@ type OpenGLRenderer struct {
|
|||
cellWidth float32
|
||||
cellHeight float32
|
||||
verticalCellPadding float32
|
||||
termCols int
|
||||
termRows int
|
||||
cellPositions map[[2]int][2]float32
|
||||
rectangles map[[2]int]*rectangle
|
||||
termCols uint
|
||||
termRows uint
|
||||
cellPositions map[[2]uint][2]float32
|
||||
rectangles map[[2]uint]*rectangle
|
||||
config config.Config
|
||||
colourAttr uint32
|
||||
program uint32
|
||||
|
@ -124,8 +124,8 @@ func NewOpenGLRenderer(config config.Config, font *glfont.Font, fontScale int32,
|
|||
areaX: areaX,
|
||||
areaY: areaY,
|
||||
fontScale: fontScale,
|
||||
cellPositions: map[[2]int][2]float32{},
|
||||
rectangles: map[[2]int]*rectangle{},
|
||||
cellPositions: map[[2]uint][2]float32{},
|
||||
rectangles: map[[2]uint]*rectangle{},
|
||||
config: config,
|
||||
colourAttr: colourAttr,
|
||||
program: program,
|
||||
|
@ -134,7 +134,7 @@ func NewOpenGLRenderer(config config.Config, font *glfont.Font, fontScale int32,
|
|||
return r
|
||||
}
|
||||
|
||||
func (r *OpenGLRenderer) GetTermSize() (int, int) {
|
||||
func (r *OpenGLRenderer) GetTermSize() (uint, uint) {
|
||||
return r.termCols, r.termRows
|
||||
}
|
||||
|
||||
|
@ -156,31 +156,31 @@ func (r *OpenGLRenderer) SetFont(font *glfont.Font) { // @todo check for monospa
|
|||
r.verticalCellPadding = (0.25 * float32(r.fontScale))
|
||||
r.cellWidth = font.Width(1, "X")
|
||||
r.cellHeight = font.Height(1, "X") + (r.verticalCellPadding * 2) // vertical padding
|
||||
r.termCols = int(math.Floor(float64(float32(r.areaWidth) / r.cellWidth)))
|
||||
r.termRows = int(math.Floor(float64(float32(r.areaHeight) / r.cellHeight)))
|
||||
r.termCols = uint(math.Floor(float64(float32(r.areaWidth) / r.cellWidth)))
|
||||
r.termRows = uint(math.Floor(float64(float32(r.areaHeight) / r.cellHeight)))
|
||||
r.calculatePositions()
|
||||
r.generateRectangles()
|
||||
}
|
||||
|
||||
func (r *OpenGLRenderer) calculatePositions() {
|
||||
for line := 0; line < r.termRows; line++ {
|
||||
for col := 0; col < r.termCols; col++ {
|
||||
for line := uint(0); line < r.termRows; line++ {
|
||||
for col := uint(0); col < r.termCols; col++ {
|
||||
// rounding to whole pixels makes everything nice
|
||||
x := float32(math.Round(float64((float32(col) * r.cellWidth))))
|
||||
y := float32(math.Round(float64(
|
||||
(float32(line) * r.cellHeight) + (r.cellHeight / 2) + r.verticalCellPadding,
|
||||
)))
|
||||
r.cellPositions[[2]int{col, line}] = [2]float32{x, y}
|
||||
r.cellPositions[[2]uint{col, line}] = [2]float32{x, y}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *OpenGLRenderer) generateRectangles() {
|
||||
gl.UseProgram(r.program)
|
||||
for line := 0; line < r.termRows; line++ {
|
||||
for col := 0; col < r.termCols; col++ {
|
||||
for line := uint(0); line < r.termRows; line++ {
|
||||
for col := uint(0); col < r.termCols; col++ {
|
||||
|
||||
rect, ok := r.rectangles[[2]int{col, line}]
|
||||
rect, ok := r.rectangles[[2]uint{col, line}]
|
||||
if ok {
|
||||
rect.Free()
|
||||
}
|
||||
|
@ -188,14 +188,14 @@ func (r *OpenGLRenderer) generateRectangles() {
|
|||
// rounding to whole pixels makes everything nice
|
||||
x := float32(float64((float32(col) * r.cellWidth)))
|
||||
y := float32(float64((float32(line) * r.cellHeight) + (r.cellHeight)))
|
||||
r.rectangles[[2]int{col, line}] = r.newRectangle(x, y, r.colourAttr)
|
||||
r.rectangles[[2]uint{col, line}] = r.newRectangle(x, y, r.colourAttr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *OpenGLRenderer) DrawCursor(col int, row int, colour config.Colour) {
|
||||
func (r *OpenGLRenderer) DrawCursor(col uint, row uint, colour config.Colour) {
|
||||
|
||||
rect, ok := r.rectangles[[2]int{col, row}]
|
||||
rect, ok := r.rectangles[[2]uint{col, row}]
|
||||
if !ok { // probably trying to draw during resize - perhaps add a mutex?
|
||||
return
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ func (r *OpenGLRenderer) DrawCursor(col int, row int, colour config.Colour) {
|
|||
//gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL)
|
||||
}
|
||||
|
||||
func (r *OpenGLRenderer) DrawCell(cell buffer.Cell, col int, row int) {
|
||||
func (r *OpenGLRenderer) DrawCell(cell buffer.Cell, col uint, row uint) {
|
||||
|
||||
if cell.Attr().Hidden || (cell.Rune() == 0x00) {
|
||||
return
|
||||
|
@ -235,7 +235,7 @@ func (r *OpenGLRenderer) DrawCell(cell buffer.Cell, col int, row int) {
|
|||
bg = cell.Bg()
|
||||
}
|
||||
|
||||
pos, ok := r.cellPositions[[2]int{col, row}]
|
||||
pos, ok := r.cellPositions[[2]uint{col, row}]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("Missing position data for cell at %d,%d", col, row))
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ func (r *OpenGLRenderer) DrawCell(cell buffer.Cell, col int, row int) {
|
|||
// don't bother rendering rectangles that are the same colour as the background
|
||||
if bg != r.config.ColourScheme.Background {
|
||||
|
||||
rect, ok := r.rectangles[[2]int{col, row}]
|
||||
rect, ok := r.rectangles[[2]uint{col, row}]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("Missing rectangle data for cell at %d,%d", col, row))
|
||||
}
|
||||
|
|
2
main.go
2
main.go
|
@ -84,6 +84,8 @@ func main() {
|
|||
// parse this
|
||||
conf := getConfig()
|
||||
|
||||
os.Setenv("TERM", "xterm-256color")
|
||||
|
||||
logger, err := getLogger(conf)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to create logger: %s\n", err)
|
||||
|
|
|
@ -15,36 +15,36 @@ var ansiSequenceMap = map[rune]escapeSequenceHandler{
|
|||
func indexHandler(buffer chan rune, terminal *Terminal) error {
|
||||
// @todo is thus right?
|
||||
// "This sequence causes the active position to move downward one line without changing the column position. If the active position is at the bottom margin, a scroll up is performed."
|
||||
if terminal.buffer.CursorLine() == terminal.buffer.ViewHeight()-1 {
|
||||
terminal.buffer.NewLine()
|
||||
if terminal.ActiveBuffer().CursorLine() == terminal.ActiveBuffer().ViewHeight()-1 {
|
||||
terminal.ActiveBuffer().NewLine()
|
||||
return nil
|
||||
}
|
||||
terminal.buffer.MovePosition(0, 1)
|
||||
terminal.ActiveBuffer().MovePosition(0, 1)
|
||||
return nil
|
||||
}
|
||||
|
||||
func reverseIndexHandler(buffer chan rune, terminal *Terminal) error {
|
||||
terminal.buffer.MovePosition(0, -1)
|
||||
terminal.ActiveBuffer().MovePosition(0, -1)
|
||||
return nil
|
||||
}
|
||||
|
||||
func saveCursorHandler(buffer chan rune, terminal *Terminal) error {
|
||||
terminal.buffer.SaveCursor()
|
||||
terminal.ActiveBuffer().SaveCursor()
|
||||
return nil
|
||||
}
|
||||
|
||||
func restoreCursorHandler(buffer chan rune, terminal *Terminal) error {
|
||||
terminal.buffer.RestoreCursor()
|
||||
terminal.ActiveBuffer().RestoreCursor()
|
||||
return nil
|
||||
}
|
||||
|
||||
func ansiHandler(buffer chan rune, terminal *Terminal) error {
|
||||
func ansiHandler(pty chan rune, terminal *Terminal) error {
|
||||
// if the byte is an escape character, read the next byte to determine which one
|
||||
b := <-buffer
|
||||
b := <-pty
|
||||
|
||||
handler, ok := ansiSequenceMap[b]
|
||||
if ok {
|
||||
return handler(buffer, terminal)
|
||||
return handler(pty, terminal)
|
||||
}
|
||||
|
||||
switch b {
|
||||
|
@ -52,7 +52,7 @@ func ansiHandler(buffer chan rune, terminal *Terminal) error {
|
|||
case 'c':
|
||||
terminal.logger.Errorf("RIS not yet supported")
|
||||
case '(':
|
||||
b = <-buffer
|
||||
b = <-pty
|
||||
switch b {
|
||||
case 'A': //uk @todo handle these?
|
||||
//terminal.charSet = C0
|
||||
|
@ -60,7 +60,7 @@ func ansiHandler(buffer chan rune, terminal *Terminal) error {
|
|||
//terminal.charSet = C0
|
||||
}
|
||||
case ')':
|
||||
b = <-buffer
|
||||
b = <-pty
|
||||
switch b {
|
||||
case 'A': //uk @todo handle these?
|
||||
//terminal.charSet = C1
|
||||
|
@ -68,7 +68,7 @@ func ansiHandler(buffer chan rune, terminal *Terminal) error {
|
|||
//terminal.charSet = C1
|
||||
}
|
||||
case '*':
|
||||
b = <-buffer
|
||||
b = <-pty
|
||||
switch b {
|
||||
case 'A': //uk @todo handle these?
|
||||
//terminal.charSet = C2
|
||||
|
@ -76,7 +76,7 @@ func ansiHandler(buffer chan rune, terminal *Terminal) error {
|
|||
//terminal.charSet = C2
|
||||
}
|
||||
case '+':
|
||||
b = <-buffer
|
||||
b = <-pty
|
||||
switch b {
|
||||
case 'A': //uk @todo handle these?
|
||||
//terminal.charSet = C3
|
||||
|
@ -90,7 +90,7 @@ func ansiHandler(buffer chan rune, terminal *Terminal) error {
|
|||
case '?':
|
||||
pm := ""
|
||||
for {
|
||||
b = <-buffer
|
||||
b = <-pty
|
||||
switch b {
|
||||
case 'h':
|
||||
switch pm {
|
||||
|
|
|
@ -22,10 +22,28 @@ func csiSetMode(modeStr string, enabled bool, terminal *Terminal) error {
|
|||
switch modeStr {
|
||||
case "?1":
|
||||
terminal.modes.ApplicationCursorKeys = enabled
|
||||
case "?12":
|
||||
case "?12", "?13":
|
||||
terminal.modes.BlinkingCursor = enabled
|
||||
case "?25":
|
||||
terminal.modes.ShowCursor = enabled
|
||||
case "?47", "?1047":
|
||||
if enabled {
|
||||
terminal.UseAltBuffer()
|
||||
} else {
|
||||
terminal.UseMainBuffer()
|
||||
}
|
||||
case "?1048":
|
||||
if enabled {
|
||||
terminal.ActiveBuffer().SaveCursor()
|
||||
} else {
|
||||
terminal.ActiveBuffer().RestoreCursor()
|
||||
}
|
||||
case "?1049":
|
||||
if enabled {
|
||||
terminal.UseAltBuffer()
|
||||
} else {
|
||||
terminal.UseMainBuffer()
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("Unsupported CSI %sl code", modeStr)
|
||||
}
|
||||
|
@ -43,7 +61,7 @@ func csiEraseCharactersHandler(params []string, intermediate string, terminal *T
|
|||
}
|
||||
}
|
||||
|
||||
terminal.buffer.EraseCharacters(count)
|
||||
terminal.ActiveBuffer().EraseCharacters(count)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -71,7 +89,7 @@ func csiLinePositionAbsolute(params []string, intermediate string, terminal *Ter
|
|||
}
|
||||
}
|
||||
|
||||
terminal.buffer.SetPosition(uint16(col), terminal.buffer.CursorLine())
|
||||
terminal.ActiveBuffer().SetPosition(uint16(col), terminal.ActiveBuffer().CursorLine())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -79,7 +97,7 @@ func csiLinePositionAbsolute(params []string, intermediate string, terminal *Ter
|
|||
type csiSequenceHandler func(params []string, intermediate string, terminal *Terminal) error
|
||||
|
||||
// CSI: Control Sequence Introducer [
|
||||
func csiHandler(buffer chan rune, terminal *Terminal) error {
|
||||
func csiHandler(pty chan rune, terminal *Terminal) error {
|
||||
var final rune
|
||||
var b rune
|
||||
var err error
|
||||
|
@ -87,7 +105,7 @@ func csiHandler(buffer chan rune, terminal *Terminal) error {
|
|||
intermediate := ""
|
||||
CSI:
|
||||
for {
|
||||
b = <-buffer
|
||||
b = <-pty
|
||||
switch true {
|
||||
case b >= 0x30 && b <= 0x3F:
|
||||
param = param + string(b)
|
||||
|
@ -117,7 +135,7 @@ CSI:
|
|||
distance = 1
|
||||
}
|
||||
}
|
||||
terminal.buffer.MovePosition(0, -int16(distance))
|
||||
terminal.ActiveBuffer().MovePosition(0, -int16(distance))
|
||||
case 'B':
|
||||
distance := 1
|
||||
if len(params) > 0 {
|
||||
|
@ -128,7 +146,7 @@ CSI:
|
|||
}
|
||||
}
|
||||
|
||||
terminal.buffer.MovePosition(0, int16(distance))
|
||||
terminal.ActiveBuffer().MovePosition(0, int16(distance))
|
||||
case 'C':
|
||||
|
||||
distance := 1
|
||||
|
@ -140,7 +158,7 @@ CSI:
|
|||
}
|
||||
}
|
||||
|
||||
terminal.buffer.MovePosition(int16(distance), 0)
|
||||
terminal.ActiveBuffer().MovePosition(int16(distance), 0)
|
||||
|
||||
case 'D':
|
||||
|
||||
|
@ -153,7 +171,7 @@ CSI:
|
|||
}
|
||||
}
|
||||
|
||||
terminal.buffer.MovePosition(-int16(distance), 0)
|
||||
terminal.ActiveBuffer().MovePosition(-int16(distance), 0)
|
||||
|
||||
case 'E':
|
||||
distance := 1
|
||||
|
@ -165,8 +183,8 @@ CSI:
|
|||
}
|
||||
}
|
||||
|
||||
terminal.buffer.MovePosition(0, int16(distance))
|
||||
terminal.buffer.SetPosition(0, terminal.buffer.CursorLine())
|
||||
terminal.ActiveBuffer().MovePosition(0, int16(distance))
|
||||
terminal.ActiveBuffer().SetPosition(0, terminal.ActiveBuffer().CursorLine())
|
||||
|
||||
case 'F':
|
||||
|
||||
|
@ -178,8 +196,8 @@ CSI:
|
|||
distance = 1
|
||||
}
|
||||
}
|
||||
terminal.buffer.MovePosition(0, -int16(distance))
|
||||
terminal.buffer.SetPosition(0, terminal.buffer.CursorLine())
|
||||
terminal.ActiveBuffer().MovePosition(0, -int16(distance))
|
||||
terminal.ActiveBuffer().SetPosition(0, terminal.ActiveBuffer().CursorLine())
|
||||
|
||||
case 'G':
|
||||
|
||||
|
@ -192,7 +210,7 @@ CSI:
|
|||
}
|
||||
}
|
||||
|
||||
terminal.buffer.SetPosition(uint16(distance-1), terminal.buffer.CursorLine())
|
||||
terminal.ActiveBuffer().SetPosition(uint16(distance-1), terminal.ActiveBuffer().CursorLine())
|
||||
|
||||
case 'H', 'f':
|
||||
|
||||
|
@ -213,7 +231,7 @@ CSI:
|
|||
}
|
||||
}
|
||||
|
||||
terminal.buffer.SetPosition(uint16(x-1), uint16(y-1))
|
||||
terminal.ActiveBuffer().SetPosition(uint16(x-1), uint16(y-1))
|
||||
|
||||
default:
|
||||
err = fmt.Errorf("Unknown CSI control sequence: 0x%02X (ESC[%s%s%s)", final, param, intermediate, string(final))
|
||||
|
@ -232,7 +250,9 @@ func csiDeleteHandler(params []string, intermediate string, terminal *Terminal)
|
|||
n = 1
|
||||
}
|
||||
}
|
||||
_ = n
|
||||
|
||||
terminal.ActiveBuffer().EraseCharacters(n)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -246,11 +266,11 @@ func csiEraseInDisplayHandler(params []string, intermediate string, terminal *Te
|
|||
switch n {
|
||||
|
||||
case "0", "":
|
||||
terminal.buffer.EraseDisplayFromCursor()
|
||||
terminal.ActiveBuffer().EraseDisplayFromCursor()
|
||||
case "1":
|
||||
terminal.buffer.EraseDisplayToCursor()
|
||||
terminal.ActiveBuffer().EraseDisplayToCursor()
|
||||
case "2":
|
||||
terminal.buffer.EraseDisplay()
|
||||
terminal.ActiveBuffer().EraseDisplay()
|
||||
default:
|
||||
return fmt.Errorf("Unsupported ED: CSI %s J", n)
|
||||
}
|
||||
|
@ -268,11 +288,11 @@ func csiEraseInLineHandler(params []string, intermediate string, terminal *Termi
|
|||
|
||||
switch n {
|
||||
case "0", "": //erase adter cursor
|
||||
terminal.buffer.EraseLineFromCursor()
|
||||
terminal.ActiveBuffer().EraseLineFromCursor()
|
||||
case "1": // erase to cursor inclusive
|
||||
terminal.buffer.EraseLineToCursor()
|
||||
terminal.ActiveBuffer().EraseLineToCursor()
|
||||
case "2": // erase entire
|
||||
terminal.buffer.EraseLine()
|
||||
terminal.ActiveBuffer().EraseLine()
|
||||
default:
|
||||
return fmt.Errorf("Unsupported EL: CSI %s K", n)
|
||||
}
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
package terminal
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
terminal := &Terminal{
|
||||
lines: []Line{
|
||||
{
|
||||
Cells: []Cell{
|
||||
{
|
||||
r: 'a',
|
||||
},
|
||||
{
|
||||
r: 'b',
|
||||
},
|
||||
{
|
||||
r: 'c',
|
||||
},
|
||||
{
|
||||
r: 'd',
|
||||
},
|
||||
{
|
||||
r: 'e',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Cells: []Cell{
|
||||
{
|
||||
r: 'f',
|
||||
},
|
||||
{
|
||||
r: 'g',
|
||||
},
|
||||
{
|
||||
r: 'h',
|
||||
},
|
||||
{
|
||||
r: 'i',
|
||||
},
|
||||
{
|
||||
r: 'j',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Cells: []Cell{
|
||||
{
|
||||
r: 'k',
|
||||
},
|
||||
{
|
||||
r: 'l',
|
||||
},
|
||||
{
|
||||
r: 'm',
|
||||
},
|
||||
{
|
||||
r: 'n',
|
||||
},
|
||||
{
|
||||
r: 'o',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
terminal.position = Position{
|
||||
Col: 3,
|
||||
Line: 1,
|
||||
}
|
||||
|
||||
if err := terminal.delete(2); err != nil {
|
||||
t.Errorf("Delete failed: %s", err)
|
||||
}
|
||||
|
||||
if len(terminal.lines) != 3 {
|
||||
t.Errorf("No. of lines has changed by deleting characters")
|
||||
}
|
||||
|
||||
if "fgh" != terminal.lines[1].String() {
|
||||
t.Errorf("Unexpected string after deletion: %s", terminal.lines[1].String())
|
||||
}
|
||||
if "abcde" != terminal.lines[0].String() {
|
||||
t.Errorf("Unexpected string after deletion: %s", terminal.lines[0].String())
|
||||
}
|
||||
|
||||
if "klmno" != terminal.lines[2].String() {
|
||||
t.Errorf("Unexpected string after deletion: %s", terminal.lines[2].String())
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
type TerminalCharSet int
|
||||
|
||||
type escapeSequenceHandler func(buffer chan rune, terminal *Terminal) error
|
||||
type escapeSequenceHandler func(pty chan rune, terminal *Terminal) error
|
||||
|
||||
var escapeSequenceMap = map[rune]escapeSequenceHandler{
|
||||
0x1b: ansiHandler,
|
||||
|
@ -28,7 +28,7 @@ func (terminal *Terminal) Resume() {
|
|||
}
|
||||
}
|
||||
|
||||
func (terminal *Terminal) processInput(ctx context.Context, buffer chan rune) {
|
||||
func (terminal *Terminal) processInput(ctx context.Context, pty chan rune) {
|
||||
|
||||
// https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
|
||||
|
@ -47,12 +47,12 @@ func (terminal *Terminal) processInput(ctx context.Context, buffer chan rune) {
|
|||
//if terminal.config.slomo
|
||||
//time.Sleep(time.Millisecond * 100)
|
||||
|
||||
b := <-buffer
|
||||
b := <-pty
|
||||
|
||||
handler, ok := escapeSequenceMap[b]
|
||||
|
||||
if ok {
|
||||
if err := handler(buffer, terminal); err != nil {
|
||||
if err := handler(pty, terminal); err != nil {
|
||||
terminal.logger.Errorf("Error handling escape sequence 0x%X: %s", b, err)
|
||||
}
|
||||
continue
|
||||
|
@ -62,19 +62,19 @@ func (terminal *Terminal) processInput(ctx context.Context, buffer chan rune) {
|
|||
|
||||
switch b {
|
||||
case 0x0a:
|
||||
terminal.buffer.NewLine()
|
||||
terminal.ActiveBuffer().NewLine()
|
||||
case 0x0d:
|
||||
terminal.buffer.CarriageReturn()
|
||||
terminal.ActiveBuffer().CarriageReturn()
|
||||
case 0x08:
|
||||
// backspace
|
||||
terminal.buffer.Backspace()
|
||||
terminal.ActiveBuffer().Backspace()
|
||||
case 0x07:
|
||||
// @todo ring bell - flash red or some shit?
|
||||
default:
|
||||
// render character at current location
|
||||
// fmt.Printf("%s\n", string([]byte{b}))
|
||||
if b >= 0x20 {
|
||||
terminal.buffer.Write(b)
|
||||
terminal.ActiveBuffer().Write(b)
|
||||
} else {
|
||||
terminal.logger.Error("Non-readable rune received: 0x%X", b)
|
||||
}
|
||||
|
|
|
@ -12,103 +12,103 @@ func sgrSequenceHandler(params []string, intermediate string, terminal *Terminal
|
|||
param := params[i]
|
||||
switch param {
|
||||
case "00", "0", "":
|
||||
attr := terminal.buffer.CursorAttr()
|
||||
attr := terminal.ActiveBuffer().CursorAttr()
|
||||
*attr = buffer.CellAttributes{
|
||||
FgColour: terminal.config.ColourScheme.Foreground,
|
||||
BgColour: terminal.config.ColourScheme.Background,
|
||||
}
|
||||
case "1", "01":
|
||||
terminal.buffer.CursorAttr().Bold = true
|
||||
terminal.ActiveBuffer().CursorAttr().Bold = true
|
||||
case "2", "02":
|
||||
terminal.buffer.CursorAttr().Dim = true
|
||||
terminal.ActiveBuffer().CursorAttr().Dim = true
|
||||
case "4", "04":
|
||||
terminal.buffer.CursorAttr().Underline = true
|
||||
terminal.ActiveBuffer().CursorAttr().Underline = true
|
||||
case "5", "05":
|
||||
terminal.buffer.CursorAttr().Blink = true
|
||||
terminal.ActiveBuffer().CursorAttr().Blink = true
|
||||
case "7", "07":
|
||||
terminal.buffer.CursorAttr().Reverse = true
|
||||
terminal.ActiveBuffer().CursorAttr().Reverse = true
|
||||
case "8", "08":
|
||||
terminal.buffer.CursorAttr().Hidden = true
|
||||
terminal.ActiveBuffer().CursorAttr().Hidden = true
|
||||
case "21":
|
||||
terminal.buffer.CursorAttr().Bold = false
|
||||
terminal.ActiveBuffer().CursorAttr().Bold = false
|
||||
case "22":
|
||||
terminal.buffer.CursorAttr().Dim = false
|
||||
terminal.ActiveBuffer().CursorAttr().Dim = false
|
||||
case "24":
|
||||
terminal.buffer.CursorAttr().Underline = false
|
||||
terminal.ActiveBuffer().CursorAttr().Underline = false
|
||||
case "25":
|
||||
terminal.buffer.CursorAttr().Blink = false
|
||||
terminal.ActiveBuffer().CursorAttr().Blink = false
|
||||
case "27":
|
||||
terminal.buffer.CursorAttr().Reverse = false
|
||||
terminal.ActiveBuffer().CursorAttr().Reverse = false
|
||||
case "28":
|
||||
terminal.buffer.CursorAttr().Hidden = false
|
||||
terminal.ActiveBuffer().CursorAttr().Hidden = false
|
||||
case "39":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.Foreground
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Foreground
|
||||
case "30":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.Black
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Black
|
||||
case "31":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.Red
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Red
|
||||
case "32":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.Green
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Green
|
||||
case "33":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.Yellow
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Yellow
|
||||
case "34":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.Blue
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Blue
|
||||
case "35":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.Magenta
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Magenta
|
||||
case "36":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.Cyan
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.Cyan
|
||||
case "37":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.White
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.White
|
||||
case "90":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.DarkGrey
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.DarkGrey
|
||||
case "91":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.LightRed
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightRed
|
||||
case "92":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.LightGreen
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightGreen
|
||||
case "93":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.LightYellow
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightYellow
|
||||
case "94":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.LightBlue
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightBlue
|
||||
case "95":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.LightMagenta
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightMagenta
|
||||
case "96":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.LightCyan
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.LightCyan
|
||||
case "97":
|
||||
terminal.buffer.CursorAttr().FgColour = terminal.config.ColourScheme.White
|
||||
terminal.ActiveBuffer().CursorAttr().FgColour = terminal.config.ColourScheme.White
|
||||
case "49":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.Background
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Background
|
||||
case "40":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.Black
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Black
|
||||
case "41":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.Red
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Red
|
||||
case "42":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.Green
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Green
|
||||
case "43":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.Yellow
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Yellow
|
||||
case "44":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.Blue
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Blue
|
||||
case "45":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.Magenta
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Magenta
|
||||
case "46":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.Cyan
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.Cyan
|
||||
case "47":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.White
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.White
|
||||
case "100":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.DarkGrey
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.DarkGrey
|
||||
case "101":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.LightRed
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightRed
|
||||
case "102":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.LightGreen
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightGreen
|
||||
case "103":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.LightYellow
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightYellow
|
||||
case "104":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.LightBlue
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightBlue
|
||||
case "105":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.LightMagenta
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightMagenta
|
||||
case "106":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.LightCyan
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.LightCyan
|
||||
case "107":
|
||||
terminal.buffer.CursorAttr().BgColour = terminal.config.ColourScheme.White
|
||||
terminal.ActiveBuffer().CursorAttr().BgColour = terminal.config.ColourScheme.White
|
||||
default:
|
||||
return fmt.Errorf("Unknown SGR control sequence: (ESC[%s%sm)", param, intermediate)
|
||||
}
|
||||
|
|
|
@ -15,18 +15,24 @@ import (
|
|||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const (
|
||||
MainBuffer uint8 = 0
|
||||
AltBuffer uint8 = 1
|
||||
)
|
||||
|
||||
type Terminal struct {
|
||||
buffer *buffer.Buffer
|
||||
lock sync.Mutex
|
||||
pty *os.File
|
||||
logger *zap.SugaredLogger
|
||||
title string
|
||||
size Winsize
|
||||
config config.Config
|
||||
titleHandlers []chan bool
|
||||
pauseChan chan bool
|
||||
resumeChan chan bool
|
||||
modes Modes
|
||||
buffers []*buffer.Buffer
|
||||
activeBufferIndex uint8
|
||||
lock sync.Mutex
|
||||
pty *os.File
|
||||
logger *zap.SugaredLogger
|
||||
title string
|
||||
size Winsize
|
||||
config config.Config
|
||||
titleHandlers []chan bool
|
||||
pauseChan chan bool
|
||||
resumeChan chan bool
|
||||
modes Modes
|
||||
}
|
||||
|
||||
type Modes struct {
|
||||
|
@ -50,10 +56,16 @@ type Position struct {
|
|||
func New(pty *os.File, logger *zap.SugaredLogger, config config.Config) *Terminal {
|
||||
|
||||
return &Terminal{
|
||||
buffer: buffer.NewBuffer(0, 0, buffer.CellAttributes{
|
||||
FgColour: config.ColourScheme.Foreground,
|
||||
BgColour: config.ColourScheme.Background,
|
||||
}),
|
||||
buffers: []*buffer.Buffer{
|
||||
buffer.NewBuffer(1, 1, buffer.CellAttributes{
|
||||
FgColour: config.ColourScheme.Foreground,
|
||||
BgColour: config.ColourScheme.Background,
|
||||
}),
|
||||
buffer.NewBuffer(1, 1, buffer.CellAttributes{
|
||||
FgColour: config.ColourScheme.Foreground,
|
||||
BgColour: config.ColourScheme.Background,
|
||||
}),
|
||||
},
|
||||
pty: pty,
|
||||
logger: logger,
|
||||
config: config,
|
||||
|
@ -66,38 +78,54 @@ func New(pty *os.File, logger *zap.SugaredLogger, config config.Config) *Termina
|
|||
}
|
||||
}
|
||||
|
||||
func (terminal *Terminal) UseMainBuffer() {
|
||||
terminal.activeBufferIndex = MainBuffer
|
||||
terminal.SetSize(uint(terminal.size.Width), uint(terminal.size.Height))
|
||||
}
|
||||
|
||||
func (terminal *Terminal) UseAltBuffer() {
|
||||
terminal.activeBufferIndex = AltBuffer
|
||||
terminal.SetSize(uint(terminal.size.Width), uint(terminal.size.Height))
|
||||
}
|
||||
|
||||
func (terminal *Terminal) ActiveBuffer() *buffer.Buffer {
|
||||
return terminal.buffers[terminal.activeBufferIndex]
|
||||
}
|
||||
|
||||
func (terminal *Terminal) GetScrollOffset() uint {
|
||||
return terminal.buffer.GetScrollOffset()
|
||||
return terminal.ActiveBuffer().GetScrollOffset()
|
||||
}
|
||||
|
||||
func (terminal *Terminal) ScrollDown(lines uint16) {
|
||||
terminal.buffer.ScrollDown(lines)
|
||||
terminal.ActiveBuffer().ScrollDown(lines)
|
||||
}
|
||||
|
||||
func (terminal *Terminal) ScrollUp(lines uint16) {
|
||||
terminal.buffer.ScrollUp(lines)
|
||||
terminal.ActiveBuffer().ScrollUp(lines)
|
||||
}
|
||||
|
||||
func (terminal *Terminal) ScrollPageDown() {
|
||||
terminal.buffer.ScrollPageDown()
|
||||
terminal.ActiveBuffer().ScrollPageDown()
|
||||
}
|
||||
func (terminal *Terminal) ScrollPageUp() {
|
||||
terminal.buffer.ScrollPageUp()
|
||||
terminal.ActiveBuffer().ScrollPageUp()
|
||||
}
|
||||
func (terminal *Terminal) ScrollToEnd() {
|
||||
terminal.buffer.ScrollToEnd()
|
||||
terminal.ActiveBuffer().ScrollToEnd()
|
||||
}
|
||||
|
||||
func (terminal *Terminal) GetVisibleLines() []buffer.Line {
|
||||
return terminal.buffer.GetVisibleLines()
|
||||
return terminal.ActiveBuffer().GetVisibleLines()
|
||||
}
|
||||
|
||||
func (terminal *Terminal) GetCell(col int, row int) *buffer.Cell {
|
||||
return terminal.buffer.GetCell(col, row)
|
||||
func (terminal *Terminal) GetCell(col uint16, row uint16) *buffer.Cell {
|
||||
return terminal.ActiveBuffer().GetCell(col, row)
|
||||
}
|
||||
|
||||
func (terminal *Terminal) AttachDisplayChangeHandler(handler chan bool) {
|
||||
terminal.buffer.AttachDisplayChangeHandler(handler)
|
||||
for i := range terminal.buffers {
|
||||
terminal.buffers[i].AttachDisplayChangeHandler(handler)
|
||||
}
|
||||
}
|
||||
|
||||
func (terminal *Terminal) AttachTitleChangeHandler(handler chan bool) {
|
||||
|
@ -117,19 +145,19 @@ func (terminal *Terminal) emitTitleChange() {
|
|||
}
|
||||
|
||||
func (terminal *Terminal) GetLogicalCursorX() uint16 {
|
||||
if terminal.buffer.CursorColumn() >= terminal.buffer.Width() {
|
||||
if terminal.ActiveBuffer().CursorColumn() >= terminal.ActiveBuffer().Width() {
|
||||
return 0
|
||||
}
|
||||
|
||||
return terminal.buffer.CursorColumn()
|
||||
return terminal.ActiveBuffer().CursorColumn()
|
||||
}
|
||||
|
||||
func (terminal *Terminal) GetLogicalCursorY() uint16 {
|
||||
if terminal.buffer.CursorColumn() >= terminal.buffer.Width() {
|
||||
return terminal.buffer.CursorLine() + 1
|
||||
if terminal.ActiveBuffer().CursorColumn() >= terminal.ActiveBuffer().Width() {
|
||||
return terminal.ActiveBuffer().CursorLine() + 1
|
||||
}
|
||||
|
||||
return terminal.buffer.CursorLine()
|
||||
return terminal.ActiveBuffer().CursorLine()
|
||||
}
|
||||
|
||||
func (terminal *Terminal) GetTitle() string {
|
||||
|
@ -174,21 +202,21 @@ func (terminal *Terminal) Read() error {
|
|||
}
|
||||
|
||||
func (terminal *Terminal) Clear() {
|
||||
terminal.buffer.Clear()
|
||||
terminal.ActiveBuffer().Clear()
|
||||
}
|
||||
|
||||
func (terminal *Terminal) GetSize() (int, int) {
|
||||
return int(terminal.size.Width), int(terminal.size.Height)
|
||||
}
|
||||
|
||||
func (terminal *Terminal) SetSize(newCols int, newLines int) error {
|
||||
func (terminal *Terminal) SetSize(newCols uint, newLines uint) error {
|
||||
terminal.lock.Lock()
|
||||
defer terminal.lock.Unlock()
|
||||
|
||||
terminal.size.Width = uint16(newCols)
|
||||
terminal.size.Height = uint16(newLines)
|
||||
|
||||
terminal.buffer.ResizeView(terminal.size.Width, terminal.size.Height)
|
||||
terminal.ActiveBuffer().ResizeView(terminal.size.Width, terminal.size.Height)
|
||||
|
||||
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(terminal.pty.Fd()),
|
||||
uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(&terminal.size)))
|
||||
|
|
Loading…
Reference in New Issue