]> git.lizzy.rs Git - micro.git/blob - cmd/micro/autocomplete.go
allow plugins to register autocomplete functions
[micro.git] / cmd / micro / autocomplete.go
1 package main
2
3 import (
4         "io/ioutil"
5         "os"
6         "strings"
7
8         "github.com/mitchellh/go-homedir"
9 )
10
11 var pluginCompletions []func(string) []string
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 // FileComplete autocompletes filenames
18 func FileComplete(input string) (string, []string) {
19         dirs := strings.Split(input, "/")
20         var files []os.FileInfo
21         var err error
22         if len(dirs) > 1 {
23                 home, _ := homedir.Dir()
24
25                 directories := strings.Join(dirs[:len(dirs)-1], "/")
26                 if strings.HasPrefix(directories, "~") {
27                         directories = strings.Replace(directories, "~", home, 1)
28                 }
29                 files, err = ioutil.ReadDir(directories)
30         } else {
31                 files, err = ioutil.ReadDir(".")
32         }
33         var suggestions []string
34         if err != nil {
35                 return "", suggestions
36         }
37         for _, f := range files {
38                 name := f.Name()
39                 if f.IsDir() {
40                         name += "/"
41                 }
42                 if strings.HasPrefix(name, dirs[len(dirs)-1]) {
43                         suggestions = append(suggestions, name)
44                 }
45         }
46
47         var chosen string
48         if len(suggestions) == 1 {
49                 if len(dirs) > 1 {
50                         chosen = strings.Join(dirs[:len(dirs)-1], "/") + "/" + suggestions[0]
51                 } else {
52                         chosen = suggestions[0]
53                 }
54         } else {
55                 if len(dirs) > 1 {
56                         chosen = strings.Join(dirs[:len(dirs)-1], "/") + "/"
57                 }
58         }
59
60         return chosen, suggestions
61 }
62
63 // CommandComplete autocompletes commands
64 func CommandComplete(input string) (string, []string) {
65         var suggestions []string
66         for cmd := range commands {
67                 if strings.HasPrefix(cmd, input) {
68                         suggestions = append(suggestions, cmd)
69                 }
70         }
71
72         var chosen string
73         if len(suggestions) == 1 {
74                 chosen = suggestions[0]
75         }
76         return chosen, suggestions
77 }
78
79 // HelpComplete autocompletes help topics
80 func HelpComplete(input string) (string, []string) {
81         var suggestions []string
82
83         for _, topic := range helpFiles {
84                 if strings.HasPrefix(topic, input) {
85
86                         suggestions = append(suggestions, topic)
87                 }
88         }
89
90         var chosen string
91         if len(suggestions) == 1 {
92                 chosen = suggestions[0]
93         }
94         return chosen, suggestions
95 }
96
97 func contains(s []string, e string) bool {
98         for _, a := range s {
99                 if a == e {
100                         return true
101                 }
102         }
103         return false
104 }
105
106 // OptionComplete autocompletes options
107 func OptionComplete(input string) (string, []string) {
108         var suggestions []string
109         localSettings := DefaultLocalSettings()
110         for option := range globalSettings {
111                 if strings.HasPrefix(option, input) {
112                         suggestions = append(suggestions, option)
113                 }
114         }
115         for option := range localSettings {
116                 if strings.HasPrefix(option, input) && !contains(suggestions, option) {
117                         suggestions = append(suggestions, option)
118                 }
119         }
120
121         var chosen string
122         if len(suggestions) == 1 {
123                 chosen = suggestions[0]
124         }
125         return chosen, suggestions
126 }
127
128 // MakeCompletion registeres a function from a plugin for autocomplete commands
129 func MakeCompletion(function string) Completion {
130         pluginCompletions = append(pluginCompletions, LuaFunctionComplete(function))
131         return Completion(-len(pluginCompletions))
132 }
133
134 // PluginComplete autocompletes from plugin function
135 func PluginComplete(complete Completion, input string) (chosen string, suggestions []string) {
136         idx := int(-complete) - 1
137
138         if len(pluginCompletions) <= idx {
139                 return "", nil
140         }
141         suggestions = pluginCompletions[idx](input)
142
143         if len(suggestions) == 1 {
144                 chosen = suggestions[0]
145         }
146         return
147 }