github.com/opentofu/opentofu@v1.7.1/internal/command/autocomplete.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package command 7 8 import ( 9 "github.com/posener/complete" 10 ) 11 12 // This file contains some re-usable predictors for auto-complete. The 13 // command-specific autocomplete configurations live within each command's 14 // own source file, as AutocompleteArgs and AutocompleteFlags methods on each 15 // Command implementation. 16 17 // For completing the value of boolean flags like -foo false 18 var completePredictBoolean = complete.PredictSet("true", "false") 19 20 // We don't currently have a real predictor for module sources, but 21 // we'll probably add one later. 22 var completePredictModuleSource = complete.PredictAnything 23 24 type completePredictSequence []complete.Predictor 25 26 func (s completePredictSequence) Predict(a complete.Args) []string { 27 // Nested subcommands do not require any placeholder entry for their subcommand name. 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 backendConfig, diags := m.loadBackendConfig(configPath) 54 if diags.HasErrors() { 55 return nil 56 } 57 58 // Load the encryption configuration 59 enc, encDiags := m.Encryption() 60 if encDiags.HasErrors() { 61 m.showDiagnostics(encDiags) 62 return nil 63 } 64 65 b, diags := m.Backend(&BackendOpts{ 66 Config: backendConfig, 67 }, enc.State()) 68 if diags.HasErrors() { 69 return nil 70 } 71 72 names, _ := b.Workspaces() 73 return names 74 }) 75 }