Very naive REPL
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
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 {
|
||||
os.Exit(0)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
type Command struct {
|
||||
Name string
|
||||
Usage string
|
||||
Action func(r *REPL, args []string) error
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package repl
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parseInput(args string) []string {
|
||||
return strings.Split(args, " ")
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// Package repl Basic UI for the user
|
||||
package repl
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
var DefaultCfg = REPLCfg{
|
||||
PS1: "\r> ",
|
||||
}
|
||||
|
||||
type REPLCfg struct {
|
||||
PS1 string
|
||||
}
|
||||
|
||||
type REPL struct {
|
||||
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) printPrompt() {
|
||||
_, _ = os.Stdout.Write([]byte(r.Cfg.PS1))
|
||||
}
|
||||
|
||||
func (r *REPL) Start() {
|
||||
reader := bufio.NewScanner(os.Stdin)
|
||||
r.printPrompt()
|
||||
for reader.Scan() {
|
||||
input := reader.Text()
|
||||
args := parseInput(input)
|
||||
|
||||
command, exists := r.Commands[args[0]]
|
||||
if exists {
|
||||
_ = command.Action(r, args[1:])
|
||||
} else {
|
||||
fmt.Printf("No such command `%s`\n", args[0])
|
||||
}
|
||||
|
||||
r.printPrompt()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user