Move file-specific logic to a document struct
All checks were successful
timw4mail/gilo/pipeline/head This commit looks good

This commit is contained in:
Timothy Warren 2021-04-01 12:02:17 -04:00
parent d831bd4f83
commit 1d4c8f99c0
6 changed files with 169 additions and 109 deletions

46
editor/buffer.go Normal file
View File

@ -0,0 +1,46 @@
package editor
import (
"fmt"
"strings"
)
// ----------------------------------------------------------------------------
// !Output Buffer
// ----------------------------------------------------------------------------
type buffer struct {
buf *strings.Builder
}
func newBuffer() *buffer {
var buf strings.Builder
b := new(buffer)
b.buf = &buf
return b
}
func (b *buffer) appendRune(r rune) int {
size, _ := b.buf.WriteRune(r)
return size
}
func (b *buffer) append(s string) int {
size, _ := b.buf.WriteString(s)
return size
}
func (b *buffer) appendLn(s string) int {
str := fmt.Sprintf("%s\r\n", s)
size, _ := b.buf.WriteString(str)
return size
}
func (b *buffer) toString() string {
return b.buf.String()
}

47
editor/document.go Normal file
View File

@ -0,0 +1,47 @@
package editor
import (
"bufio"
"log"
"os"
)
type document struct {
filename string
rows []*row
}
func newDocument() *document {
var rows []*row
return &document{
"",
rows,
}
}
func (d *document) open(filename string) {
file, err := os.Open(filename)
if err != nil {
log.Fatalf("failed to open file")
}
defer file.Close()
d.filename = filename
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
d.appendRow(scanner.Text())
}
}
func (d *document) appendRow(s string) {
newRow := newRow(s)
newRow.update()
d.rows = append(d.rows, newRow)
}
func (d *document) rowCount() int {
return len(d.rows)
}

35
editor/document_test.go Normal file
View File

@ -0,0 +1,35 @@
package editor
import "testing"
func TestNewDocument(t *testing.T) {
d := newDocument()
if d == nil {
t.Errorf("Failed to create document")
}
}
func TestAppendRow(t *testing.T) {
d := newDocument()
d.appendRow("Test Row")
got := len(d.rows)
want := 1
if got != want {
t.Errorf("Failed to add a row to the document")
}
}
func TestRowCount(t *testing.T) {
d := newDocument()
d.appendRow("Test Row")
got := d.rowCount()
want := 1
if got != want {
t.Errorf("Expected %d rows, got %d rows", want, got)
}
}

View File

@ -32,8 +32,8 @@ func (e *editor) RefreshScreen() {
func (e *editor) scroll() { func (e *editor) scroll() {
e.renderX = 0 e.renderX = 0
if e.cursor.y < e.rowCount() { if e.cursor.y < e.document.rowCount() {
e.renderX = e.rows[e.cursor.y].cursorXToRenderX(e.cursor.x) e.renderX = e.document.rows[e.cursor.y].cursorXToRenderX(e.cursor.x)
} }
if e.cursor.y < e.offset.y { if e.cursor.y < e.offset.y {
@ -57,10 +57,10 @@ func (e *editor) drawRows(ab *buffer) {
for y :=0; y < e.screen.Rows; y++ { for y :=0; y < e.screen.Rows; y++ {
fileRow := y + e.offset.y fileRow := y + e.offset.y
if fileRow >= e.rowCount() { if fileRow >= e.document.rowCount() {
e.drawPlaceholderRow(y, ab) e.drawPlaceholderRow(y, ab)
} else { } else {
rawRow := e.rows[fileRow] rawRow := e.document.rows[fileRow]
// If the column offset is greater than the length of the row, // If the column offset is greater than the length of the row,
// just display an empty row // just display an empty row
@ -70,8 +70,8 @@ func (e *editor) drawRows(ab *buffer) {
continue continue
} }
rowLen := e.rows[fileRow].rSize() - e.offset.x rowLen := e.document.rows[fileRow].rSize() - e.offset.x
outputRow := truncateString(string(e.rows[fileRow].render[e.offset.x:]), rowLen) outputRow := truncateString(string(e.document.rows[fileRow].render[e.offset.x:]), rowLen)
ab.append(outputRow) ab.append(outputRow)
} }
@ -81,7 +81,7 @@ func (e *editor) drawRows(ab *buffer) {
} }
func (e *editor) drawPlaceholderRow(y int, ab *buffer) { func (e *editor) drawPlaceholderRow(y int, ab *buffer) {
if e.rowCount() == 0 && y == e.screen.Rows / 3 { if e.document.rowCount() == 0 && y == e.screen.Rows / 3 {
welcome := fmt.Sprintf("Gilo editor -- version %s", KiloVersion) welcome := fmt.Sprintf("Gilo editor -- version %s", KiloVersion)
if len(welcome) > e.screen.Cols { if len(welcome) > e.screen.Cols {
welcome = truncateString(welcome, e.screen.Cols) welcome = truncateString(welcome, e.screen.Cols)
@ -112,43 +112,3 @@ func (e *editor) drawStatusBar(ab *buffer) {
ab.append(terminal.ResetColor) ab.append(terminal.ResetColor)
} }
// ----------------------------------------------------------------------------
// !Output Buffer
// ----------------------------------------------------------------------------
type buffer struct {
buf *strings.Builder
}
func newBuffer() *buffer {
var buf strings.Builder
b := new(buffer)
b.buf = &buf
return b
}
func (b *buffer) appendRune(r rune) int {
size, _ := b.buf.WriteRune(r)
return size
}
func (b *buffer) append(s string) int {
size, _ := b.buf.WriteString(s)
return size
}
func (b *buffer) appendLn(s string) int {
str := fmt.Sprintf("%s\r\n", s)
size, _ := b.buf.WriteString(str)
return size
}
func (b *buffer) toString() string {
return b.buf.String()
}

View File

@ -1,9 +1,6 @@
package editor package editor
import ( import (
"bufio"
"log"
"os"
"timshome.page/gilo/terminal" "timshome.page/gilo/terminal"
) )
@ -20,8 +17,8 @@ type editor struct {
screen *terminal.Screen screen *terminal.Screen
cursor *point cursor *point
offset *point offset *point
document *document
renderX int renderX int
rows []*row
} }
func New() *editor { func New() *editor {
@ -32,30 +29,19 @@ func New() *editor {
cursor := &point { 0, 0 } cursor := &point { 0, 0 }
offset := &point { 0, 0 } offset := &point { 0, 0 }
var rows []*row document := newDocument()
return &editor{ return &editor{
screen, screen,
cursor, cursor,
offset, offset,
document,
0, 0,
rows,
} }
} }
func (e *editor) Open(filename string) { func (e *editor) Open(filename string) {
file, err := os.Open(filename) e.document.open(filename)
if err != nil {
log.Fatalf("failed to open file")
}
defer file.Close()
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
e.appendRow(scanner.Text())
}
} }
func (e *editor) ProcessKeypress() bool { func (e *editor) ProcessKeypress() bool {
@ -92,10 +78,10 @@ func (e *editor) ProcessKeypress() bool {
func (e *editor) moveCursor (key string) { func (e *editor) moveCursor (key string) {
var row *row var row *row
if e.cursor.y >= len(e.rows) { if e.cursor.y >= e.document.rowCount() {
row = nil row = nil
} else { } else {
row = e.rows[e.cursor.y] row = e.document.rows[e.cursor.y]
} }
switch key { switch key {
@ -107,7 +93,7 @@ func (e *editor) moveCursor (key string) {
// Move from beginning of current row to end of previous row // Move from beginning of current row to end of previous row
if e.cursor.y > 0 { if e.cursor.y > 0 {
e.cursor.y -= 1 e.cursor.y -= 1
e.cursor.x = e.rows[e.cursor.y].size() e.cursor.x = e.document.rows[e.cursor.y].size()
} }
case keyRight: case keyRight:
if row != nil && e.cursor.x < row.size() { if row != nil && e.cursor.x < row.size() {
@ -115,7 +101,7 @@ func (e *editor) moveCursor (key string) {
} }
// Move from end of current line to beginning of next line // Move from end of current line to beginning of next line
if row != nil && e.cursor.x == row.size() && e.cursor.y < len(e.rows) - 1 { if row != nil && e.cursor.x == row.size() && e.cursor.y < e.document.rowCount() - 1 {
e.cursor.y += 1 e.cursor.y += 1
e.cursor.x = 0 e.cursor.x = 0
} }
@ -124,7 +110,7 @@ func (e *editor) moveCursor (key string) {
e.cursor.y -= 1 e.cursor.y -= 1
} }
case keyDown: case keyDown:
if e.cursor.y < (len(e.rows) - 1) { if e.cursor.y < (e.document.rowCount() - 1) {
e.cursor.y += 1 e.cursor.y += 1
} }
case keyPageUp: case keyPageUp:
@ -135,10 +121,10 @@ func (e *editor) moveCursor (key string) {
} }
case keyPageDown: case keyPageDown:
if e.cursor.y + e.screen.Rows > len(e.rows) { if e.cursor.y + e.screen.Rows > e.document.rowCount() {
e.cursor.y += e.screen.Rows e.cursor.y += e.screen.Rows
} else { } else {
e.cursor.y = len(e.rows) - 1 e.cursor.y = e.document.rowCount() - 1
} }
case keyHome: case keyHome:
@ -149,10 +135,8 @@ func (e *editor) moveCursor (key string) {
} }
} }
if e.cursor.y > len(e.rows) { if e.cursor.y < e.document.rowCount() {
row = nil row = e.document.rows[e.cursor.y]
} else {
row = e.rows[e.cursor.y]
rowLen := row.size() rowLen := row.size()
// Snap to the end of a shorter line from a longer one // Snap to the end of a shorter line from a longer one
@ -162,16 +146,6 @@ func (e *editor) moveCursor (key string) {
} }
} }
func (e *editor) appendRow(s string) {
newRow := newRow(s)
newRow.update()
e.rows = append(e.rows, newRow)
}
func (e *editor) rowCount() int {
return len(e.rows)
}
// Convert the raw ANSI escape sequences to the type of key input // Convert the raw ANSI escape sequences to the type of key input
func parseEscapeSequence () string { func parseEscapeSequence () string {
var runes []rune var runes []rune

View File

@ -10,26 +10,24 @@ func TestNew(t *testing.T) {
} }
} }
func TestAppendRow(t *testing.T) { //type moveCursor struct {
e := New() // key string
e.appendRow("Test Row") // editor *editor
//}
got := len(e.rows) //
want := 1 //var cursorTests = []moveCursor{
// {"\x1b", New()},
if got != want { //}
t.Errorf("Failed to add a row to the editor") //
} //func TestMoveCursor(t *testing.T) {
} // for _, test := range cursorTests {
// e := New()
func TestRowCount(t *testing.T) { // e.moveCursor(test.key)
e := New() // want := test.editor
e.appendRow("Test Row") // got := e
//
got := e.rowCount() // if got != want {
want := 1 // t.Errorf("Output %v not equal to expected %v for input %q", got, want, test.key)
// }
if got != want { // }
t.Errorf("Expected %d rows, got %d rows", want, got) //}
}
}