diff --git a/editor/draw.go b/editor/draw.go index 762a5b5..0946e73 100644 --- a/editor/draw.go +++ b/editor/draw.go @@ -20,7 +20,7 @@ func (e *editor) RefreshScreen() { ab.append(terminal.ResetCursor) e.drawRows(ab) - ab.append(terminal.MoveCursor(e.cursor.x, e.cursor.y)) + ab.append(terminal.MoveCursor(e.cursor.x - e.offset.x, e.cursor.y - e.offset.y)) ab.append(terminal.ShowCursor) @@ -35,6 +35,14 @@ func (e *editor) scroll() { if e.cursor.y >= e.offset.y + e.screen.Rows { e.offset.y = e.cursor.y - e.screen.Rows + 1 } + + if e.cursor.x < e.offset.x { + e.offset.x = e.cursor.x + } + + if e.cursor.x >= e.offset.x + e.screen.Cols { + e.offset.x = e.cursor.x - e.screen.Cols + } } func (e *editor) drawRows(ab *buffer) { @@ -44,7 +52,17 @@ func (e *editor) drawRows(ab *buffer) { if fileRow >= len(e.rows) { e.drawPlaceholderRow(y, ab) } else { - row := truncateString(string(e.rows[fileRow].chars), e.screen.Cols) + rawRow := e.rows[fileRow] + + // If the column offset is greater than the length of the row, + // just display an empty row + 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) } diff --git a/editor/editor.go b/editor/editor.go index 943dc93..7188508 100644 --- a/editor/editor.go +++ b/editor/editor.go @@ -85,15 +85,34 @@ func (e *editor) ProcessKeypress() bool { } func (e *editor) moveCursor (key string) { + var row *row + if e.cursor.y > len(e.rows) { + row = nil + } else { + row = e.rows[e.cursor.y] + } + switch key { case keyLeft: if e.cursor.x != 0 { e.cursor.x -= 1 } + + // 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() + } case keyRight: - if e.cursor.x != e.screen.Cols-1 { + 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() { + e.cursor.y += 1 + e.cursor.x = 0 + } case keyUp: if e.cursor.y != 0 { e.cursor.y -= 1 @@ -109,7 +128,21 @@ func (e *editor) moveCursor (key string) { case keyHome: e.cursor.x = 0 case keyEnd: - e.cursor.x = e.screen.Cols + if row != nil { + e.cursor.x = row.Size() + } + } + + if e.cursor.y > len(e.rows) { + row = nil + } else { + row = e.rows[e.cursor.y] + rowLen := row.Size() + + // Snap to the end of a shorter line from a longer one + if e.cursor.x > rowLen { + e.cursor.x = rowLen + } } }