From ae65be003c2f8f423f917d4211eff423967a7f4e Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Wed, 31 Mar 2021 14:32:43 -0400 Subject: [PATCH] Fix some offset errors for cursor operations --- editor/constants.go | 3 ++- editor/draw.go | 7 ++++--- editor/editor.go | 31 +++++++++++++++++++++---------- editor/row.go | 24 +++++++++++++++++++++--- editor/row_test.go | 6 +++--- 5 files changed, 51 insertions(+), 20 deletions(-) diff --git a/editor/constants.go b/editor/constants.go index 2b40751..2819ccc 100644 --- a/editor/constants.go +++ b/editor/constants.go @@ -4,4 +4,5 @@ package editor // !Constants // ---------------------------------------------------------------------------- -const KiloVersion = "0.0.1" \ No newline at end of file +const KiloVersion = "0.0.1" +const KiloTabStop = 4 \ No newline at end of file diff --git a/editor/draw.go b/editor/draw.go index 0946e73..ea57c3e 100644 --- a/editor/draw.go +++ b/editor/draw.go @@ -56,14 +56,15 @@ func (e *editor) drawRows(ab *buffer) { // If the column offset is greater than the length of the row, // just display an empty row - if e.offset.x > rawRow.Size() { + if e.offset.x > rawRow.size() { ab.append("") continue } - row := truncateString(string(e.rows[fileRow].chars[e.offset.x:]), e.screen.Cols) - ab.append(row) + rowLen := e.rows[fileRow].rSize() - e.offset.x + outputRow := truncateString(string(e.rows[fileRow].render[e.offset.x:]), rowLen) + ab.append(outputRow) } ab.append(terminal.ClearLine) diff --git a/editor/editor.go b/editor/editor.go index 7188508..58771cd 100644 --- a/editor/editor.go +++ b/editor/editor.go @@ -86,7 +86,7 @@ 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 >= len(e.rows) { row = nil } else { row = e.rows[e.cursor.y] @@ -101,15 +101,15 @@ 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.rows[e.cursor.y].size() } case keyRight: - if row != nil && e.cursor.x < row.Size() { + if row != nil && e.cursor.x < row.size() { e.cursor.x += 1 } // Move from end of current line to beginning of next line - if row != nil && e.cursor.x == row.Size() { + if row != nil && e.cursor.x == row.size() && e.cursor.y < len(e.rows) - 1 { e.cursor.y += 1 e.cursor.x = 0 } @@ -118,18 +118,28 @@ func (e *editor) moveCursor (key string) { e.cursor.y -= 1 } case keyDown: - if e.cursor.y < len(e.rows) { + if e.cursor.y < (len(e.rows) - 1) { e.cursor.y += 1 } case keyPageUp: - e.cursor.y = 0 + if e.cursor.y > e.screen.Rows { + e.cursor.y -= e.screen.Rows + } else { + e.cursor.y = 0 + } + case keyPageDown: - e.cursor.y = e.screen.Rows + if e.cursor.y + e.screen.Rows > len(e.rows) { + e.cursor.y += e.screen.Rows + } else { + e.cursor.y = len(e.rows) - 1 + } + case keyHome: e.cursor.x = 0 case keyEnd: if row != nil { - e.cursor.x = row.Size() + e.cursor.x = row.size() } } @@ -137,7 +147,7 @@ func (e *editor) moveCursor (key string) { row = nil } 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 if e.cursor.x > rowLen { @@ -147,7 +157,8 @@ func (e *editor) moveCursor (key string) { } func (e *editor) appendRow(s string) { - newRow := NewRow(s) + newRow := newRow(s) + newRow.update() e.rows = append(e.rows, newRow) } diff --git a/editor/row.go b/editor/row.go index fb51558..fc3da1e 100644 --- a/editor/row.go +++ b/editor/row.go @@ -1,21 +1,39 @@ package editor +import "strings" + type row struct { chars []rune + render []rune } -func NewRow(s string) *row { +func newRow(s string) *row { var chars []rune + var render []rune for _, ch := range s { chars = append(chars, ch) + render = append(render, ch) } - return &row {chars} + return &row {chars, render} } -func (r *row) Size() int { +func (r *row) size() int { return len(r.chars) } +func (r *row) rSize() int { + return len(r.render) +} + +func (r *row) update() { + r.render = r.render[:0] + replacement := strings.Repeat(" ", KiloTabStop) + + str := strings.ReplaceAll(string(r.chars), "\t", replacement) + for _, ch := range str { + r.render = append(r.render, ch) + } +} diff --git a/editor/row_test.go b/editor/row_test.go index 0eb07ec..6a9bf16 100644 --- a/editor/row_test.go +++ b/editor/row_test.go @@ -4,7 +4,7 @@ import "testing" func TestNewRow(t *testing.T) { str := "abcdefg" - row := NewRow(str) + row := newRow(str) got := string(row.chars) want := str @@ -16,9 +16,9 @@ func TestNewRow(t *testing.T) { func TestRowSize(t *testing.T) { str := "abcdefg" - row := NewRow(str) + row := newRow(str) - got := row.Size() + got := row.size() want := 7 if got != want {