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  }