]> git.lizzy.rs Git - micro.git/blob - internal/action/infocomplete.go
Merge
[micro.git] / internal / action / infocomplete.go
1 package action
2
3 import (
4         "bytes"
5         "sort"
6         "strings"
7
8         "github.com/zyedidia/micro/v2/internal/buffer"
9         "github.com/zyedidia/micro/v2/internal/config"
10         "github.com/zyedidia/micro/v2/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         for option := range config.GlobalSettings {
96                 if strings.HasPrefix(option, input) {
97                         suggestions = append(suggestions, option)
98                 }
99         }
100         // for option := range localSettings {
101         //      if strings.HasPrefix(option, input) && !contains(suggestions, option) {
102         //              suggestions = append(suggestions, option)
103         //      }
104         // }
105
106         sort.Strings(suggestions)
107         completions := make([]string, len(suggestions))
108         for i := range suggestions {
109                 completions[i] = util.SliceEndStr(suggestions[i], c.X-argstart)
110         }
111         return completions, suggestions
112 }
113
114 // OptionValueComplete completes values for various options
115 func OptionValueComplete(b *buffer.Buffer) ([]string, []string) {
116         c := b.GetActiveCursor()
117         l := b.LineBytes(c.Y)
118         l = util.SliceStart(l, c.X)
119         input, argstart := buffer.GetArg(b)
120
121         completeValue := false
122         args := bytes.Split(l, []byte{' '})
123         if len(args) >= 2 {
124                 // localSettings := config.DefaultLocalSettings()
125                 for option := range config.GlobalSettings {
126                         if option == string(args[len(args)-2]) {
127                                 completeValue = true
128                                 break
129                         }
130                 }
131                 // for option := range localSettings {
132                 //      if option == string(args[len(args)-2]) {
133                 //              completeValue = true
134                 //              break
135                 //      }
136                 // }
137         }
138         if !completeValue {
139                 return OptionComplete(b)
140         }
141
142         inputOpt := string(args[len(args)-2])
143
144         inputOpt = strings.TrimSpace(inputOpt)
145         var suggestions []string
146         // localSettings := config.DefaultLocalSettings()
147         var optionVal interface{}
148         for k, option := range config.GlobalSettings {
149                 if k == inputOpt {
150                         optionVal = option
151                 }
152         }
153         // for k, option := range localSettings {
154         //      if k == inputOpt {
155         //              optionVal = option
156         //      }
157         // }
158
159         switch optionVal.(type) {
160         case bool:
161                 if strings.HasPrefix("on", input) {
162                         suggestions = append(suggestions, "on")
163                 } else if strings.HasPrefix("true", input) {
164                         suggestions = append(suggestions, "true")
165                 }
166                 if strings.HasPrefix("off", input) {
167                         suggestions = append(suggestions, "off")
168                 } else if strings.HasPrefix("false", input) {
169                         suggestions = append(suggestions, "false")
170                 }
171         case string:
172                 switch inputOpt {
173                 case "colorscheme":
174                         _, suggestions = colorschemeComplete(input)
175                 case "fileformat":
176                         if strings.HasPrefix("unix", input) {
177                                 suggestions = append(suggestions, "unix")
178                         }
179                         if strings.HasPrefix("dos", input) {
180                                 suggestions = append(suggestions, "dos")
181                         }
182                 case "sucmd":
183                         if strings.HasPrefix("sudo", input) {
184                                 suggestions = append(suggestions, "sudo")
185                         }
186                         if strings.HasPrefix("doas", input) {
187                                 suggestions = append(suggestions, "doas")
188                         }
189                 case "clipboard":
190                         if strings.HasPrefix("external", input) {
191                                 suggestions = append(suggestions, "external")
192                         }
193                         if strings.HasPrefix("internal", input) {
194                                 suggestions = append(suggestions, "internal")
195                         }
196                         if strings.HasPrefix("terminal", input) {
197                                 suggestions = append(suggestions, "terminal")
198                         }
199                 }
200         }
201         sort.Strings(suggestions)
202
203         completions := make([]string, len(suggestions))
204         for i := range suggestions {
205                 completions[i] = util.SliceEndStr(suggestions[i], c.X-argstart)
206         }
207         return completions, suggestions
208 }
209
210 // PluginCmdComplete autocompletes the plugin command
211 func PluginCmdComplete(b *buffer.Buffer) ([]string, []string) {
212         c := b.GetActiveCursor()
213         input, argstart := buffer.GetArg(b)
214
215         var suggestions []string
216         for _, cmd := range PluginCmds {
217                 if strings.HasPrefix(cmd, input) {
218                         suggestions = append(suggestions, cmd)
219                 }
220         }
221
222         sort.Strings(suggestions)
223         completions := make([]string, len(suggestions))
224         for i := range suggestions {
225                 completions[i] = util.SliceEndStr(suggestions[i], c.X-argstart)
226         }
227         return completions, suggestions
228 }
229
230 // PluginComplete completes values for the plugin command
231 func PluginComplete(b *buffer.Buffer) ([]string, []string) {
232         c := b.GetActiveCursor()
233         l := b.LineBytes(c.Y)
234         l = util.SliceStart(l, c.X)
235         input, argstart := buffer.GetArg(b)
236
237         completeValue := false
238         args := bytes.Split(l, []byte{' '})
239         if len(args) >= 2 {
240                 for _, cmd := range PluginCmds {
241                         if cmd == string(args[len(args)-2]) {
242                                 completeValue = true
243                                 break
244                         }
245                 }
246         }
247         if !completeValue {
248                 return PluginCmdComplete(b)
249         }
250
251         var suggestions []string
252         for _, pl := range config.Plugins {
253                 if strings.HasPrefix(pl.Name, input) {
254                         suggestions = append(suggestions, pl.Name)
255                 }
256         }
257         sort.Strings(suggestions)
258
259         completions := make([]string, len(suggestions))
260         for i := range suggestions {
261                 completions[i] = util.SliceEndStr(suggestions[i], c.X-argstart)
262         }
263         return completions, suggestions
264 }
265
266 // PluginNameComplete completes with the names of loaded plugins
267 // func PluginNameComplete(b *buffer.Buffer) ([]string, []string) {
268 //      c := b.GetActiveCursor()
269 //      input, argstart := buffer.GetArg(b)
270 //
271 //      var suggestions []string
272 //      for _, pp := range config.GetAllPluginPackages(nil) {
273 //              if strings.HasPrefix(pp.Name, input) {
274 //                      suggestions = append(suggestions, pp.Name)
275 //              }
276 //      }
277 //
278 //      sort.Strings(suggestions)
279 //      completions := make([]string, len(suggestions))
280 //      for i := range suggestions {
281 //              completions[i] = util.SliceEndStr(suggestions[i], c.X-argstart)
282 //      }
283 //      return completions, suggestions
284 // }
285
286 // // MakeCompletion registers a function from a plugin for autocomplete commands
287 // func MakeCompletion(function string) Completion {
288 //      pluginCompletions = append(pluginCompletions, LuaFunctionComplete(function))
289 //      return Completion(-len(pluginCompletions))
290 // }