diff --git a/buffer/buffer.go b/buffer/buffer.go new file mode 100644 index 0000000..1eb5274 --- /dev/null +++ b/buffer/buffer.go @@ -0,0 +1,74 @@ +package buffer + +import ( + "fmt" +) + +type Buffer struct { + lines []line + x int + y int + columnCount int + lineCount int +} + +// NewBuffer creates a new terminal buffer +func NewBuffer(columns int) *Buffer { + return &Buffer{ + x: 0, + y: 0, + lines: []line{}, + columnCount: columns, + } +} + +// Column returns cursor column +func (buffer *Buffer) Column() int { + return buffer.x +} + +// Line returns cursor line +func (buffer *Buffer) Line() int { + return buffer.y +} + +// Width returns the width of the buffer in columns +func (buffer *Buffer) Width() int { + return buffer.columnCount +} + +// 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 buffer.Line() >= len(buffer.lines) { + buffer.lines = append(buffer.lines, newLine()) + } + line := &buffer.lines[buffer.Line()] + for buffer.Column() >= len(line.cells) { + line.cells = append(line.cells, newCell()) + } + cell := line.cells[buffer.Column()] + cell.setRune(r) +} + +func (buffer *Buffer) incrementCursorPosition() { + + if buffer.Column()+1 < buffer.Width() { + buffer.x++ + } else { + buffer.y++ + buffer.x = 0 + } +} + +func (buffer *Buffer) SetPosition(col int, line int) 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()) + } + buffer.x = col + buffer.y = line + return nil +} + +func (buffer *Buffer) SetSize(cols int, lines int) { + +} diff --git a/buffer/buffer_test.go b/buffer/buffer_test.go new file mode 100644 index 0000000..abd616c --- /dev/null +++ b/buffer/buffer_test.go @@ -0,0 +1,60 @@ +package buffer + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/stretchr/testify/assert" +) + +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()) + assert.NotNil(t, b.lines) +} + +func TestBufferCursorIncrement(t *testing.T) { + + b := NewBuffer(5) + b.incrementCursorPosition() + require.Equal(t, 1, b.Column()) + require.Equal(t, 0, b.Line()) + + b.incrementCursorPosition() + require.Equal(t, 2, b.Column()) + require.Equal(t, 0, b.Line()) + + b.incrementCursorPosition() + require.Equal(t, 3, b.Column()) + require.Equal(t, 0, b.Line()) + + b.incrementCursorPosition() + require.Equal(t, 4, b.Column()) + require.Equal(t, 0, b.Line()) + + b.incrementCursorPosition() + require.Equal(t, 0, b.Column()) + require.Equal(t, 1, b.Line()) + + b.incrementCursorPosition() + b.incrementCursorPosition() + b.incrementCursorPosition() + b.incrementCursorPosition() + b.incrementCursorPosition() + b.incrementCursorPosition() + b.incrementCursorPosition() + b.incrementCursorPosition() + b.incrementCursorPosition() + b.incrementCursorPosition() + + require.Equal(t, 0, b.Column()) + require.Equal(t, 3, b.Line()) + +} + +func TestBufferWrite(t *testing.T) { + +} diff --git a/buffer/cell.go b/buffer/cell.go new file mode 100644 index 0000000..6ae66ba --- /dev/null +++ b/buffer/cell.go @@ -0,0 +1,27 @@ +package buffer + +type Cell struct { + r rune + attr CellAttributes + hasContent bool +} + +type CellAttributes struct { + FgColour [3]float32 + BgColour [3]float32 + Bold bool + Dim bool + Underline bool + Blink bool + Reverse bool + Hidden bool +} + +func newCell() Cell { + return Cell{} +} + +func (cell *Cell) setRune(r rune) { + cell.r = r + cell.hasContent = true +} diff --git a/buffer/cursor.go b/buffer/cursor.go new file mode 100644 index 0000000..27faa92 --- /dev/null +++ b/buffer/cursor.go @@ -0,0 +1,5 @@ +package buffer + +type Cursor struct { + // holds current attr data +} diff --git a/buffer/line.go b/buffer/line.go new file mode 100644 index 0000000..6eec4ee --- /dev/null +++ b/buffer/line.go @@ -0,0 +1,13 @@ +package buffer + +type line struct { + wrapped bool // whether line was wrapped onto from the previous one + cells []Cell +} + +func newLine() line { + return line{ + wrapped: false, + cells: []Cell{}, + } +} diff --git a/buffer/view.go b/buffer/view.go new file mode 100644 index 0000000..d0c050c --- /dev/null +++ b/buffer/view.go @@ -0,0 +1,4 @@ +package buffer + +type View struct { +} diff --git a/terminal/buffer.go b/terminal/buffer.go deleted file mode 100644 index d8a147d..0000000 --- a/terminal/buffer.go +++ /dev/null @@ -1,4 +0,0 @@ -package terminal - -type Buffer struct { -}