Move stuff again, just because
All checks were successful
timw4mail/gilo/pipeline/head This commit looks good

This commit is contained in:
Timothy Warren 2021-04-02 15:36:43 -04:00
parent c99cf3faf9
commit 787166df3a
17 changed files with 84 additions and 73 deletions

View File

@ -1,27 +0,0 @@
package editor
// ----------------------------------------------------------------------------
// !General Constants
// ----------------------------------------------------------------------------
const (
KiloVersion = "0.0.1"
KiloTabStop = 4
KiloQuitTimes = 3
)
// ----------------------------------------------------------------------------
// !Constants representing input keys
// ----------------------------------------------------------------------------
const (
keyUp = "ARROW_UP"
keyDown = "ARROW_DOWN"
keyLeft = "ARROW_LEFT"
keyRight = "ARROW_RIGHT"
keyPageUp = "PAGE_UP"
keyPageDown = "PAGE_DOWN"
keyHome = "HOME"
keyEnd = "END"
keyDelete = "DELETE"
)

View File

@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"golang.org/x/term" "golang.org/x/term"
"os" "os"
"timshome.page/gilo/editor" "timshome.page/gilo/internal/editor"
"timshome.page/gilo/internal/terminal" "timshome.page/gilo/internal/terminal"
) )
@ -22,7 +22,7 @@ func main() {
oldState := terminal.RawOn() oldState := terminal.RawOn()
defer cleanup(oldState) defer cleanup(oldState)
e := editor.New() e := editor.NewEditor()
// If there is an argument passed, open it as a file to edit // If there is an argument passed, open it as a file to edit
if len(os.Args) >= 2 && os.Args[1] != "" { if len(os.Args) >= 2 && os.Args[1] != "" {

View File

@ -1,16 +1,15 @@
package editor package document
import ( import (
"bufio" "bufio"
"log" "log"
"os" "os"
"timshome.page/gilo/internal/buffer"
"timshome.page/gilo/internal/gilo" "timshome.page/gilo/internal/gilo"
) )
type Document struct { type Document struct {
dirty bool dirty bool
filename string Filename string
rows []*Row rows []*Row
} }
@ -31,7 +30,7 @@ func (d *Document) Open(filename string) {
} }
defer file.Close() defer file.Close()
d.filename = filename d.Filename = filename
scanner := bufio.NewScanner(file) scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines) scanner.Split(bufio.ScanLines)
@ -43,11 +42,11 @@ func (d *Document) Open(filename string) {
} }
func (d *Document) Save() int { func (d *Document) Save() int {
if d.filename == "" { if d.Filename == "" {
return 0 return 0
} }
file, err := os.OpenFile(d.filename, os.O_RDWR|os.O_CREATE, 0644) file, err := os.OpenFile(d.Filename, os.O_RDWR|os.O_CREATE, 0644)
if err != nil { if err != nil {
panic("failed to open/create file for saving") panic("failed to open/create file for saving")
} }
@ -89,7 +88,7 @@ func (d *Document) AppendRow(s string) {
} }
func (d *Document) ToString() string { func (d *Document) ToString() string {
buf := buffer.NewBuffer() buf := gilo.NewBuffer()
for _, row := range d.rows { for _, row := range d.rows {
buf.Append(row.toString()) buf.Append(row.toString())
@ -105,10 +104,14 @@ func (d *Document) RowCount() int {
func (d *Document) InsertChar(at *gilo.Point, ch rune) { func (d *Document) InsertChar(at *gilo.Point, ch rune) {
d.rows[at.Y].insertRune(ch, at.X) d.rows[at.Y].insertRune(ch, at.X)
d.dirty = true
} }
func (d *Document) DelChar(at *gilo.Point) { func (d *Document) DelChar(at *gilo.Point) {
d.rows[at.Y].deleteRune(at.X) d.rows[at.Y].deleteRune(at.X)
d.dirty = true
} }
func (d *Document) IsDirty() bool { func (d *Document) IsDirty() bool {

View File

@ -1,4 +1,4 @@
package editor package document
import "testing" import "testing"

View File

@ -1,7 +1,8 @@
package editor package document
import ( import (
"strings" "strings"
"timshome.page/gilo/internal/gilo"
) )
type Row struct { type Row struct {
@ -29,6 +30,10 @@ func (r *Row) RenderSize() int {
return len(r.render) return len(r.render)
} }
func (r *Row) Render(at *gilo.Point) string {
return string(r.render[at.X:])
}
func (r *Row) insertRune(ch rune, at int) { func (r *Row) insertRune(ch rune, at int) {
// If insertion index is invalid, just // If insertion index is invalid, just
// append the rune to the end of the array // append the rune to the end of the array
@ -75,7 +80,7 @@ func (r *Row) deleteRune(at int) {
func (r *Row) update() { func (r *Row) update() {
r.render = r.render[:0] r.render = r.render[:0]
replacement := strings.Repeat(" ", KiloTabStop) replacement := strings.Repeat(" ", gilo.TabSize)
str := strings.ReplaceAll(string(r.chars), "\t", replacement) str := strings.ReplaceAll(string(r.chars), "\t", replacement)
for _, ch := range str { for _, ch := range str {
@ -87,13 +92,13 @@ func (r *Row) toString() string {
return string(r.chars) return string(r.chars)
} }
func (r *Row) cursorXToRenderX(cursorX int) int { func (r *Row) CursorXToRenderX(cursorX int) (renderX int) {
renderX := 0 renderX = 0
i := 0 i := 0
for ; i < cursorX; i++ { for ; i < cursorX; i++ {
if r.chars[i] == '\t' { if r.chars[i] == '\t' {
renderX += (KiloTabStop - 1) - (renderX % KiloTabStop) renderX += (gilo.TabSize - 1) - (renderX % gilo.TabSize)
} }
renderX += 1 renderX += 1

View File

@ -1,4 +1,4 @@
package editor package document
import "testing" import "testing"

View File

@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"time" "time"
"timshome.page/gilo/internal/buffer" "timshome.page/gilo/internal/gilo"
"timshome.page/gilo/internal/terminal" "timshome.page/gilo/internal/terminal"
) )
@ -16,7 +16,7 @@ import (
func (e *editor) RefreshScreen() { func (e *editor) RefreshScreen() {
e.scroll() e.scroll()
ab := buffer.NewBuffer() ab := gilo.NewBuffer()
ab.Append(terminal.HideCursor) ab.Append(terminal.HideCursor)
ab.Append(terminal.ResetCursor) ab.Append(terminal.ResetCursor)
@ -36,7 +36,7 @@ func (e *editor) scroll() {
e.renderX = 0 e.renderX = 0
if e.cursor.Y < e.document.RowCount() { if e.cursor.Y < e.document.RowCount() {
e.renderX = e.document.Row(e.cursor.Y).cursorXToRenderX(e.cursor.X) e.renderX = e.document.Row(e.cursor.Y).CursorXToRenderX(e.cursor.X)
} }
if e.cursor.Y < e.offset.Y { if e.cursor.Y < e.offset.Y {
@ -56,7 +56,7 @@ func (e *editor) scroll() {
} }
} }
func (e *editor) drawRows(ab *buffer.Buffer) { func (e *editor) drawRows(ab *gilo.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
@ -74,7 +74,7 @@ func (e *editor) drawRows(ab *buffer.Buffer) {
} }
rowLen := e.document.Row(fileRow).RenderSize() - e.offset.X rowLen := e.document.Row(fileRow).RenderSize() - e.offset.X
outputRow := truncate(string(e.document.Row(fileRow).render[e.offset.X:]), rowLen) outputRow := truncate(e.document.Row(fileRow).Render(e.offset), rowLen)
ab.Append(outputRow) ab.Append(outputRow)
} }
@ -82,9 +82,9 @@ func (e *editor) drawRows(ab *buffer.Buffer) {
} }
} }
func (e *editor) drawPlaceholderRow(y int, ab *buffer.Buffer) { func (e *editor) drawPlaceholderRow(y int, ab *gilo.Buffer) {
if e.document.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", gilo.Version)
if len(welcome) > e.screen.Cols { if len(welcome) > e.screen.Cols {
welcome = truncate(welcome, e.screen.Cols) welcome = truncate(welcome, e.screen.Cols)
} }
@ -106,17 +106,17 @@ func (e *editor) drawPlaceholderRow(y int, ab *buffer.Buffer) {
} }
} }
func (e *editor) drawStatusBar(ab *buffer.Buffer) { func (e *editor) drawStatusBar(ab *gilo.Buffer) {
cols := e.screen.Cols cols := e.screen.Cols
ab.Append(terminal.InvertColor) ab.Append(terminal.InvertColor)
fileName := "[No Name]" fileName := "[No Name]"
if e.document.filename != "" { if e.document.Filename != "" {
fileName = e.document.filename fileName = e.document.Filename
} }
modified := "" modified := ""
if e.document.dirty { if e.document.IsDirty() {
modified = "(modified)" modified = "(modified)"
} }
@ -157,7 +157,7 @@ func (e *editor) drawStatusBar(ab *buffer.Buffer) {
ab.Append(terminal.ResetColor) ab.Append(terminal.ResetColor)
} }
func (e *editor) drawMessageBar(ab *buffer.Buffer) { func (e *editor) drawMessageBar(ab *gilo.Buffer) {
ab.Append("\r\n") ab.Append("\r\n")
ab.Append(terminal.ClearLine) ab.Append(terminal.ClearLine)

View File

@ -4,6 +4,7 @@ package editor
import ( import (
"fmt" "fmt"
"time" "time"
doc "timshome.page/gilo/internal/editor/document"
"timshome.page/gilo/internal/gilo" "timshome.page/gilo/internal/gilo"
"timshome.page/gilo/internal/terminal" "timshome.page/gilo/internal/terminal"
) )
@ -21,13 +22,13 @@ type editor struct {
screen *terminal.Screen screen *terminal.Screen
cursor *gilo.Point cursor *gilo.Point
offset *gilo.Point offset *gilo.Point
document *Document document *doc.Document
status *statusMsg status *statusMsg
quitTimes uint8 quitTimes uint8
renderX int renderX int
} }
func New() *editor { func NewEditor() *editor {
screen := terminal.Size() screen := terminal.Size()
// Subtract rows for status bar and message bar/prompt // Subtract rows for status bar and message bar/prompt
@ -35,7 +36,7 @@ func New() *editor {
cursor := gilo.DefaultPoint() cursor := gilo.DefaultPoint()
offset := gilo.DefaultPoint() offset := gilo.DefaultPoint()
document := NewDocument() document := doc.NewDocument()
status := &statusMsg{ status := &statusMsg{
"", "",
time.Now(), time.Now(),
@ -47,7 +48,7 @@ func New() *editor {
offset, offset,
document, document,
status, status,
KiloQuitTimes, gilo.QuitTimes,
0, 0,
} }
} }
@ -84,9 +85,8 @@ func (e *editor) insertChar(ch rune) {
e.document.AppendRow("") e.document.AppendRow("")
} }
e.document.Row(e.cursor.Y).insertRune(ch, e.cursor.X) e.document.InsertChar(e.cursor, ch)
e.cursor.X += 1 e.cursor.X += 1
e.document.dirty = true
} }
func (e *editor) delChar() { func (e *editor) delChar() {
@ -95,9 +95,10 @@ func (e *editor) delChar() {
} }
if e.cursor.X > 0 { if e.cursor.X > 0 {
e.document.Row(e.cursor.Y).deleteRune(e.cursor.X - 1) at := e.cursor
at.X -= 1
e.document.DelChar(at)
e.cursor.X -= 1 e.cursor.X -= 1
} }
e.document.dirty = true
} }

View File

@ -3,7 +3,7 @@ package editor
import "testing" import "testing"
func TestNew(t *testing.T) { func TestNew(t *testing.T) {
e := New() e := NewEditor()
if e == nil { if e == nil {
t.Errorf("Failed to create editor") t.Errorf("Failed to create editor")
@ -11,7 +11,7 @@ func TestNew(t *testing.T) {
} }
func TestInsertChar(t *testing.T) { func TestInsertChar(t *testing.T) {
e := New() e := NewEditor()
e.insertChar('q') e.insertChar('q')
if e.document.RowCount() != 1 { if e.document.RowCount() != 1 {

View File

@ -1,17 +1,35 @@
package editor package editor
import ( import (
"timshome.page/gilo/internal/editor/document"
"timshome.page/gilo/internal/gilo"
"timshome.page/gilo/internal/key" "timshome.page/gilo/internal/key"
"timshome.page/gilo/internal/terminal" "timshome.page/gilo/internal/terminal"
) )
// ----------------------------------------------------------------------------
// !Constants representing input keys
// ----------------------------------------------------------------------------
const (
keyUp = "ARROW_UP"
keyDown = "ARROW_DOWN"
keyLeft = "ARROW_LEFT"
keyRight = "ARROW_RIGHT"
keyPageUp = "PAGE_UP"
keyPageDown = "PAGE_DOWN"
keyHome = "HOME"
keyEnd = "END"
keyDelete = "DELETE"
)
/** /**
* Determine what to do with an individual character of input * Determine what to do with an individual character of input
*/ */
func (e *editor) processKeypressChar(ch rune) bool { func (e *editor) processKeypressChar(ch rune) bool {
switch ch { switch ch {
case key.Ctrl('q'): case key.Ctrl('q'):
if e.document.dirty && e.quitTimes > 0 { if e.document.IsDirty() && e.quitTimes > 0 {
e.SetStatusMessage("WARNING!!! File has unsaved changes. Press Ctrl-Q %d more tiems to quite.", e.quitTimes) e.SetStatusMessage("WARNING!!! File has unsaved changes. Press Ctrl-Q %d more tiems to quite.", e.quitTimes)
e.quitTimes -= 1 e.quitTimes -= 1
@ -50,8 +68,8 @@ func (e *editor) processKeypressChar(ch rune) bool {
// Clear the quit message and restart the // Clear the quit message and restart the
// confirmation count if confirmation is not // confirmation count if confirmation is not
// completed // completed
if e.quitTimes != KiloQuitTimes { if e.quitTimes != gilo.QuitTimes {
e.quitTimes = KiloQuitTimes e.quitTimes = gilo.QuitTimes
e.SetStatusMessage("") e.SetStatusMessage("")
} }
@ -81,7 +99,7 @@ func (e *editor) processKeypressStr(key string) {
} }
func (e *editor) moveCursor(key string) { func (e *editor) moveCursor(key string) {
var row *Row var row *document.Row
if e.cursor.Y >= e.document.RowCount() { if e.cursor.Y >= e.document.RowCount() {
row = nil row = nil
} else { } else {

View File

@ -24,7 +24,7 @@ var cursorTests = []moveCursor{
func TestMoveCursor(t *testing.T) { func TestMoveCursor(t *testing.T) {
for _, test := range cursorTests { for _, test := range cursorTests {
e := New() e := NewEditor()
if test.withFile { if test.withFile {
e.Open("editor.go") e.Open("editor.go")

View File

@ -1,4 +1,4 @@
package buffer package gilo
import ( import (
"fmt" "fmt"

View File

@ -1,4 +1,4 @@
package buffer package gilo
import "testing" import "testing"

View File

@ -0,0 +1,11 @@
package gilo
// ----------------------------------------------------------------------------
// !General Constants
// ----------------------------------------------------------------------------
const (
Version = "0.0.1"
TabSize = 4
QuitTimes = 3
)