github.com/vlad2095/complete@v1.1.2/args.go (about) 1 package complete 2 3 import ( 4 "os" 5 "path/filepath" 6 "strings" 7 "unicode" 8 ) 9 10 // Args describes command line arguments 11 type Args struct { 12 // All lists of all arguments in command line (not including the command itself) 13 All []string 14 // Completed lists of all completed arguments in command line, 15 // If the last one is still being typed - no space after it, 16 // it won't appear in this list of arguments. 17 Completed []string 18 // Last argument in command line, the one being typed, if the last 19 // character in the command line is a space, this argument will be empty, 20 // otherwise this would be the last word. 21 Last string 22 // LastCompleted is the last argument that was fully typed. 23 // If the last character in the command line is space, this would be the 24 // last word, otherwise, it would be the word before that. 25 LastCompleted string 26 } 27 28 // Directory gives the directory of the current written 29 // last argument if it represents a file name being written. 30 // in case that it is not, we fall back to the current directory. 31 func (a Args) Directory() string { 32 if info, err := os.Stat(a.Last); err == nil && info.IsDir() { 33 return fixPathForm(a.Last, a.Last) 34 } 35 dir := filepath.Dir(a.Last) 36 if info, err := os.Stat(dir); err != nil || !info.IsDir() { 37 return "./" 38 } 39 return fixPathForm(a.Last, dir) 40 } 41 42 func newArgs(line string) Args { 43 var ( 44 all []string 45 completed []string 46 ) 47 parts := splitFields(line) 48 if len(parts) > 0 { 49 all = parts[1:] 50 completed = removeLast(parts[1:]) 51 } 52 return Args{ 53 All: all, 54 Completed: completed, 55 Last: last(parts), 56 LastCompleted: last(completed), 57 } 58 } 59 60 func splitFields(line string) []string { 61 parts := strings.Fields(line) 62 if len(line) > 0 && unicode.IsSpace(rune(line[len(line)-1])) { 63 parts = append(parts, "") 64 } 65 parts = splitLastEqual(parts) 66 return parts 67 } 68 69 func splitLastEqual(line []string) []string { 70 if len(line) == 0 { 71 return line 72 } 73 parts := strings.Split(line[len(line)-1], "=") 74 return append(line[:len(line)-1], parts...) 75 } 76 77 func (a Args) from(i int) Args { 78 if i > len(a.All) { 79 i = len(a.All) 80 } 81 a.All = a.All[i:] 82 83 if i > len(a.Completed) { 84 i = len(a.Completed) 85 } 86 a.Completed = a.Completed[i:] 87 return a 88 } 89 90 func removeLast(a []string) []string { 91 if len(a) > 0 { 92 return a[:len(a)-1] 93 } 94 return a 95 } 96 97 func last(args []string) string { 98 if len(args) == 0 { 99 return "" 100 } 101 return args[len(args)-1] 102 }