Files
esdi/repl/repl.go
T
2025-12-06 22:26:03 +00:00

89 lines
1.4 KiB
Go

// 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 (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 := parseInput(strings.TrimSpace(line))
if args[0] == "" {
continue
}
command, exists := r.Commands[args[0]]
if exists {
_ = command.Action(r, args[1:])
} else {
fmt.Printf("No such command `%s`\n", args[0])
}
if r.Stop {
break
}
}
}
func (r *REPL) Start() {
// Setup handlers and whatnot
r.mainLoop()
}