Skip to content

Commit

Permalink
add cmdPrint and implement io.ReadFrom and io.WriteTo for Buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
eckertalex committed Nov 14, 2024
1 parent ee69973 commit 619850b
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 38 deletions.
54 changes: 49 additions & 5 deletions cmd/edgo/buffer.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
package main

import (
"bufio"
"fmt"
"io"
"slices"
)

type BufferIO interface {
io.ReaderFrom
io.WriterTo
}

// Compile-time check to ensure Buffer implements BufferIO
var _ BufferIO = (*Buffer)(nil)

type Buffer struct {
lines []string
modified bool
index int
lines []string
index int
}

func NewBuffer() *Buffer {
Expand All @@ -16,13 +26,47 @@ func NewBuffer() *Buffer {
}
}

func (b *Buffer) Clear() {
func (b *Buffer) ReadFrom(r io.Reader) (int64, error) {
b.lines = b.lines[:0]
b.modified = false
b.index = 0

var bytesRead int64
scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := scanner.Text()
b.lines = append(b.lines, line)
b.index++
bytesRead += int64(len(line) + 1)
}

if err := scanner.Err(); err != nil {
return bytesRead, err
}

return bytesRead, nil
}

func (b *Buffer) WriteTo(w io.Writer) (int64, error) {
var bytesWritten int64
for _, line := range b.lines {
n, err := fmt.Fprintln(w, line)
bytesWritten += int64(n)
if err != nil {
return bytesWritten, err
}
}
return bytesWritten, nil
}

func (b *Buffer) Append(line string) {
b.lines = slices.Insert(b.lines, b.index, line)
b.index++
}

func (b *Buffer) Current() string {
if len(b.lines) == 0 {
return ""
}

return b.lines[b.index-1]
}
13 changes: 11 additions & 2 deletions cmd/edgo/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,17 @@ func parseCommand(input string) Command {
args := parts[1:]

validCommands := map[string]bool{
"w": true, "e": true, "P": true, "p": true, "q": true, "x": true,
"Q": true, ".": true, "$": true, "+": true, "-": true,
"P": true,
"h": true,
"H": true,
"e": true,
"p": true,
"n": true,
".": true,
"$": true,
"w": true,
"q": true,
"Q": true,
}

if validCommands[name] {
Expand Down
11 changes: 6 additions & 5 deletions cmd/edgo/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ func TestParseCommand(t *testing.T) {
expected Command
}{
{"P", Command{name: "P", args: []string{}}},
{"h", Command{name: "h", args: []string{}}},
{"H", Command{name: "H", args: []string{}}},
{"e", Command{name: "e", args: []string{}}},
{"p", Command{name: "p", args: []string{}}},
{"q", Command{name: "q", args: []string{}}},
{"x", Command{name: "x", args: []string{}}},
{"Q", Command{name: "Q", args: []string{}}},
{"n", Command{name: "n", args: []string{}}},
{".", Command{name: ".", args: []string{}}},
{"$", Command{name: "$", args: []string{}}},
{"+", Command{name: "+", args: []string{}}},
{"-", Command{name: "-", args: []string{}}},
{"q", Command{name: "q", args: []string{}}},
{"Q", Command{name: "Q", args: []string{}}},

{"w filename.txt", Command{name: "w", args: []string{"filename.txt"}}},
{"e filename.txt", Command{name: "e", args: []string{"filename.txt"}}},
Expand Down
55 changes: 31 additions & 24 deletions cmd/edgo/commands.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"bufio"
"fmt"
"os"
"path/filepath"
Expand All @@ -17,53 +16,61 @@ func (ed *Editor) cmdTogglePrompt() error {
return nil
}

func (ed *Editor) cmdToggleShowFullError() error {
ed.isFullErrorShown = !ed.isFullErrorShown

if ed.isFullErrorShown {
ed.cmdShowLastError()
}

return nil
}

func (ed *Editor) cmdShowLastError() error {
if ed.lastError != nil {
fmt.Fprintln(ed.writer, ed.lastError)
}
return nil
}

func (ed *Editor) cmdEdit(filename string) error {
func (ed *Editor) cmdToggleShowFullError() error {
var err error

ed.isFullErrorShown = !ed.isFullErrorShown
if ed.isFullErrorShown {
err = ed.cmdShowLastError()
}

return err
}

func (ed *Editor) cmdRead(filename string) error {
ed.filename = filepath.ToSlash(filename)

stat, err := os.Stat(ed.filename)
_, err := os.Stat(ed.filename)
if os.IsNotExist(err) {
fmt.Fprintf(os.Stdout, "%s: No such file or directory\n", ed.filename)
fmt.Fprintf(os.Stdout, "%s: No such file or directory\n", filename)
return nil
}

if err != nil {
return fmt.Errorf("error stating file: %w", err)
}

ed.buffer.Clear()
fmt.Fprintf(os.Stdout, "%d\n", stat.Size())

file, err := os.Open(ed.filename)
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()

scanner := bufio.NewScanner(file)
for scanner.Scan() {
ed.buffer.Append(scanner.Text())
}

if err := scanner.Err(); err != nil {
bytesRead, err := ed.buffer.ReadFrom(file)
if err != nil {
return err
}
fmt.Fprintf(ed.writer, "%d\n", bytesRead)

return nil
}

func (ed *Editor) cmdPrint(showLineNumber bool) error {
var err error

currentLine := ed.buffer.Current()
if showLineNumber {
_, err = fmt.Fprintf(ed.writer, "%d\t%s\n", ed.buffer.index, currentLine)
} else {
_, err = fmt.Fprintf(ed.writer, "%s\n", currentLine)
}

return err
}
12 changes: 11 additions & 1 deletion cmd/edgo/editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,17 @@ func (ed *Editor) executeCommand(cmd Command) {
case "H":
err = ed.cmdToggleShowFullError()
case "e":
err = ed.cmdEdit(cmd.name)
err = ed.cmdRead(cmd.args[0])
case "p":
err = ed.cmdPrint(false)
case "n":
err = ed.cmdPrint(true)
case ".":
err = ed.cmdPrint(false)
case "$":
fmt.Fprintln(ed.writer, "TODO")
case "w":
fmt.Fprintln(ed.writer, "TODO")
case "q":
err = ed.cmdQuit()
case "Q":
Expand Down
2 changes: 1 addition & 1 deletion cmd/edgo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func main() {
ed := NewEditor(os.Stdin, os.Stdout, prompt, isPromptShown)

if flag.NArg() == 1 {
ed.cmdEdit(flag.Arg(0))
ed.cmdRead(flag.Arg(0))
}

if err := ed.Run(); err != nil {
Expand Down

0 comments on commit 619850b

Please sign in to comment.