From 1d4c8f99c0a7fbe0b508dba55a1be67d8a45ec47 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Thu, 1 Apr 2021 12:02:17 -0400 Subject: [PATCH] Move file-specific logic to a document struct --- editor/buffer.go | 46 +++++++++++++++++++++++++++++++++++ editor/document.go | 47 +++++++++++++++++++++++++++++++++++ editor/document_test.go | 35 ++++++++++++++++++++++++++ editor/draw.go | 54 ++++++----------------------------------- editor/editor.go | 52 ++++++++++----------------------------- editor/editor_test.go | 44 ++++++++++++++++----------------- 6 files changed, 169 insertions(+), 109 deletions(-) create mode 100644 editor/buffer.go create mode 100644 editor/document.go create mode 100644 editor/document_test.go diff --git a/editor/buffer.go b/editor/buffer.go new file mode 100644 index 0000000..ea8d868 --- /dev/null +++ b/editor/buffer.go @@ -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() +} diff --git a/editor/document.go b/editor/document.go new file mode 100644 index 0000000..a86aa8f --- /dev/null +++ b/editor/document.go @@ -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) +} \ No newline at end of file diff --git a/editor/document_test.go b/editor/document_test.go new file mode 100644 index 0000000..e019bc5 --- /dev/null +++ b/editor/document_test.go @@ -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) + } +} \ No newline at end of file diff --git a/editor/draw.go b/editor/draw.go index e385d0a..09669a3 100644 --- a/editor/draw.go +++ b/editor/draw.go @@ -32,8 +32,8 @@ func (e *editor) RefreshScreen() { func (e *editor) scroll() { e.renderX = 0 - if e.cursor.y < e.rowCount() { - e.renderX = e.rows[e.cursor.y].cursorXToRenderX(e.cursor.x) + if e.cursor.y < e.document.rowCount() { + e.renderX = e.document.rows[e.cursor.y].cursorXToRenderX(e.cursor.x) } 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++ { fileRow := y + e.offset.y - if fileRow >= e.rowCount() { + if fileRow >= e.document.rowCount() { e.drawPlaceholderRow(y, ab) } else { - rawRow := e.rows[fileRow] + rawRow := e.document.rows[fileRow] // If the column offset is greater than the length of the row, // just display an empty row @@ -70,8 +70,8 @@ func (e *editor) drawRows(ab *buffer) { continue } - rowLen := e.rows[fileRow].rSize() - e.offset.x - outputRow := truncateString(string(e.rows[fileRow].render[e.offset.x:]), rowLen) + rowLen := e.document.rows[fileRow].rSize() - e.offset.x + outputRow := truncateString(string(e.document.rows[fileRow].render[e.offset.x:]), rowLen) ab.append(outputRow) } @@ -81,7 +81,7 @@ func (e *editor) drawRows(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) if len(welcome) > e.screen.Cols { welcome = truncateString(welcome, e.screen.Cols) @@ -112,43 +112,3 @@ func (e *editor) drawStatusBar(ab *buffer) { 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() -} \ No newline at end of file diff --git a/editor/editor.go b/editor/editor.go index 871fc47..16c6db2 100644 --- a/editor/editor.go +++ b/editor/editor.go @@ -1,9 +1,6 @@ package editor import ( - "bufio" - "log" - "os" "timshome.page/gilo/terminal" ) @@ -20,8 +17,8 @@ type editor struct { screen *terminal.Screen cursor *point offset *point + document *document renderX int - rows []*row } func New() *editor { @@ -32,30 +29,19 @@ func New() *editor { cursor := &point { 0, 0 } offset := &point { 0, 0 } - var rows []*row + document := newDocument() return &editor{ screen, cursor, offset, + document, 0, - rows, } } func (e *editor) Open(filename string) { - file, err := os.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()) - } + e.document.open(filename) } func (e *editor) ProcessKeypress() bool { @@ -92,10 +78,10 @@ func (e *editor) ProcessKeypress() bool { func (e *editor) moveCursor (key string) { var row *row - if e.cursor.y >= len(e.rows) { + if e.cursor.y >= e.document.rowCount() { row = nil } else { - row = e.rows[e.cursor.y] + row = e.document.rows[e.cursor.y] } switch key { @@ -107,7 +93,7 @@ func (e *editor) moveCursor (key string) { // Move from beginning of current row to end of previous row if e.cursor.y > 0 { 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: 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 - 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.x = 0 } @@ -124,7 +110,7 @@ func (e *editor) moveCursor (key string) { e.cursor.y -= 1 } case keyDown: - if e.cursor.y < (len(e.rows) - 1) { + if e.cursor.y < (e.document.rowCount() - 1) { e.cursor.y += 1 } case keyPageUp: @@ -135,10 +121,10 @@ func (e *editor) moveCursor (key string) { } 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 } else { - e.cursor.y = len(e.rows) - 1 + e.cursor.y = e.document.rowCount() - 1 } case keyHome: @@ -149,10 +135,8 @@ func (e *editor) moveCursor (key string) { } } - if e.cursor.y > len(e.rows) { - row = nil - } else { - row = e.rows[e.cursor.y] + if e.cursor.y < e.document.rowCount() { + row = e.document.rows[e.cursor.y] rowLen := row.size() // 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 func parseEscapeSequence () string { var runes []rune diff --git a/editor/editor_test.go b/editor/editor_test.go index 34c65e4..abd97ed 100644 --- a/editor/editor_test.go +++ b/editor/editor_test.go @@ -10,26 +10,24 @@ func TestNew(t *testing.T) { } } -func TestAppendRow(t *testing.T) { - e := New() - e.appendRow("Test Row") - - got := len(e.rows) - want := 1 - - if got != want { - t.Errorf("Failed to add a row to the editor") - } -} - -func TestRowCount(t *testing.T) { - e := New() - e.appendRow("Test Row") - - got := e.rowCount() - want := 1 - - if got != want { - t.Errorf("Expected %d rows, got %d rows", want, got) - } -} \ No newline at end of file +//type moveCursor struct { +// key string +// editor *editor +//} +// +//var cursorTests = []moveCursor{ +// {"\x1b", New()}, +//} +// +//func TestMoveCursor(t *testing.T) { +// for _, test := range cursorTests { +// e := New() +// e.moveCursor(test.key) +// want := test.editor +// got := e +// +// if got != want { +// t.Errorf("Output %v not equal to expected %v for input %q", got, want, test.key) +// } +// } +//} \ No newline at end of file