github.com/posener/flag@v0.0.0-20170525115107-e8c69325eea7/complete.go (about) 1 package flag 2 3 import ( 4 gflag "flag" 5 "fmt" 6 "strings" 7 ) 8 9 // Complete tries to complete the command line that was already 10 // entered. It returns true on success, on which the main program 11 // should exit 12 func Complete() bool { 13 return CommandLine.Complete() 14 } 15 16 // Complete tries to complete the command line according to a FlagSet. 17 // It returns true on success, on which the main program should exit. 18 func (f *FlagSet) Complete() bool { 19 l := readLine() 20 if l == nil { 21 return cli.Run() 22 } 23 24 options := f.complete(l) 25 26 for _, option := range options { 27 fmt.Println(option) 28 } 29 return true 30 } 31 32 func (f *FlagSet) complete(line *line) []string { 33 var options []string 34 35 // flag completion according to last completed argument in command line 36 if flg := f.lastFlag(line.lastCompleted); flg != nil { 37 if cmp, ok := flg.Value.(Completer); ok { 38 // last flag implements the Completer interface, complete according 39 // to its decision 40 var only bool 41 options, only = cmp.Complete(line.last) 42 if only { 43 return options 44 } 45 } else { 46 // standard library flag, we want to return an empty 47 // choice of completion, since anything can come after this 48 // kind of flag, and we should not complete any other 49 // flags after it. 50 return []string{} 51 } 52 } 53 54 // add all flag names to the complete options 55 f.VisitAll(func(flg *gflag.Flag) { 56 name := "-" + flg.Name 57 if strings.HasPrefix(name, line.last) { 58 options = append(options, name) 59 } 60 }) 61 return options 62 } 63 64 func (f *FlagSet) lastFlag(lastCompleted string) *gflag.Flag { 65 if !strings.HasPrefix(lastCompleted, "-") { 66 return nil 67 } 68 return f.Lookup(lastCompleted[1:]) 69 } 70 71 // Completer interface is for the Complete function 72 type Completer interface { 73 // Complete according to the given last string in the command line. 74 // returns list of options to complete the last word in the command 75 // line, and a boolean indicating if those options should be the 76 // only shown options. 77 Complete(last string) (options []string, only bool) 78 } 79 80 // CompleteFn is function implementing the Completer interface 81 type CompleteFn func(string) ([]string, bool) 82 83 // Complete implements the Complete interface 84 func (c CompleteFn) Complete(last string) ([]string, bool) { 85 if c == nil { 86 return nil, false 87 } 88 return c(last) 89 }