github.com/alexaandru/terraform@v0.11.1-0.20171120185746-28632790b723/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  }