54 lines
1.7 KiB
Go
54 lines
1.7 KiB
Go
|
|
package commandkit
|
||
|
|
|
||
|
|
import (
|
||
|
|
"errors"
|
||
|
|
"io"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
internalcobra "gitea.maximumdirect.net/eric/CommandKit/internal/cobra"
|
||
|
|
commandmeta "gitea.maximumdirect.net/eric/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)
|
||
|
|
}
|