github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/command/autocomplete.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package command
     5  
     6  import (
     7  	"github.com/posener/complete"
     8  )
     9  
    10  // This file contains some re-usable predictors for auto-complete. The
    11  // command-specific autocomplete configurations live within each command's
    12  // own source file, as AutocompleteArgs and AutocompleteFlags methods on each
    13  // Command implementation.
    14  
    15  // For completing the value of boolean flags like -foo false
    16  var completePredictBoolean = complete.PredictSet("true", "false")
    17  
    18  // We don't currently have a real predictor for module sources, but
    19  // we'll probably add one later.
    20  var completePredictModuleSource = complete.PredictAnything
    21  
    22  type completePredictSequence []complete.Predictor
    23  
    24  func (s completePredictSequence) Predict(a complete.Args) []string {
    25  	// Nested subcommands do not require any placeholder entry for their subcommand name.
    26  	idx := len(a.Completed)
    27  	if idx >= len(s) {
    28  		return nil
    29  	}
    30  
    31  	return s[idx].Predict(a)
    32  }
    33  
    34  func (m *Meta) completePredictWorkspaceName() complete.Predictor {
    35  	return complete.PredictFunc(func(a complete.Args) []string {
    36  		// There are lot of things that can fail in here, so if we encounter
    37  		// any error then we'll just return nothing and not support autocomplete
    38  		// until whatever error is fixed. (The user can't actually see the error
    39  		// here, but other commands should produce a user-visible error before
    40  		// too long.)
    41  
    42  		// We assume here that we want to autocomplete for the current working
    43  		// directory, since we don't have enough context to know where to
    44  		// find any config path argument, and it might be _after_ the argument
    45  		// we're trying to complete here anyway.
    46  		configPath, err := ModulePath(nil)
    47  		if err != nil {
    48  			return nil
    49  		}
    50  
    51  		backendConfig, diags := m.loadBackendConfig(configPath)
    52  		if diags.HasErrors() {
    53  			return nil
    54  		}
    55  
    56  		b, diags := m.Backend(&BackendOpts{
    57  			Config: backendConfig,
    58  		})
    59  		if diags.HasErrors() {
    60  			return nil
    61  		}
    62  
    63  		names, _ := b.Workspaces()
    64  		return names
    65  	})
    66  }