mirror of https://github.com/liamg/aminal.git
nice tested buffer package
This commit is contained in:
parent
89b8002d48
commit
002d617630
184
buffer/buffer.go
184
buffer/buffer.go
|
@ -1,75 +1,183 @@
|
|||
package buffer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Buffer struct {
|
||||
lines []line
|
||||
x uint16
|
||||
y uint16
|
||||
columnCount uint16
|
||||
viewHeight uint16
|
||||
lines []Line
|
||||
cursorX uint16
|
||||
cursorY uint16
|
||||
viewHeight uint16
|
||||
viewWidth uint16
|
||||
cursorAttr CellAttributes
|
||||
}
|
||||
|
||||
// NewBuffer creates a new terminal buffer
|
||||
func NewBuffer() *Buffer {
|
||||
return &Buffer{
|
||||
x: 0,
|
||||
y: 0,
|
||||
lines: []line{},
|
||||
columnCount: 0,
|
||||
func NewBuffer(viewCols uint16, viewLines uint16) *Buffer {
|
||||
b := &Buffer{
|
||||
cursorX: 0,
|
||||
cursorY: 0,
|
||||
lines: []Line{},
|
||||
}
|
||||
b.ResizeView(viewCols, viewLines)
|
||||
return b
|
||||
}
|
||||
|
||||
// Column returns cursor column
|
||||
func (buffer *Buffer) Column() uint16 {
|
||||
return buffer.x
|
||||
func (buffer *Buffer) CursorColumn() uint16 {
|
||||
return buffer.cursorX
|
||||
}
|
||||
|
||||
// Line returns cursor line
|
||||
func (buffer *Buffer) Line() uint16 {
|
||||
return buffer.y
|
||||
func (buffer *Buffer) CursorLine() uint16 {
|
||||
return buffer.cursorY
|
||||
}
|
||||
|
||||
// translates the cursor line to the raw buffer line
|
||||
func (buffer *Buffer) RawLine() uint64 {
|
||||
rawHeight := buffer.Height()
|
||||
if int(buffer.viewHeight) > rawHeight {
|
||||
return uint64(buffer.cursorY)
|
||||
}
|
||||
return uint64(int(buffer.cursorY) + (rawHeight - int(buffer.viewHeight)))
|
||||
}
|
||||
|
||||
// Width returns the width of the buffer in columns
|
||||
func (buffer *Buffer) Width() uint16 {
|
||||
return buffer.columnCount
|
||||
return buffer.viewWidth
|
||||
}
|
||||
|
||||
func (buffer *Buffer) ViewWidth() uint16 {
|
||||
return buffer.viewWidth
|
||||
}
|
||||
|
||||
func (buffer *Buffer) Height() int {
|
||||
return len(buffer.lines)
|
||||
}
|
||||
|
||||
func (buffer *Buffer) ViewHeight() uint16 {
|
||||
return buffer.viewHeight
|
||||
}
|
||||
|
||||
func (buffer *Buffer) ensureLinesExistToRawHeight() {
|
||||
for int(buffer.RawLine()) >= len(buffer.lines) {
|
||||
buffer.lines = append(buffer.lines, newLine())
|
||||
}
|
||||
}
|
||||
|
||||
// Write will write a rune to the terminal at the position of the cursor, and increment the cursor position
|
||||
func (buffer *Buffer) Write(r rune) {
|
||||
for int(buffer.Line()) >= len(buffer.lines) {
|
||||
buffer.lines = append(buffer.lines, newLine())
|
||||
func (buffer *Buffer) Write(runes ...rune) {
|
||||
for _, r := range runes {
|
||||
buffer.ensureLinesExistToRawHeight()
|
||||
if r == 0x0a {
|
||||
buffer.NewLine()
|
||||
continue
|
||||
}
|
||||
line := &buffer.lines[buffer.RawLine()]
|
||||
for int(buffer.CursorColumn()) >= len(line.cells) {
|
||||
line.cells = append(line.cells, newCell())
|
||||
}
|
||||
cell := &line.cells[buffer.CursorColumn()]
|
||||
cell.setRune(r)
|
||||
cell.attr = buffer.cursorAttr
|
||||
buffer.incrementCursorPosition()
|
||||
}
|
||||
line := &buffer.lines[buffer.Line()]
|
||||
for int(buffer.Column()) >= len(line.cells) {
|
||||
line.cells = append(line.cells, newCell())
|
||||
}
|
||||
cell := line.cells[buffer.Column()]
|
||||
cell.setRune(r)
|
||||
buffer.incrementCursorPosition()
|
||||
}
|
||||
|
||||
func (buffer *Buffer) incrementCursorPosition() {
|
||||
|
||||
if buffer.Column()+1 < buffer.Width() {
|
||||
buffer.x++
|
||||
if buffer.CursorColumn()+1 < buffer.Width() {
|
||||
buffer.cursorX++
|
||||
} else {
|
||||
buffer.y++
|
||||
buffer.x = 0
|
||||
if buffer.cursorY == buffer.viewHeight-1 { // if we're on the last line, we can't move the cursor down, we have to move the buffer up, i.e. add a new line
|
||||
line := newLine()
|
||||
line.setWrapped(true)
|
||||
buffer.lines = append(buffer.lines, line)
|
||||
buffer.cursorX = 0
|
||||
} else {
|
||||
buffer.cursorX = 0
|
||||
if buffer.Height() < int(buffer.ViewHeight()) {
|
||||
line := newLine()
|
||||
line.setWrapped(true)
|
||||
buffer.lines = append(buffer.lines, line)
|
||||
buffer.cursorY++
|
||||
} else {
|
||||
panic("no test for this yet - not sure if possible?")
|
||||
line := &buffer.lines[buffer.RawLine()]
|
||||
line.setWrapped(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (buffer *Buffer) SetPosition(col uint16, line uint16) error {
|
||||
if buffer.x >= buffer.Width() {
|
||||
return fmt.Errorf("Cannot set cursor position: column %d is outside of the current buffer width (%d columns)", col, buffer.Width())
|
||||
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 buffer.cursorX == 0 {
|
||||
line := &buffer.lines[buffer.RawLine()]
|
||||
if line.wrapped {
|
||||
line.setWrapped(false)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if buffer.cursorY == buffer.viewHeight-1 {
|
||||
buffer.lines = append(buffer.lines, newLine())
|
||||
buffer.cursorX = 0
|
||||
} else {
|
||||
buffer.cursorX = 0
|
||||
buffer.cursorY++
|
||||
}
|
||||
buffer.x = col
|
||||
buffer.y = line
|
||||
return nil
|
||||
}
|
||||
|
||||
func (buffer *Buffer) Resize(cols int, lines int) {
|
||||
func (buffer *Buffer) MovePosition(x int16, y int16) {
|
||||
|
||||
if int16(buffer.cursorX)+x < 0 {
|
||||
x = -int16(buffer.cursorX)
|
||||
}
|
||||
|
||||
if int16(buffer.cursorY)+y < 0 {
|
||||
y = -int16(buffer.cursorY)
|
||||
}
|
||||
|
||||
buffer.SetPosition(uint16(int16(buffer.cursorX)+x), uint16(int16(buffer.cursorY)+y))
|
||||
}
|
||||
|
||||
func (buffer *Buffer) SetPosition(col uint16, line uint16) {
|
||||
if col >= buffer.ViewWidth() {
|
||||
col = buffer.ViewWidth() - 1
|
||||
logrus.Errorf("Cannot set cursor position: column %d is outside of the current view width (%d columns)", col, buffer.ViewWidth())
|
||||
}
|
||||
if line >= buffer.ViewHeight() {
|
||||
line = buffer.ViewHeight() - 1
|
||||
logrus.Errorf("Cannot set cursor position: line %d is outside of the current view height (%d lines)", line, buffer.ViewHeight())
|
||||
}
|
||||
buffer.cursorX = col
|
||||
buffer.cursorY = line
|
||||
}
|
||||
|
||||
func (buffer *Buffer) GetVisibleLines() []Line {
|
||||
lines := []Line{}
|
||||
for i := buffer.Height() - int(buffer.ViewHeight()); i < buffer.Height(); i++ {
|
||||
if i >= 0 && i < len(buffer.lines) {
|
||||
lines = append(lines, buffer.lines[i])
|
||||
}
|
||||
}
|
||||
return lines
|
||||
}
|
||||
|
||||
// tested to here
|
||||
|
||||
func (buffer *Buffer) Clear() {
|
||||
for i := 0; i < int(buffer.ViewHeight()); i++ {
|
||||
buffer.lines = append(buffer.lines, newLine())
|
||||
}
|
||||
buffer.SetPosition(0, 0)
|
||||
}
|
||||
|
||||
func (buffer *Buffer) ResizeView(width uint16, height uint16) {
|
||||
buffer.viewWidth = width
|
||||
buffer.viewHeight = height
|
||||
|
||||
// @todo wrap/unwrap
|
||||
}
|
||||
|
|
|
@ -8,36 +8,47 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestOffsets(t *testing.T) {
|
||||
b := NewBuffer(10, 8)
|
||||
test := "hellothere\nhellothere\nhellothere\nhellothere\nhellothere\nhellothere\nhellothere\nhellothere\nhellothere\nhellothere\nhellothere\nhellothere\n?"
|
||||
b.Write([]rune(test)...)
|
||||
assert.Equal(t, uint16(10), b.ViewWidth())
|
||||
assert.Equal(t, uint16(10), b.Width())
|
||||
assert.Equal(t, uint16(8), b.ViewHeight())
|
||||
assert.Equal(t, 13, b.Height())
|
||||
}
|
||||
|
||||
func TestBufferCreation(t *testing.T) {
|
||||
b := NewBuffer(10)
|
||||
assert.Equal(t, 10, b.Width())
|
||||
assert.Equal(t, 0, b.Column())
|
||||
assert.Equal(t, 0, b.Line())
|
||||
b := NewBuffer(10, 20)
|
||||
assert.Equal(t, uint16(10), b.Width())
|
||||
assert.Equal(t, uint16(20), b.ViewHeight())
|
||||
assert.Equal(t, uint16(0), b.CursorColumn())
|
||||
assert.Equal(t, uint16(0), b.CursorLine())
|
||||
assert.NotNil(t, b.lines)
|
||||
}
|
||||
|
||||
func TestBufferCursorIncrement(t *testing.T) {
|
||||
|
||||
b := NewBuffer(5)
|
||||
b := NewBuffer(5, 4)
|
||||
b.incrementCursorPosition()
|
||||
require.Equal(t, 1, b.Column())
|
||||
require.Equal(t, 0, b.Line())
|
||||
require.Equal(t, uint16(1), b.CursorColumn())
|
||||
require.Equal(t, uint16(0), b.CursorLine())
|
||||
|
||||
b.incrementCursorPosition()
|
||||
require.Equal(t, 2, b.Column())
|
||||
require.Equal(t, 0, b.Line())
|
||||
require.Equal(t, uint16(2), b.CursorColumn())
|
||||
require.Equal(t, uint16(0), b.CursorLine())
|
||||
|
||||
b.incrementCursorPosition()
|
||||
require.Equal(t, 3, b.Column())
|
||||
require.Equal(t, 0, b.Line())
|
||||
require.Equal(t, uint16(3), b.CursorColumn())
|
||||
require.Equal(t, uint16(0), b.CursorLine())
|
||||
|
||||
b.incrementCursorPosition()
|
||||
require.Equal(t, 4, b.Column())
|
||||
require.Equal(t, 0, b.Line())
|
||||
require.Equal(t, uint16(4), b.CursorColumn())
|
||||
require.Equal(t, uint16(0), b.CursorLine())
|
||||
|
||||
b.incrementCursorPosition()
|
||||
require.Equal(t, 0, b.Column())
|
||||
require.Equal(t, 1, b.Line())
|
||||
require.Equal(t, uint16(0), b.CursorColumn())
|
||||
require.Equal(t, uint16(1), b.CursorLine())
|
||||
|
||||
b.incrementCursorPosition()
|
||||
b.incrementCursorPosition()
|
||||
|
@ -50,11 +61,179 @@ func TestBufferCursorIncrement(t *testing.T) {
|
|||
b.incrementCursorPosition()
|
||||
b.incrementCursorPosition()
|
||||
|
||||
require.Equal(t, 0, b.Column())
|
||||
require.Equal(t, 3, b.Line())
|
||||
require.Equal(t, uint16(0), b.CursorColumn())
|
||||
require.Equal(t, uint16(3), b.CursorLine())
|
||||
|
||||
b.Write([]rune("hello\n")...)
|
||||
b.Write([]rune("hello\n")...)
|
||||
b.Write([]rune("hello\n")...)
|
||||
b.Write([]rune("hello\n")...)
|
||||
b.Write([]rune("hello\n")...)
|
||||
b.Write([]rune("hello")...)
|
||||
b.SetPosition(0, 2)
|
||||
b.incrementCursorPosition()
|
||||
|
||||
}
|
||||
|
||||
func TestBufferWrite(t *testing.T) {
|
||||
|
||||
b := NewBuffer(5, 20)
|
||||
|
||||
assert.Equal(t, uint16(0), b.CursorColumn())
|
||||
assert.Equal(t, uint16(0), b.CursorLine())
|
||||
|
||||
b.Write('a')
|
||||
assert.Equal(t, uint16(1), b.CursorColumn())
|
||||
assert.Equal(t, uint16(0), b.CursorLine())
|
||||
|
||||
b.Write('b')
|
||||
assert.Equal(t, uint16(2), b.CursorColumn())
|
||||
assert.Equal(t, uint16(0), b.CursorLine())
|
||||
|
||||
b.Write('c')
|
||||
assert.Equal(t, uint16(3), b.CursorColumn())
|
||||
assert.Equal(t, uint16(0), b.CursorLine())
|
||||
|
||||
b.Write('d')
|
||||
assert.Equal(t, uint16(4), b.CursorColumn())
|
||||
assert.Equal(t, uint16(0), b.CursorLine())
|
||||
|
||||
b.Write('e')
|
||||
assert.Equal(t, uint16(0), b.CursorColumn())
|
||||
assert.Equal(t, uint16(1), b.CursorLine())
|
||||
|
||||
b.Write('f')
|
||||
assert.Equal(t, uint16(1), b.CursorColumn())
|
||||
assert.Equal(t, uint16(1), b.CursorLine())
|
||||
|
||||
//b.lines[0].cells[]
|
||||
|
||||
}
|
||||
|
||||
func TestWritingNewLineAsFirstRuneOnWrappedLine(t *testing.T) {
|
||||
b := NewBuffer(3, 20)
|
||||
b.Write('a', 'b', 'c')
|
||||
assert.Equal(t, uint16(0), b.cursorX)
|
||||
b.Write(0x0a)
|
||||
b.Write('d', 'e', 'f')
|
||||
b.Write(0x0a)
|
||||
|
||||
assert.Equal(t, "abc", b.lines[0].String())
|
||||
assert.Equal(t, "def", b.lines[1].String())
|
||||
assert.Equal(t, "", b.lines[2].String())
|
||||
|
||||
}
|
||||
|
||||
func TestWritingNewLineAsSecondRuneOnWrappedLine(t *testing.T) {
|
||||
b := NewBuffer(3, 20)
|
||||
b.Write('a', 'b', 'c', 'd')
|
||||
b.Write(0x0a)
|
||||
b.Write('e', 'f')
|
||||
b.Write(0x0a)
|
||||
b.Write(0x0a)
|
||||
b.Write(0x0a)
|
||||
b.Write('z')
|
||||
|
||||
assert.Equal(t, "abc", b.lines[0].String())
|
||||
assert.Equal(t, "d", b.lines[1].String())
|
||||
assert.Equal(t, "ef", b.lines[2].String())
|
||||
assert.Equal(t, "", b.lines[3].String())
|
||||
assert.Equal(t, "", b.lines[4].String())
|
||||
assert.Equal(t, "z", b.lines[5].String())
|
||||
}
|
||||
|
||||
func TestSetPosition(t *testing.T) {
|
||||
|
||||
b := NewBuffer(120, 80)
|
||||
assert.Equal(t, 0, int(b.CursorColumn()))
|
||||
assert.Equal(t, 0, int(b.CursorLine()))
|
||||
b.SetPosition(60, 10)
|
||||
assert.Equal(t, 60, int(b.CursorColumn()))
|
||||
assert.Equal(t, 10, int(b.CursorLine()))
|
||||
b.SetPosition(0, 0)
|
||||
assert.Equal(t, 0, int(b.CursorColumn()))
|
||||
assert.Equal(t, 0, int(b.CursorLine()))
|
||||
b.SetPosition(120, 90)
|
||||
assert.Equal(t, 119, int(b.CursorColumn()))
|
||||
assert.Equal(t, 79, int(b.CursorLine()))
|
||||
|
||||
}
|
||||
|
||||
func TestMovePosition(t *testing.T) {
|
||||
b := NewBuffer(120, 80)
|
||||
assert.Equal(t, 0, int(b.CursorColumn()))
|
||||
assert.Equal(t, 0, int(b.CursorLine()))
|
||||
b.MovePosition(-1, -1)
|
||||
assert.Equal(t, 0, int(b.CursorColumn()))
|
||||
assert.Equal(t, 0, int(b.CursorLine()))
|
||||
b.MovePosition(30, 20)
|
||||
assert.Equal(t, 30, int(b.CursorColumn()))
|
||||
assert.Equal(t, 20, int(b.CursorLine()))
|
||||
b.MovePosition(30, 20)
|
||||
assert.Equal(t, 60, int(b.CursorColumn()))
|
||||
assert.Equal(t, 40, int(b.CursorLine()))
|
||||
b.MovePosition(-1, -1)
|
||||
assert.Equal(t, 59, int(b.CursorColumn()))
|
||||
assert.Equal(t, 39, int(b.CursorLine()))
|
||||
b.MovePosition(100, 100)
|
||||
assert.Equal(t, 119, int(b.CursorColumn()))
|
||||
assert.Equal(t, 79, int(b.CursorLine()))
|
||||
}
|
||||
|
||||
func TestVisibleLines(t *testing.T) {
|
||||
|
||||
b := NewBuffer(80, 10)
|
||||
b.Write([]rune("hello 1\n")...)
|
||||
b.Write([]rune("hello 2\n")...)
|
||||
b.Write([]rune("hello 3\n")...)
|
||||
b.Write([]rune("hello 4\n")...)
|
||||
b.Write([]rune("hello 5\n")...)
|
||||
b.Write([]rune("hello 6\n")...)
|
||||
b.Write([]rune("hello 7\n")...)
|
||||
b.Write([]rune("hello 8\n")...)
|
||||
b.Write([]rune("hello 9\n")...)
|
||||
b.Write([]rune("hello 10\n")...)
|
||||
b.Write([]rune("hello 11\n")...)
|
||||
b.Write([]rune("hello 12\n")...)
|
||||
b.Write([]rune("hello 13\n")...)
|
||||
b.Write([]rune("hello 14")...)
|
||||
|
||||
lines := b.GetVisibleLines()
|
||||
require.Equal(t, 10, len(lines))
|
||||
assert.Equal(t, "hello 5", lines[0].String())
|
||||
assert.Equal(t, "hello 14", lines[9].String())
|
||||
|
||||
}
|
||||
|
||||
func TestClearWithoutFullView(t *testing.T) {
|
||||
b := NewBuffer(80, 10)
|
||||
b.Write([]rune("hello 1\n")...)
|
||||
b.Write([]rune("hello 2\n")...)
|
||||
b.Write([]rune("hello 3")...)
|
||||
b.Clear()
|
||||
lines := b.GetVisibleLines()
|
||||
for _, line := range lines {
|
||||
assert.Equal(t, "", line.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestClearWithFullView(t *testing.T) {
|
||||
b := NewBuffer(80, 5)
|
||||
b.Write([]rune("hello 1\n")...)
|
||||
b.Write([]rune("hello 2\n")...)
|
||||
b.Write([]rune("hello 3\n")...)
|
||||
b.Write([]rune("hello 4\n")...)
|
||||
b.Write([]rune("hello 5\n")...)
|
||||
b.Write([]rune("hello 6\n")...)
|
||||
b.Write([]rune("hello 7\n")...)
|
||||
b.Write([]rune("hello 8\n")...)
|
||||
b.Clear()
|
||||
lines := b.GetVisibleLines()
|
||||
for _, line := range lines {
|
||||
assert.Equal(t, "", line.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestResizeView(t *testing.T) {
|
||||
b := NewBuffer(80, 20)
|
||||
b.ResizeView(40, 10)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package buffer
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSetRune(t *testing.T) {
|
||||
cell := newCell()
|
||||
assert.False(t, cell.hasContent)
|
||||
cell.setRune('X')
|
||||
assert.True(t, cell.hasContent)
|
||||
assert.Equal(t, 'X', cell.r)
|
||||
cell.setRune('Y')
|
||||
assert.True(t, cell.hasContent)
|
||||
assert.Equal(t, 'Y', cell.r)
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
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
|
|
@ -1,5 +0,0 @@
|
|||
package buffer
|
||||
|
||||
type Cursor struct {
|
||||
// holds current attr data
|
||||
}
|
|
@ -1,13 +1,25 @@
|
|||
package buffer
|
||||
|
||||
type line struct {
|
||||
type Line struct {
|
||||
wrapped bool // whether line was wrapped onto from the previous one
|
||||
cells []Cell
|
||||
}
|
||||
|
||||
func newLine() line {
|
||||
return line{
|
||||
func newLine() Line {
|
||||
return Line{
|
||||
wrapped: false,
|
||||
cells: []Cell{},
|
||||
}
|
||||
}
|
||||
|
||||
func (line *Line) setWrapped(wrapped bool) {
|
||||
line.wrapped = wrapped
|
||||
}
|
||||
|
||||
func (line *Line) String() string {
|
||||
runes := []rune{}
|
||||
for _, cell := range line.cells {
|
||||
runes = append(runes, cell.r)
|
||||
}
|
||||
return string(runes)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package buffer
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestLine(t *testing.T) {
|
||||
|
||||
line := newLine()
|
||||
line.cells = []Cell{
|
||||
{r: 'h'},
|
||||
{r: 'e'},
|
||||
{r: 'l'},
|
||||
{r: 'l'},
|
||||
{r: 'o'},
|
||||
}
|
||||
|
||||
assert.Equal(t, "hello", line.String())
|
||||
assert.False(t, line.wrapped)
|
||||
|
||||
line.setWrapped(true)
|
||||
assert.True(t, line.wrapped)
|
||||
|
||||
line.setWrapped(false)
|
||||
assert.False(t, line.wrapped)
|
||||
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
package buffer
|
||||
|
||||
type View struct {
|
||||
}
|
Loading…
Reference in New Issue