ucl/repl/repl.go

62 lines
1.4 KiB
Go
Raw Normal View History

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)
}