From abe228b14d97d8d47e8ff4406de387fac45cfe68 Mon Sep 17 00:00:00 2001 From: Robin Jarry Date: Sun, 22 Oct 2023 23:23:18 +0200 Subject: commands: use completion from go-opt Implement command completion with complete struct field tags from the get-opt library introduced earlier. Changelog-changed: Improved command completion. Signed-off-by: Robin Jarry Reviewed-by: Koni Marti Tested-by: Moritz Poldrack Tested-by: Inwit --- commands/parser.go | 134 ----------------------------------------------------- 1 file changed, 134 deletions(-) delete mode 100644 commands/parser.go (limited to 'commands/parser.go') diff --git a/commands/parser.go b/commands/parser.go deleted file mode 100644 index e8146506..00000000 --- a/commands/parser.go +++ /dev/null @@ -1,134 +0,0 @@ -package commands - -import ( - "strings" -) - -type completionType int - -const ( - NONE completionType = iota - COMMAND - OPERAND - SHORT_OPTION - OPTION_ARGUMENT -) - -type parser struct { - tokens []string - optind int - spec string - space bool - kind completionType - flag string - arg string - err error -} - -func newParser(cmd, spec string, spaceTerminated bool) (*parser, error) { - args, err := splitCmd(cmd) - if err != nil { - return nil, err - } - - p := &parser{ - tokens: args, - optind: 0, - spec: spec, - space: spaceTerminated, - kind: NONE, - flag: "", - arg: "", - err: nil, - } - - state := command - for state != nil { - state = state(p) - } - - return p, p.err -} - -func (p *parser) empty() bool { - return len(p.tokens) == 0 -} - -func (p *parser) peek() string { - return p.tokens[0] -} - -func (p *parser) advance() string { - if p.empty() { - return "" - } - tok := p.tokens[0] - p.tokens = p.tokens[1:] - p.optind++ - return tok -} - -func (p *parser) set(t completionType) { - p.kind = t -} - -func (p *parser) hasArgument() bool { - n := len(p.flag) - if n > 0 { - s := string(p.flag[n-1]) + ":" - return strings.Contains(p.spec, s) - } - return false -} - -type stateFn func(*parser) stateFn - -func command(p *parser) stateFn { - p.set(COMMAND) - p.advance() - return peek(p) -} - -func peek(p *parser) stateFn { - if p.empty() { - if p.space { - return operand - } - return nil - } - if p.spec == "" { - return operand - } - s := p.peek() - switch { - case s == "--": - p.advance() - case strings.HasPrefix(s, "-"): - return short_option - } - return operand -} - -func short_option(p *parser) stateFn { - p.set(SHORT_OPTION) - tok := p.advance() - p.flag = tok[1:] - if p.hasArgument() { - return option_argument - } - return peek(p) -} - -func option_argument(p *parser) stateFn { - p.set(OPTION_ARGUMENT) - p.arg = p.advance() - if p.empty() && len(p.arg) == 0 { - return nil - } - return peek(p) -} - -func operand(p *parser) stateFn { - p.set(OPERAND) - return nil -} -- cgit