Added help command
This commit is contained in:
parent
5b4e45ff80
commit
e0db900e4e
4 changed files with 120 additions and 28 deletions
87
repl/docs.go
87
repl/docs.go
|
|
@ -1,6 +1,93 @@
|
|||
package repl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/lmika/gopkgs/fp/maps"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
"ucl.lmika.dev/ucl"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type Doc struct {
|
||||
Brief string
|
||||
Detailed string
|
||||
}
|
||||
|
||||
func (d Doc) config(cmdName string, r *REPL) {
|
||||
r.commandDocs[cmdName] = d
|
||||
}
|
||||
|
||||
func (r *REPL) helpBuiltin(ctx context.Context, args ucl.CallArgs) (any, error) {
|
||||
switch {
|
||||
case args.NArgs() == 0:
|
||||
names := maps.Keys(r.commandDocs)
|
||||
sort.Strings(names)
|
||||
|
||||
tabWriter := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
|
||||
|
||||
for _, name := range names {
|
||||
cdoc := r.commandDocs[name]
|
||||
if cdoc.Brief != "" {
|
||||
fmt.Fprintf(tabWriter, "%v\t %v\n", name, r.commandDocs[name].Brief)
|
||||
} else {
|
||||
fmt.Fprintf(tabWriter, "%v\n", name)
|
||||
}
|
||||
}
|
||||
|
||||
tabWriter.Flush()
|
||||
default:
|
||||
var cmdName string
|
||||
if err := args.Bind(&cmdName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
docs, ok := r.commandDocs[cmdName]
|
||||
if !ok {
|
||||
return nil, errors.New("no help docs found for command")
|
||||
}
|
||||
|
||||
fmt.Printf("%v\n", cmdName)
|
||||
fmt.Printf(" %v\n", docs.Brief)
|
||||
|
||||
if docs.Detailed != "" {
|
||||
fmt.Println("")
|
||||
fmt.Println("Details:")
|
||||
|
||||
lines := strings.Split(docs.Detailed, "\n")
|
||||
|
||||
trimLeft := 0
|
||||
if len(lines) == 0 {
|
||||
return nil, nil
|
||||
} else if len(strings.TrimSpace(lines[0])) == 0 && len(lines) > 1 {
|
||||
// indicates that the next line should indicate the indentation
|
||||
trimLeft = len(lines[1]) - len(strings.TrimLeftFunc(lines[1], unicode.IsSpace))
|
||||
lines = lines[1:]
|
||||
}
|
||||
|
||||
for _, line := range lines {
|
||||
fmt.Printf(" %v\n", trimSpaceLeftUpto(line, trimLeft))
|
||||
}
|
||||
}
|
||||
}
|
||||
return NoResults{}, nil
|
||||
}
|
||||
|
||||
func trimSpaceLeftUpto(s string, n int) string {
|
||||
if n == 0 {
|
||||
return s
|
||||
}
|
||||
|
||||
for i, c := range s {
|
||||
if i >= n {
|
||||
return s[i:]
|
||||
} else if !unicode.IsSpace(c) {
|
||||
return s[i:]
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue