This commit is contained in:
Liam Galvin 2018-08-07 21:00:34 +01:00
parent d5f5cf8592
commit 444f716c64
4 changed files with 293 additions and 10 deletions

View File

@ -112,7 +112,6 @@ func (buffer *Buffer) ensureLinesExistToRawHeight() {
// Write will write a rune to the terminal at the position of the cursor, and increment the cursor position // Write will write a rune to the terminal at the position of the cursor, and increment the cursor position
func (buffer *Buffer) Write(runes ...rune) { func (buffer *Buffer) Write(runes ...rune) {
for _, r := range runes { for _, r := range runes {
buffer.ensureLinesExistToRawHeight()
if r == 0x0a { if r == 0x0a {
buffer.NewLine() buffer.NewLine()
continue continue
@ -120,6 +119,7 @@ func (buffer *Buffer) Write(runes ...rune) {
buffer.CarriageReturn() buffer.CarriageReturn()
continue continue
} }
buffer.ensureLinesExistToRawHeight()
line := &buffer.lines[buffer.RawLine()] line := &buffer.lines[buffer.RawLine()]
for int(buffer.CursorColumn()) >= len(line.cells) { for int(buffer.CursorColumn()) >= len(line.cells) {
line.cells = append(line.cells, newCell()) line.cells = append(line.cells, newCell())
@ -172,9 +172,11 @@ func (buffer *Buffer) CarriageReturn() {
line, err := buffer.getCurrentLine() line, err := buffer.getCurrentLine()
if err != nil { if err != nil {
// @todo check this... buffer.ensureLinesExistToRawHeight()
buffer.cursorX = 0 line, err = buffer.getCurrentLine()
return if err != nil {
panic(err)
}
} }
if buffer.cursorX == 0 && line.wrapped { if buffer.cursorX == 0 && line.wrapped {
buffer.cursorY-- buffer.cursorY--
@ -193,7 +195,14 @@ func (buffer *Buffer) NewLine() {
// if we're at the beginning of a line which wrapped from the previous one, and we need a new line, we can effectively not add a new line, and set the current one to non-wrapped // if we're at the beginning of a line which wrapped from the previous one, and we need a new line, we can effectively not add a new line, and set the current one to non-wrapped
if buffer.cursorX == 0 { if buffer.cursorX == 0 {
line := &buffer.lines[buffer.RawLine()] line, err := buffer.getCurrentLine()
if err != nil {
buffer.ensureLinesExistToRawHeight()
line, err = buffer.getCurrentLine()
if err != nil {
panic(err)
}
}
if line.wrapped { if line.wrapped {
line.setWrapped(false) line.setWrapped(false)
return return
@ -321,6 +330,16 @@ func (buffer *Buffer) EraseLineAfterCursor() {
line.cells = line.cells[:max] line.cells = line.cells[:max]
} }
func (buffer *Buffer) EraseDisplay() {
defer buffer.emitDisplayChange()
for i := uint16(0); i < (buffer.ViewHeight()); i++ {
rawLine := buffer.convertViewLineToRawLine(i)
if int(rawLine) < len(buffer.lines) {
buffer.lines[int(rawLine)].cells = []Cell{}
}
}
}
func (buffer *Buffer) EraseDisplayAfterCursor() { func (buffer *Buffer) EraseDisplayAfterCursor() {
defer buffer.emitDisplayChange() defer buffer.emitDisplayChange()
line, err := buffer.getCurrentLine() line, err := buffer.getCurrentLine()
@ -342,7 +361,9 @@ func (buffer *Buffer) EraseDisplayToCursor() {
if err != nil { if err != nil {
return return
} }
line.cells = line.cells[buffer.cursorX+1:] for i := 0; i < int(buffer.cursorY); i++ {
line.cells[i].erase()
}
for i := uint16(0); i < buffer.cursorY; i++ { for i := uint16(0); i < buffer.cursorY; i++ {
rawLine := buffer.convertViewLineToRawLine(i) rawLine := buffer.convertViewLineToRawLine(i)
if int(rawLine) < len(buffer.lines) { if int(rawLine) < len(buffer.lines) {

View File

@ -2,6 +2,7 @@ package buffer
import ( import (
"testing" "testing"
"time"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -258,7 +259,145 @@ func TestCarriageReturnOnOverWrappedLine(t *testing.T) {
assert.Equal(t, "", lines[3].String()) assert.Equal(t, "", lines[3].String())
} }
func TestCarriageReturnOnLineThatDoesntExist(t *testing.T) {
b := NewBuffer(6, 10, CellAttributes{})
b.cursorY = 3
b.Write('\r')
assert.Equal(t, uint16(0), b.cursorX)
assert.Equal(t, uint16(3), b.cursorY)
}
func TestResizeView(t *testing.T) { func TestResizeView(t *testing.T) {
b := NewBuffer(80, 20, CellAttributes{}) b := NewBuffer(80, 20, CellAttributes{})
b.ResizeView(40, 10) b.ResizeView(40, 10)
} }
func TestGetCell(t *testing.T) {
b := NewBuffer(80, 20, CellAttributes{})
b.Write([]rune("Hello\nthere\nsomething...")...)
cell := b.GetCell(8, 2)
require.NotNil(t, cell)
assert.Equal(t, 'g', cell.Rune())
}
func TestGetCellWithHistory(t *testing.T) {
b := NewBuffer(80, 2, CellAttributes{})
b.Write([]rune("Hello\nthere\nsomething...")...)
cell := b.GetCell(8, 1)
require.NotNil(t, cell)
assert.Equal(t, 'g', cell.Rune())
}
func TestGetCellWithBadCursor(t *testing.T) {
b := NewBuffer(80, 2, CellAttributes{})
b.Write([]rune("Hello\nthere\nsomething...")...)
require.Nil(t, b.GetCell(8, 3))
require.Nil(t, b.GetCell(8, -1))
require.Nil(t, b.GetCell(-8, 1))
require.Nil(t, b.GetCell(90, 0))
}
func TestCursorAttr(t *testing.T) {
b := NewBuffer(80, 2, CellAttributes{})
assert.Equal(t, &b.cursorAttr, b.CursorAttr())
}
func TestAttachingHandlers(t *testing.T) {
b := NewBuffer(80, 2, CellAttributes{})
displayHandler := make(chan bool, 1)
b.AttachDisplayChangeHandler(displayHandler)
require.Equal(t, 1, len(b.displayChangeHandlers))
assert.Equal(t, b.displayChangeHandlers[0], displayHandler)
}
func TestEmitDisplayHandlers(t *testing.T) {
b := NewBuffer(80, 2, CellAttributes{})
displayHandler := make(chan bool, 1)
b.AttachDisplayChangeHandler(displayHandler)
b.emitDisplayChange()
time.Sleep(time.Millisecond * 50)
ok := false
select {
case <-displayHandler:
ok = true
default:
}
assert.True(t, ok)
}
func TestCursorPositionQuerying(t *testing.T) {
b := NewBuffer(80, 20, CellAttributes{})
b.cursorX = 17
b.cursorY = 9
assert.Equal(t, b.cursorX, b.CursorColumn())
assert.Equal(t, b.cursorY, b.CursorLine())
}
func TestRawPositionQuerying(t *testing.T) {
b := NewBuffer(80, 5, CellAttributes{})
b.Write([]rune("a\na\na\na\na\na\na\na\na\na")...)
b.cursorX = 3
b.cursorY = 4
assert.Equal(t, uint64(9), b.RawLine())
}
// CSI 2 K
func TestEraseLine(t *testing.T) {
b := NewBuffer(80, 5, CellAttributes{})
b.Write([]rune("hello, this is a test\nthis line should be deleted")...)
b.EraseLine()
assert.Equal(t, "hello, this is a test", b.lines[0].String())
assert.Equal(t, "", b.lines[1].String())
}
// CSI 1 K
func TestEraseLineToCursor(t *testing.T) {
b := NewBuffer(80, 5, CellAttributes{})
b.Write([]rune("hello, this is a test\ndeleted")...)
b.MovePosition(-3, 0)
b.EraseLineToCursor()
assert.Equal(t, "hello, this is a test", b.lines[0].String())
assert.Equal(t, "\x00\x00\x00\x00\x00ed", b.lines[1].String())
}
// CSI 0 K
func TestEraseLineAfterCursor(t *testing.T) {
b := NewBuffer(80, 5, CellAttributes{})
b.Write([]rune("hello, this is a test\ndeleted")...)
b.MovePosition(-3, 0)
b.EraseLineAfterCursor()
assert.Equal(t, "hello, this is a test", b.lines[0].String())
assert.Equal(t, "delet", b.lines[1].String())
}
func TestEraseDisplay(t *testing.T) {
b := NewBuffer(80, 5, CellAttributes{})
b.Write([]rune("hello\nasdasd\nthing")...)
b.MovePosition(2, 1)
b.EraseDisplay()
lines := b.GetVisibleLines()
for _, line := range lines {
assert.Equal(t, "", line.String())
}
}
func TestEraseDisplayToCursor(t *testing.T) {
b := NewBuffer(80, 5, CellAttributes{})
b.Write([]rune("hello\nasdasd\nthing")...)
b.MovePosition(-3, 0)
b.EraseDisplayToCursor()
lines := b.GetVisibleLines()
assert.Equal(t, "", lines[0].String())
assert.Equal(t, "", lines[1].String())
assert.Equal(t, "\x00\x00ing", lines[2].String())
}
func TestEraseDisplayAfterCursor(t *testing.T) {
b := NewBuffer(80, 5, CellAttributes{})
b.Write([]rune("hello\nasdasd\nthings")...)
b.MovePosition(-3, -1)
b.EraseDisplayAfterCursor()
lines := b.GetVisibleLines()
assert.Equal(t, "hello", lines[0].String())
assert.Equal(t, "asd", lines[1].String())
assert.Equal(t, "", lines[2].String())
}

126
cover.out
View File

@ -1 +1,127 @@
mode: set mode: set
gitlab.com/liamg/raft/buffer/buffer.go:18.80,27.2 3 1
gitlab.com/liamg/raft/buffer/buffer.go:29.52,31.2 1 1
gitlab.com/liamg/raft/buffer/buffer.go:33.63,37.69 2 1
gitlab.com/liamg/raft/buffer/buffer.go:40.2,41.32 2 1
gitlab.com/liamg/raft/buffer/buffer.go:44.2,44.29 1 1
gitlab.com/liamg/raft/buffer/buffer.go:37.69,39.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:41.32,43.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:47.69,48.41 1 1
gitlab.com/liamg/raft/buffer/buffer.go:52.2,52.78 1 1
gitlab.com/liamg/raft/buffer/buffer.go:48.41,50.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:55.43,56.55 1 1
gitlab.com/liamg/raft/buffer/buffer.go:56.55,57.24 1 1
gitlab.com/liamg/raft/buffer/buffer.go:57.24,58.11 1 1
gitlab.com/liamg/raft/buffer/buffer.go:59.19,59.19 0 1
gitlab.com/liamg/raft/buffer/buffer.go:60.12,60.12 0 0
gitlab.com/liamg/raft/buffer/buffer.go:67.45,69.2 1 1
gitlab.com/liamg/raft/buffer/buffer.go:72.43,74.2 1 1
gitlab.com/liamg/raft/buffer/buffer.go:77.40,79.2 1 1
gitlab.com/liamg/raft/buffer/buffer.go:81.72,83.40 2 1
gitlab.com/liamg/raft/buffer/buffer.go:86.2,86.69 1 1
gitlab.com/liamg/raft/buffer/buffer.go:83.40,85.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:90.38,92.2 1 1
gitlab.com/liamg/raft/buffer/buffer.go:94.42,96.2 1 1
gitlab.com/liamg/raft/buffer/buffer.go:98.36,100.2 1 1
gitlab.com/liamg/raft/buffer/buffer.go:102.43,104.2 1 1
gitlab.com/liamg/raft/buffer/buffer.go:106.53,107.49 1 1
gitlab.com/liamg/raft/buffer/buffer.go:107.49,109.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:113.44,114.26 1 1
gitlab.com/liamg/raft/buffer/buffer.go:114.26,115.16 1 1
gitlab.com/liamg/raft/buffer/buffer.go:122.3,124.53 3 1
gitlab.com/liamg/raft/buffer/buffer.go:127.3,130.35 4 1
gitlab.com/liamg/raft/buffer/buffer.go:115.16,117.12 2 1
gitlab.com/liamg/raft/buffer/buffer.go:118.9,118.23 1 1
gitlab.com/liamg/raft/buffer/buffer.go:118.23,120.12 2 1
gitlab.com/liamg/raft/buffer/buffer.go:124.53,126.4 1 1
gitlab.com/liamg/raft/buffer/buffer.go:134.49,138.46 2 1
gitlab.com/liamg/raft/buffer/buffer.go:138.46,142.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:142.8,144.44 1 1
gitlab.com/liamg/raft/buffer/buffer.go:144.44,152.4 4 1
gitlab.com/liamg/raft/buffer/buffer.go:152.9,159.18 4 1
gitlab.com/liamg/raft/buffer/buffer.go:159.18,163.5 3 1
gitlab.com/liamg/raft/buffer/buffer.go:169.40,174.16 3 1
gitlab.com/liamg/raft/buffer/buffer.go:181.2,181.41 1 1
gitlab.com/liamg/raft/buffer/buffer.go:174.16,177.17 3 1
gitlab.com/liamg/raft/buffer/buffer.go:177.17,178.14 1 0
gitlab.com/liamg/raft/buffer/buffer.go:181.41,183.27 2 1
gitlab.com/liamg/raft/buffer/buffer.go:183.27,186.4 2 1
gitlab.com/liamg/raft/buffer/buffer.go:187.8,189.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:192.33,197.25 2 1
gitlab.com/liamg/raft/buffer/buffer.go:212.2,212.43 1 1
gitlab.com/liamg/raft/buffer/buffer.go:197.25,199.17 2 1
gitlab.com/liamg/raft/buffer/buffer.go:206.3,206.19 1 1
gitlab.com/liamg/raft/buffer/buffer.go:199.17,202.18 3 1
gitlab.com/liamg/raft/buffer/buffer.go:202.18,203.15 1 0
gitlab.com/liamg/raft/buffer/buffer.go:206.19,209.4 2 1
gitlab.com/liamg/raft/buffer/buffer.go:212.43,215.3 2 1
gitlab.com/liamg/raft/buffer/buffer.go:215.8,218.3 2 1
gitlab.com/liamg/raft/buffer/buffer.go:221.54,226.33 3 1
gitlab.com/liamg/raft/buffer/buffer.go:232.2,232.33 1 1
gitlab.com/liamg/raft/buffer/buffer.go:238.2,238.30 1 1
gitlab.com/liamg/raft/buffer/buffer.go:226.33,228.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:228.8,230.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:232.33,234.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:234.8,236.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:241.37,243.2 0 0
gitlab.com/liamg/raft/buffer/buffer.go:245.37,247.2 0 0
gitlab.com/liamg/raft/buffer/buffer.go:249.53,251.2 0 0
gitlab.com/liamg/raft/buffer/buffer.go:253.60,255.31 2 1
gitlab.com/liamg/raft/buffer/buffer.go:259.2,259.33 1 1
gitlab.com/liamg/raft/buffer/buffer.go:263.2,264.23 2 1
gitlab.com/liamg/raft/buffer/buffer.go:255.31,258.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:259.33,262.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:267.48,269.80 2 1
gitlab.com/liamg/raft/buffer/buffer.go:274.2,274.14 1 1
gitlab.com/liamg/raft/buffer/buffer.go:269.80,270.38 1 1
gitlab.com/liamg/raft/buffer/buffer.go:270.38,272.4 1 1
gitlab.com/liamg/raft/buffer/buffer.go:279.31,281.48 2 1
gitlab.com/liamg/raft/buffer/buffer.go:284.2,284.26 1 1
gitlab.com/liamg/raft/buffer/buffer.go:281.48,283.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:287.55,289.47 1 1
gitlab.com/liamg/raft/buffer/buffer.go:293.2,293.66 1 1
gitlab.com/liamg/raft/buffer/buffer.go:289.47,291.3 1 1
gitlab.com/liamg/raft/buffer/buffer.go:296.35,299.16 3 1
gitlab.com/liamg/raft/buffer/buffer.go:302.2,302.23 1 1
gitlab.com/liamg/raft/buffer/buffer.go:299.16,301.3 1 0
gitlab.com/liamg/raft/buffer/buffer.go:305.43,308.16 3 1
gitlab.com/liamg/raft/buffer/buffer.go:311.2,311.44 1 1
gitlab.com/liamg/raft/buffer/buffer.go:308.16,310.3 1 0
gitlab.com/liamg/raft/buffer/buffer.go:311.44,312.26 1 1
gitlab.com/liamg/raft/buffer/buffer.go:312.26,314.4 1 1
gitlab.com/liamg/raft/buffer/buffer.go:318.46,321.16 3 1
gitlab.com/liamg/raft/buffer/buffer.go:325.2,326.27 2 1
gitlab.com/liamg/raft/buffer/buffer.go:330.2,330.31 1 1
gitlab.com/liamg/raft/buffer/buffer.go:321.16,323.3 1 0
gitlab.com/liamg/raft/buffer/buffer.go:326.27,328.3 1 0
gitlab.com/liamg/raft/buffer/buffer.go:333.49,336.16 3 0
gitlab.com/liamg/raft/buffer/buffer.go:339.2,340.60 2 0
gitlab.com/liamg/raft/buffer/buffer.go:336.16,338.3 1 0
gitlab.com/liamg/raft/buffer/buffer.go:340.60,342.39 2 0
gitlab.com/liamg/raft/buffer/buffer.go:342.39,344.4 1 0
gitlab.com/liamg/raft/buffer/buffer.go:348.46,351.16 3 0
gitlab.com/liamg/raft/buffer/buffer.go:354.2,355.46 2 0
gitlab.com/liamg/raft/buffer/buffer.go:351.16,353.3 1 0
gitlab.com/liamg/raft/buffer/buffer.go:355.46,357.39 2 0
gitlab.com/liamg/raft/buffer/buffer.go:357.39,359.4 1 0
gitlab.com/liamg/raft/buffer/buffer.go:363.63,369.2 3 1
gitlab.com/liamg/raft/buffer/cell.go:20.21,22.2 1 1
gitlab.com/liamg/raft/buffer/cell.go:24.31,25.17 1 1
gitlab.com/liamg/raft/buffer/cell.go:28.2,28.15 1 1
gitlab.com/liamg/raft/buffer/cell.go:25.17,27.3 1 0
gitlab.com/liamg/raft/buffer/cell.go:31.35,32.17 1 0
gitlab.com/liamg/raft/buffer/cell.go:35.2,35.34 1 0
gitlab.com/liamg/raft/buffer/cell.go:32.17,34.3 1 0
gitlab.com/liamg/raft/buffer/cell.go:39.35,41.2 1 0
gitlab.com/liamg/raft/buffer/cell.go:43.27,45.2 1 1
gitlab.com/liamg/raft/buffer/cell.go:47.35,50.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
gitlab.com/liamg/raft/buffer/line.go:28.47,32.2 3 0
gitlab.com/liamg/raft/buffer/line.go:34.55,35.25 1 0
gitlab.com/liamg/raft/buffer/line.go:38.2,40.12 3 0
gitlab.com/liamg/raft/buffer/line.go:35.25,37.3 1 0
gitlab.com/liamg/raft/buffer/line.go:43.49,47.2 3 0

View File

@ -197,10 +197,7 @@ func csiEraseInDisplayHandler(params []string, intermediate string, terminal *Te
case "1": case "1":
terminal.buffer.EraseDisplayToCursor() terminal.buffer.EraseDisplayToCursor()
case "2": case "2":
terminal.Clear() terminal.buffer.EraseDisplay()
case "3":
terminal.Clear()
default: default:
return fmt.Errorf("Unsupported ED: CSI %s J", n) return fmt.Errorf("Unsupported ED: CSI %s J", n)
} }