From bb6f7764a1a83576804005b9a9697c8999eed233 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Wed, 24 Mar 2021 15:09:28 -0400 Subject: [PATCH] Use buffer for creating output --- internal/ansi/ansi.go | 10 +++++ internal/editor/editor.go | 85 +++++++++++++++++++++++++---------- internal/terminal/terminal.go | 37 +++++---------- 3 files changed, 83 insertions(+), 49 deletions(-) create mode 100644 internal/ansi/ansi.go diff --git a/internal/ansi/ansi.go b/internal/ansi/ansi.go new file mode 100644 index 0000000..37b66e9 --- /dev/null +++ b/internal/ansi/ansi.go @@ -0,0 +1,10 @@ +package ansi + +import "fmt" + +const ClearScreen = "\x1b[2J" +const ResetCursor = "\x1b[H" + +func Code (s string) string { + return fmt.Sprintf("\x1b[%s", s) +} \ No newline at end of file diff --git a/internal/editor/editor.go b/internal/editor/editor.go index a7b63f8..65d0b11 100644 --- a/internal/editor/editor.go +++ b/internal/editor/editor.go @@ -1,32 +1,39 @@ package editor import ( + "fmt" + "strings" + "timshome.page/gilo/internal/ansi" "timshome.page/gilo/internal/char" "timshome.page/gilo/internal/terminal" ) +// ---------------------------------------------------------------------------- +// !Editor +// ---------------------------------------------------------------------------- + type editor struct { rows int cols int } func New() *editor { - cols, rows := terminal.Size() + rows, cols := terminal.Size() - e := new(editor) - e.cols = cols - e.rows = rows - - return e + return &editor{rows, cols} } func (e *editor) RefreshScreen() { - terminal.ANSICode(terminal.ClearScreen) - terminal.ANSICode(terminal.ResetCursor) + ab := newBuffer() - e.drawRows() + ab.append(ansi.ClearScreen) + ab.append(ansi.ResetCursor) - terminal.ANSICode(terminal.ResetCursor) + e.drawRows(ab) + + ab.append(ansi.ResetCursor) + + terminal.Write(ab.toString()) } func (e *editor) ProcessKeypress() bool { @@ -34,29 +41,61 @@ func (e *editor) ProcessKeypress() bool { // Clean up on exit if ch == char.Ctrl('q') { - terminal.ANSICode(terminal.ClearScreen) - terminal.ANSICode(terminal.ResetCursor) + terminal.Write(ansi.ClearScreen) + terminal.Write(ansi.ResetCursor) return false } - // Ugliest syntax structure ever? - switch { - case char.IsCtrl(ch): - terminal.WriteLn("%d", ch) - default: - terminal.WriteLn("%d ('%c')", ch, ch) - } - return true } -func (e *editor) drawRows() { +func (e *editor) drawRows(ab *buffer) { for y :=0; y < e.rows; y += 1 { - terminal.Write("~") + ab.appendRune('~') if y < (e.rows - 1) { - terminal.Write("\r\n") + ab.append("\r\n") } } } + +// ---------------------------------------------------------------------------- +// !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/internal/terminal/terminal.go b/internal/terminal/terminal.go index c0638cc..dafe9c5 100644 --- a/internal/terminal/terminal.go +++ b/internal/terminal/terminal.go @@ -8,9 +8,6 @@ import ( "golang.org/x/term" ) -const ClearScreen = "2J" -const ResetCursor = "H" - var reader = bufio.NewReader(os.Stdin) func ReadKey() (rune, int) { @@ -49,10 +46,6 @@ func RawOff(oldState *term.State) { } } -func ANSICode (code string) { - fmt.Printf("\x1b[%s", code) -} - func sizeTrick () (rows int, cols int) { // Move cursor to location further than likely screen size // The cursor will move to maximum available position @@ -84,32 +77,24 @@ func sizeTrick () (rows int, cols int) { return rows, cols } -func Size () (width int, height int) { - width = 80 - height = 24 +// Get the size of the terminal in rows and columns +func Size () (rows int, cols int) { + cols = 80 + rows = 24 // Try the syscall first - width, height, err := term.GetSize(int(os.Stdin.Fd())) + cols, rows, err := term.GetSize(int(os.Stdin.Fd())) if err == nil { - return width, height + return rows, cols } // Figure out the size the hard way - height, width = sizeTrick() + rows, cols = sizeTrick() - WriteLn("%d Rows, %d Cols", height, width) - - return width, height + return rows, cols } - -// Print a formatted string to stdout, with CRLF line endings for proper terminal formatting -func WriteLn(format string, a ...interface{}) { - formatted := fmt.Sprintf(format, a...) - - fmt.Printf("%s\r\n", formatted) -} - -func Write(format string, a ...interface{}) { - fmt.Printf(format, a...) +// Print string to stdout +func Write(s string) { + fmt.Print(s) }