Files
commandkit/completion_query.go

54 lines
1.7 KiB
Go

package commandkit
import (
"errors"
"io"
"strings"
internalcobra "go.maximumdirect.net/commandkit/internal/cobra"
commandmeta "go.maximumdirect.net/commandkit/internal/commandmeta"
)
func completeRequest(snapshot *routingSnapshot, words []string) (commandmeta.CompletionResult, error) {
if len(words) == 0 {
return commandmeta.CompletionResult{}, errors.New("completion request has no current word")
}
context := resolveCompletionContext(snapshot, words[:len(words)-1], words[len(words)-1])
target := completionTargetFor(snapshot, context)
result := commandmeta.CompletionResult{Prefix: target.prefix}
switch target.kind {
case completionTargetCommands, completionTargetFlags:
result.Kind = commandmeta.CompletionChoices
result.Choices = target.choices
case completionTargetValue, completionTargetOperand:
result.Kind = target.hint.Kind
if target.hint.Kind == commandmeta.CompletionChoices {
for _, choice := range target.hint.Choices {
if strings.HasPrefix(choice.Value, target.valuePrefix) {
result.Choices = append(result.Choices, choice)
}
}
}
}
return result, nil
}
func (current *execution) complete(words []string) Outcome {
result, err := completeRequest(current.snapshot, words)
var reply string
if err == nil {
reply, err = internalcobra.CompletionReply(result)
}
if err != nil {
reply = internalcobra.CompletionErrorReply()
}
_ = current.reporter.RenderOutput(func(writer io.Writer) error {
_, writeErr := io.WriteString(writer, reply)
return writeErr
})
if err != nil {
return current.reporter.finalize(Failure("Could not complete the shell request.").WithCause(err), nil)
}
return current.reporter.finalize(Success(), nil)
}