Move file-specific logic to a document struct
All checks were successful
timw4mail/gilo/pipeline/head This commit looks good
All checks were successful
timw4mail/gilo/pipeline/head This commit looks good
This commit is contained in:
parent
d831bd4f83
commit
1d4c8f99c0
46
editor/buffer.go
Normal file
46
editor/buffer.go
Normal 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
47
editor/document.go
Normal 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
35
editor/document_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
@ -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()
|
|
||||||
}
|
|
@ -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
|
||||||
|
@ -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)
|
//}
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user