2024-12-11 09:47:05 +00:00
|
|
|
package repl
|
|
|
|
|
|
|
|
import (
|
2024-12-11 11:30:14 +00:00
|
|
|
"io"
|
|
|
|
"reflect"
|
|
|
|
"slices"
|
2024-12-11 09:47:05 +00:00
|
|
|
"ucl.lmika.dev/ucl"
|
|
|
|
)
|
|
|
|
|
|
|
|
type CommandOpt interface {
|
|
|
|
config(cmdName string, r *REPL)
|
|
|
|
}
|
|
|
|
|
|
|
|
type REPL struct {
|
|
|
|
inst *ucl.Inst
|
|
|
|
|
2024-12-11 11:30:14 +00:00
|
|
|
commandDocs map[string]Doc
|
|
|
|
typePrinters map[reflect.Type]func(w io.Writer, v any, brief bool) error
|
2024-12-11 09:47:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func New(opts ...ucl.InstOption) *REPL {
|
|
|
|
r := &REPL{
|
2024-12-11 11:30:14 +00:00
|
|
|
commandDocs: make(map[string]Doc),
|
|
|
|
typePrinters: make(map[reflect.Type]func(w io.Writer, v any, brief bool) error),
|
2024-12-11 09:47:05 +00:00
|
|
|
}
|
2024-12-11 11:30:14 +00:00
|
|
|
|
|
|
|
instOpts := append(slices.Clone(opts), ucl.WithCustomEchoPrinter(r.echoPrinter))
|
|
|
|
r.inst = ucl.New(instOpts...)
|
|
|
|
|
2024-12-11 10:16:08 +00:00
|
|
|
r.SetCommand("help", r.helpBuiltin, Doc{
|
|
|
|
Brief: "displays help about a command",
|
2024-12-11 10:23:53 +00:00
|
|
|
Usage: "[command]",
|
|
|
|
Args: []ArgDoc{
|
|
|
|
{Name: "command", Brief: "command to display detailed help for"},
|
|
|
|
},
|
2024-12-11 10:16:08 +00:00
|
|
|
Detailed: `
|
|
|
|
When used without arguments, 'help' will display the list of known commands,
|
|
|
|
along with a brief description on what each one does.
|
|
|
|
|
|
|
|
When used with an argument, 'help' will display a more detailed explanation
|
|
|
|
of what each command does.
|
|
|
|
`,
|
|
|
|
})
|
2024-12-11 09:47:05 +00:00
|
|
|
|
2024-12-11 11:30:14 +00:00
|
|
|
AddTypePrinter(r, func(w io.Writer, t NoResults, concise bool) error { return nil })
|
|
|
|
|
2024-12-11 09:47:05 +00:00
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *REPL) Inst() *ucl.Inst {
|
|
|
|
return r.inst
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *REPL) SetCommand(name string, fn ucl.BuiltinHandler, opts ...CommandOpt) {
|
|
|
|
r.commandDocs[name] = Doc{}
|
|
|
|
for _, opt := range opts {
|
|
|
|
opt.config(name, r)
|
|
|
|
}
|
|
|
|
|
|
|
|
r.inst.SetBuiltin(name, fn)
|
|
|
|
}
|