80 lines
2.4 KiB
Go
80 lines
2.4 KiB
Go
package command
|
|
|
|
import (
|
|
"github.com/posener/complete"
|
|
"github.com/posener/complete/match"
|
|
)
|
|
|
|
// This file contains some re-usable predictors for auto-complete. The
|
|
// command-specific autocomplete configurations live within each command's
|
|
// own source file, as AutocompleteArgs and AutocompleteFlags methods on each
|
|
// Command implementation.
|
|
|
|
// For completing the value of boolean flags like -foo false
|
|
var completePredictBoolean = complete.PredictSet("true", "false")
|
|
|
|
// We don't currently have a real predictor for module sources, but
|
|
// we'll probably add one later.
|
|
var completePredictModuleSource = complete.PredictAnything
|
|
|
|
type completePredictSequence []complete.Predictor
|
|
|
|
func (s completePredictSequence) Predict(a complete.Args) []string {
|
|
// Only one level of command is stripped off the prefix of a.Completed
|
|
// here, so nested subcommands like "workspace new" will need to provide
|
|
// dummy entries (e.g. complete.PredictNothing) as placeholders for
|
|
// all but the first subcommand. For example, "workspace new" needs
|
|
// one placeholder for the argument "new".
|
|
idx := len(a.Completed)
|
|
if idx >= len(s) {
|
|
return nil
|
|
}
|
|
|
|
return s[idx].Predict(a)
|
|
}
|
|
|
|
func (m *Meta) completePredictWorkspaceName() complete.Predictor {
|
|
return complete.PredictFunc(func(a complete.Args) []string {
|
|
// There are lot of things that can fail in here, so if we encounter
|
|
// any error then we'll just return nothing and not support autocomplete
|
|
// until whatever error is fixed. (The user can't actually see the error
|
|
// here, but other commands should produce a user-visible error before
|
|
// too long.)
|
|
|
|
// We assume here that we want to autocomplete for the current working
|
|
// directory, since we don't have enough context to know where to
|
|
// find any config path argument, and it might be _after_ the argument
|
|
// we're trying to complete here anyway.
|
|
configPath, err := ModulePath(nil)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
cfg, err := m.Config(configPath)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
b, err := m.Backend(&BackendOpts{
|
|
Config: cfg,
|
|
})
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
names, _ := b.States()
|
|
|
|
if a.Last != "" {
|
|
// filter for names that match the prefix only
|
|
filtered := make([]string, 0, len(names))
|
|
for _, name := range names {
|
|
if match.Prefix(name, a.Last) {
|
|
filtered = append(filtered, name)
|
|
}
|
|
}
|
|
names = filtered
|
|
}
|
|
return names
|
|
})
|
|
}
|