github.com/hooklift/terraform@v0.11.0-beta1.0.20171117000744-6786c1361ffe/command/autocomplete.go (about) 1 package command 2 3 import ( 4 "github.com/posener/complete" 5 "github.com/posener/complete/match" 6 ) 7 8 // This file contains some re-usable predictors for auto-complete. The 9 // command-specific autocomplete configurations live within each command's 10 // own source file, as AutocompleteArgs and AutocompleteFlags methods on each 11 // Command implementation. 12 13 // For completing the value of boolean flags like -foo false 14 var completePredictBoolean = complete.PredictSet("true", "false") 15 16 // We don't currently have a real predictor for module sources, but 17 // we'll probably add one later. 18 var completePredictModuleSource = complete.PredictAnything 19 20 type completePredictSequence []complete.Predictor 21 22 func (s completePredictSequence) Predict(a complete.Args) []string { 23 // Only one level of command is stripped off the prefix of a.Completed 24 // here, so nested subcommands like "workspace new" will need to provide 25 // dummy entries (e.g. complete.PredictNothing) as placeholders for 26 // all but the first subcommand. For example, "workspace new" needs 27 // one placeholder for the argument "new". 28 idx := len(a.Completed) 29 if idx >= len(s) { 30 return nil 31 } 32 33 return s[idx].Predict(a) 34 } 35 36 func (m *Meta) completePredictWorkspaceName() complete.Predictor { 37 return complete.PredictFunc(func(a complete.Args) []string { 38 // There are lot of things that can fail in here, so if we encounter 39 // any error then we'll just return nothing and not support autocomplete 40 // until whatever error is fixed. (The user can't actually see the error 41 // here, but other commands should produce a user-visible error before 42 // too long.) 43 44 // We assume here that we want to autocomplete for the current working 45 // directory, since we don't have enough context to know where to 46 // find any config path argument, and it might be _after_ the argument 47 // we're trying to complete here anyway. 48 configPath, err := ModulePath(nil) 49 if err != nil { 50 return nil 51 } 52 53 cfg, err := m.Config(configPath) 54 if err != nil { 55 return nil 56 } 57 58 b, err := m.Backend(&BackendOpts{ 59 Config: cfg, 60 }) 61 if err != nil { 62 return nil 63 } 64 65 names, _ := b.States() 66 67 if a.Last != "" { 68 // filter for names that match the prefix only 69 filtered := make([]string, 0, len(names)) 70 for _, name := range names { 71 if match.Prefix(name, a.Last) { 72 filtered = append(filtered, name) 73 } 74 } 75 names = filtered 76 } 77 return names 78 }) 79 }