Moved the REPL thing to its own package

This commit is contained in:
2026-01-03 21:48:18 +00:00
parent 6a988c2b62
commit 785db2a59b
6 changed files with 6 additions and 200 deletions
+2 -1
View File
@@ -2,10 +2,11 @@ package cmd
import (
"esdi/peripheral"
"esdi/repl"
"fmt"
"strconv"
repl "github.com/ESilva15/ESgoRepl"
"github.com/spf13/cobra"
)
+2 -1
View File
@@ -1,8 +1,9 @@
module esdi
go 1.23.2
go 1.25.5
require (
github.com/ESilva15/ESgoRepl v0.1.0
github.com/ESilva15/gobngsdk v0.0.2
github.com/ESilva15/goirsdk v0.2.0
github.com/spf13/cobra v1.8.1
+2
View File
@@ -1,3 +1,5 @@
github.com/ESilva15/ESgoRepl v0.1.0 h1:hOVcRBfdP8Yw1kLr2tFoM3SetV7vxFswKjzfAtq8UgM=
github.com/ESilva15/ESgoRepl v0.1.0/go.mod h1:O2JQMyEgHy0zf9UvzvLNvp2w95T2uazc3torrzRmG9Y=
github.com/ESilva15/gobngsdk v0.0.2 h1:N6stNOE14Wg80BAZMFu/Qd9Qa/J0DmExCfdPoDf7lco=
github.com/ESilva15/gobngsdk v0.0.2/go.mod h1:cKLaZRgM0tGGXDvosaSjHnxeyC5Y6rg7zCLqEUJnOzw=
github.com/ESilva15/goirsdk v0.2.0 h1:zmtYyH3ayGRcDfzzLrJmEpX6zdmCHTUqbs4tnV2hXmI=
-42
View File
@@ -1,42 +0,0 @@
package repl
import (
"fmt"
"os"
)
var (
helpCmd = Command{
Name: ".help",
Usage: " type `.help` for help",
Action: func(r *REPL, args []string) error {
for _, cmd := range r.Commands {
fmt.Printf("%-20s\t%s\n", cmd.Name, cmd.Usage)
}
return nil
},
}
clearCmd = Command{
Name: ".clear",
Usage: " type `.clear` to clear the screen",
Action: func(r *REPL, args []string) error {
_, _ = os.Stdout.Write([]byte("\033[2J\033[H"))
return nil
},
}
exitCmd = Command{
Name: ".exit",
Usage: " type `.exit` to exit this REPL",
Action: func(r *REPL, args []string) error {
r.Stop = true
return nil
},
}
)
type Command struct {
Name string
Usage string
Action func(r *REPL, args []string) error
}
-9
View File
@@ -1,9 +0,0 @@
package repl
import (
"strings"
)
func parseInput(args string) []string {
return strings.Split(args, " ")
}
-147
View File
@@ -1,147 +0,0 @@
// Package repl Basic UI for the user
package repl
import (
"bufio"
"fmt"
"io"
"os"
"strings"
)
var DefaultCfg = REPLCfg{
PS1: "\r> ",
}
type REPLCfg struct {
PS1 string
}
type REPL struct {
Stop bool
Cfg REPLCfg
Commands map[string]Command
}
func NewREPL(cfg REPLCfg) *REPL {
return &REPL{
Cfg: cfg,
Commands: map[string]Command{
helpCmd.Name: helpCmd,
clearCmd.Name: clearCmd,
exitCmd.Name: exitCmd,
},
}
}
func (r *REPL) Close() {
// Do whatever cleanup we have to do
}
func (r *REPL) RegisterCMD(newCMD Command) {
// Add a verification to check that the command doesn't exist. Fatal if it does
r.Commands[newCMD.Name] = newCMD
}
func (r *REPL) printPrompt() {
_, _ = os.Stdout.Write([]byte(r.Cfg.PS1))
}
func (r *REPL) SetPS1(s string) {
r.Cfg.PS1 = s
}
func parseArgs(l string) ([]string, error) {
args := []string{}
input := strings.TrimSpace(l)
type ArgParserState uint8
const (
readingQuotedStr ArgParserState = iota
readingNormalStr
storeArg
)
curState := readingNormalStr
curStr := []byte{}
for k := 0; k < len(input); {
switch curState {
case readingNormalStr:
switch input[k] {
case '"':
curState = readingQuotedStr
case ' ':
curState = storeArg
default:
curStr = append(curStr, input[k])
}
k++
case readingQuotedStr:
switch input[k] {
case '"':
if k+1 < len(input) {
k++
}
curState = storeArg
default:
curStr = append(curStr, input[k])
}
k++
case storeArg:
args = append(args, string(curStr))
curStr = nil
curState = readingNormalStr
}
if k == len(input) {
args = append(args, string(curStr))
curStr = nil
}
}
if curState == readingQuotedStr {
return []string{}, fmt.Errorf("quoted string was not closed: %s", curStr)
}
return args, nil
}
func (r *REPL) mainLoop() {
reader := bufio.NewReader(os.Stdin)
for {
r.printPrompt()
line, err := reader.ReadString('\n')
if err != nil {
if err == io.EOF {
break
}
fmt.Println("error: ", err)
continue
}
args, err := parseArgs(line)
if err != nil {
fmt.Printf("%s\n", err.Error())
}
command, exists := r.Commands[args[0]]
if exists {
err = command.Action(r, args[1:])
if err != nil {
fmt.Printf("error: %s\n", err.Error())
}
} else {
fmt.Printf("No such command `%s`\n", args[0])
}
if r.Stop {
break
}
}
}
func (r *REPL) Start() {
// Setup handlers and whatnot
r.mainLoop()
}