]> git.lizzy.rs Git - micro.git/blob - internal/action/infocomplete.go
Fix test dependencies and travis build
[micro.git] / internal / action / infocomplete.go
1 package action
2
3 import (
4         "bytes"
5         "sort"
6         "strings"
7
8         "github.com/zyedidia/micro/internal/buffer"
9         "github.com/zyedidia/micro/internal/config"
10         "github.com/zyedidia/micro/internal/util"
11 )
12
13 // This file is meant (for now) for autocompletion in command mode, not
14 // while coding. This helps micro autocomplete commands and then filenames
15 // for example with `vsplit filename`.
16
17 // CommandComplete autocompletes commands
18 func CommandComplete(b *buffer.Buffer) ([]string, []string) {
19         c := b.GetActiveCursor()
20         input, argstart := buffer.GetArg(b)
21
22         var suggestions []string
23         for cmd := range commands {
24                 if strings.HasPrefix(cmd, input) {
25                         suggestions = append(suggestions, cmd)
26                 }
27         }
28
29         sort.Strings(suggestions)
30         completions := make([]string, len(suggestions))
31         for i := range suggestions {
32                 completions[i] = util.SliceEndStr(suggestions[i], c.X-argstart)
33         }
34
35         return completions, suggestions
36 }
37
38 // HelpComplete autocompletes help topics
39 func HelpComplete(b *buffer.Buffer) ([]string, []string) {
40         c := b.GetActiveCursor()
41         input, argstart := buffer.GetArg(b)
42
43         var suggestions []string
44
45         for _, file := range config.ListRuntimeFiles(config.RTHelp) {
46                 topic := file.Name()
47                 if strings.HasPrefix(topic, input) {
48                         suggestions = append(suggestions, topic)
49                 }
50         }
51
52         sort.Strings(suggestions)
53         completions := make([]string, len(suggestions))
54         for i := range suggestions {
55                 completions[i] = util.SliceEndStr(suggestions[i], c.X-argstart)
56         }
57         return completions, suggestions
58 }
59
60 // colorschemeComplete tab-completes names of colorschemes.
61 // This is just a heper value for OptionValueComplete
62 func colorschemeComplete(input string) (string, []string) {
63         var suggestions []string
64         files := config.ListRuntimeFiles(config.RTColorscheme)
65
66         for _, f := range files {
67                 if strings.HasPrefix(f.Name(), input) {
68                         suggestions = append(suggestions, f.Name())
69                 }
70         }
71
72         var chosen string
73         if len(suggestions) == 1 {
74                 chosen = suggestions[0]
75         }
76
77         return chosen, suggestions
78 }
79
80 func contains(s []string, e string) bool {
81         for _, a := range s {
82                 if a == e {
83                         return true
84                 }
85         }
86         return false
87 }
88
89 // OptionComplete autocompletes options
90 func OptionComplete(b *buffer.Buffer) ([]string, []string) {
91         c := b.GetActiveCursor()
92         input, argstart := buffer.GetArg(b)
93
94         var suggestions []string
95         localSettings := config.DefaultLocalSettings()
96         for option := range config.GlobalSettings {
97                 if strings.HasPrefix(option, input) {
98                         suggestions = append(suggestions, option)
99                 }
100         }
101         for option := range localSettings {
102                 if strings.HasPrefix(option, input) && !contains(suggestions, option) {
103                         suggestions = append(suggestions, option)
104                 }
105         }
106
107         sort.Strings(suggestions)
108         completions := make([]string, len(suggestions))
109         for i := range suggestions {
110                 completions[i] = util.SliceEndStr(suggestions[i], c.X-argstart)
111         }
112         return completions, suggestions
113 }
114
115 // OptionValueComplete completes values for various options
116 func OptionValueComplete(b *buffer.Buffer) ([]string, []string) {
117         c := b.GetActiveCursor()
118         l := b.LineBytes(c.Y)
119         l = util.SliceStart(l, c.X)
120         input, argstart := buffer.GetArg(b)
121
122         completeValue := false
123         args := bytes.Split(l, []byte{' '})
124         if len(args) >= 2 {
125                 localSettings := config.DefaultLocalSettings()
126                 for option := range config.GlobalSettings {
127                         if option == string(args[len(args)-2]) {
128                                 completeValue = true
129                                 break
130                         }
131                 }
132                 for option := range localSettings {
133                         if option == string(args[len(args)-2]) {
134                                 completeValue = true
135                                 break
136                         }
137                 }
138         }
139         if !completeValue {
140                 return OptionComplete(b)
141         }
142
143         inputOpt := string(args[len(args)-2])
144
145         inputOpt = strings.TrimSpace(inputOpt)
146         var suggestions []string
147         localSettings := config.DefaultLocalSettings()
148         var optionVal interface{}
149         for k, option := range config.GlobalSettings {
150                 if k == inputOpt {
151                         optionVal = option
152                 }
153         }
154         for k, option := range localSettings {
155                 if k == inputOpt {
156                         optionVal = option
157                 }
158         }
159
160         switch optionVal.(type) {
161         case bool:
162                 if strings.HasPrefix("on", input) {
163                         suggestions = append(suggestions, "on")
164                 } else if strings.HasPrefix("true", input) {
165                         suggestions = append(suggestions, "true")
166                 }
167                 if strings.HasPrefix("off", input) {
168                         suggestions = append(suggestions, "off")
169                 } else if strings.HasPrefix("false", input) {
170                         suggestions = append(suggestions, "false")
171                 }
172         case string:
173                 switch inputOpt {
174                 case "colorscheme":
175                         _, suggestions = colorschemeComplete(input)
176                 case "fileformat":
177                         if strings.HasPrefix("unix", input) {
178                                 suggestions = append(suggestions, "unix")
179                         }
180                         if strings.HasPrefix("dos", input) {
181                                 suggestions = append(suggestions, "dos")
182                         }
183                 case "sucmd":
184                         if strings.HasPrefix("sudo", input) {
185                                 suggestions = append(suggestions, "sudo")
186                         }
187                         if strings.HasPrefix("doas", input) {
188                                 suggestions = append(suggestions, "doas")
189                         }
190                 }
191         }
192         sort.Strings(suggestions)
193
194         completions := make([]string, len(suggestions))
195         for i := range suggestions {
196                 completions[i] = util.SliceEndStr(suggestions[i], c.X-argstart)
197         }
198         return completions, suggestions
199 }
200
201 // // MakeCompletion registers a function from a plugin for autocomplete commands
202 // func MakeCompletion(function string) Completion {
203 //      pluginCompletions = append(pluginCompletions, LuaFunctionComplete(function))
204 //      return Completion(-len(pluginCompletions))
205 // }
206 //
207 // // PluginComplete autocompletes from plugin function
208 // func PluginComplete(complete Completion, input string) (chosen string, suggestions []string) {
209 //      idx := int(-complete) - 1
210 //
211 //      if len(pluginCompletions) <= idx {
212 //              return "", nil
213 //      }
214 //      suggestions = pluginCompletions[idx](input)
215 //
216 //      if len(suggestions) == 1 {
217 //              chosen = suggestions[0]
218 //      }
219 //      return
220 // }
221 //
222 // // PluginCmdComplete completes with possible choices for the `> plugin` command
223 // func PluginCmdComplete(input string) (chosen string, suggestions []string) {
224 //      for _, cmd := range []string{"install", "remove", "search", "update", "list"} {
225 //              if strings.HasPrefix(cmd, input) {
226 //                      suggestions = append(suggestions, cmd)
227 //              }
228 //      }
229 //
230 //      if len(suggestions) == 1 {
231 //              chosen = suggestions[0]
232 //      }
233 //      return chosen, suggestions
234 // }
235 //
236 // // PluginnameComplete completes with the names of loaded plugins
237 // func PluginNameComplete(input string) (chosen string, suggestions []string) {
238 //      for _, pp := range GetAllPluginPackages() {
239 //              if strings.HasPrefix(pp.Name, input) {
240 //                      suggestions = append(suggestions, pp.Name)
241 //              }
242 //      }
243 //
244 //      if len(suggestions) == 1 {
245 //              chosen = suggestions[0]
246 //      }
247 //      return chosen, suggestions
248 // }