2016-08-15 20:29:37 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
|
|
|
"os"
|
2016-08-16 20:17:19 +00:00
|
|
|
"path"
|
2016-08-15 20:29:37 +00:00
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
gCmdWords = []string{"set", "map", "cmd"}
|
|
|
|
gOptWords = []string{
|
|
|
|
"preview",
|
|
|
|
"nopreview",
|
2016-08-16 20:13:57 +00:00
|
|
|
"preview!",
|
2016-08-15 20:29:37 +00:00
|
|
|
"hidden",
|
|
|
|
"nohidden",
|
2016-08-16 20:13:57 +00:00
|
|
|
"hidden!",
|
2016-08-15 20:29:37 +00:00
|
|
|
"tabstop",
|
|
|
|
"scrolloff",
|
|
|
|
"sortby",
|
|
|
|
"showinfo",
|
|
|
|
"opener",
|
|
|
|
"ratios",
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2016-08-16 20:13:57 +00:00
|
|
|
func matchLongest(s1, s2 string) string {
|
|
|
|
i := 0
|
|
|
|
for ; i < len(s1) && i < len(s2); i++ {
|
|
|
|
if s1[i] != s2[i] {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return s1[:i]
|
|
|
|
}
|
|
|
|
|
2016-08-15 20:29:37 +00:00
|
|
|
func matchWord(s string, words []string) string {
|
|
|
|
var match string
|
|
|
|
|
|
|
|
for _, w := range words {
|
|
|
|
if strings.HasPrefix(w, s) {
|
|
|
|
if match != "" {
|
2016-08-16 20:13:57 +00:00
|
|
|
match = matchLongest(match, w)
|
|
|
|
} else {
|
|
|
|
match = w + " "
|
2016-08-15 20:29:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if match != "" {
|
2016-08-16 20:13:57 +00:00
|
|
|
return match
|
2016-08-15 20:29:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
2016-08-16 19:31:17 +00:00
|
|
|
func matchExec(s string) string {
|
|
|
|
var match string
|
|
|
|
|
|
|
|
paths := strings.Split(envPath, ":")
|
|
|
|
|
|
|
|
for _, p := range paths {
|
2016-08-16 20:18:26 +00:00
|
|
|
if _, err := os.Stat(p); os.IsNotExist(err) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2016-08-16 19:31:17 +00:00
|
|
|
fi, err := ioutil.ReadDir(p)
|
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, f := range fi {
|
|
|
|
if strings.HasPrefix(f.Name(), s) {
|
2016-08-16 20:17:19 +00:00
|
|
|
f, err = os.Stat(path.Join(p, f.Name()))
|
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
}
|
|
|
|
|
2016-08-16 19:31:17 +00:00
|
|
|
if !f.Mode().IsRegular() || f.Mode()&0111 == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if match != "" {
|
2016-08-16 20:13:57 +00:00
|
|
|
match = matchLongest(match, f.Name())
|
|
|
|
} else {
|
|
|
|
match = f.Name() + " "
|
2016-08-16 19:31:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if match != "" {
|
2016-08-16 20:13:57 +00:00
|
|
|
return match
|
2016-08-16 19:31:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
2016-08-15 20:29:37 +00:00
|
|
|
func matchFile(s string) string {
|
|
|
|
var match string
|
|
|
|
|
|
|
|
wd, err := os.Getwd()
|
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
fi, err := ioutil.ReadDir(wd)
|
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, f := range fi {
|
|
|
|
if strings.HasPrefix(f.Name(), s) {
|
|
|
|
if match != "" {
|
2016-08-16 20:13:57 +00:00
|
|
|
match = matchLongest(match, f.Name())
|
|
|
|
} else {
|
|
|
|
match = f.Name() + " "
|
2016-08-15 20:29:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if match != "" {
|
2016-08-16 20:13:57 +00:00
|
|
|
return match
|
2016-08-15 20:29:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
func compCmd(acc []rune) []rune {
|
|
|
|
if len(acc) == 0 || acc[len(acc)-1] == ' ' {
|
|
|
|
return acc
|
|
|
|
}
|
|
|
|
|
|
|
|
s := string(acc)
|
|
|
|
f := strings.Fields(s)
|
|
|
|
|
|
|
|
switch len(f) {
|
|
|
|
case 0: // do nothing
|
|
|
|
case 1:
|
|
|
|
words := gCmdWords
|
|
|
|
for c, _ := range gOpts.cmds {
|
|
|
|
words = append(words, c)
|
|
|
|
}
|
|
|
|
return []rune(matchWord(s, words))
|
|
|
|
default:
|
|
|
|
switch f[0] {
|
|
|
|
case "set":
|
|
|
|
opt := matchWord(f[1], gOptWords)
|
|
|
|
ret := []rune(f[0])
|
|
|
|
ret = append(ret, ' ')
|
|
|
|
ret = append(ret, []rune(opt)...)
|
|
|
|
return ret
|
|
|
|
case "map", "cmd": // do nothing
|
|
|
|
default:
|
|
|
|
ret := []rune(f[0])
|
|
|
|
ret = append(ret, ' ')
|
|
|
|
for i := 1; i < len(f); i++ {
|
|
|
|
name := matchFile(f[i])
|
|
|
|
ret = append(ret, []rune(name)...)
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return acc
|
|
|
|
}
|
2016-08-16 19:31:17 +00:00
|
|
|
|
|
|
|
func compShell(acc []rune) []rune {
|
|
|
|
if len(acc) == 0 || acc[len(acc)-1] == ' ' {
|
|
|
|
return acc
|
|
|
|
}
|
|
|
|
|
|
|
|
s := string(acc)
|
|
|
|
f := strings.Fields(s)
|
|
|
|
|
|
|
|
switch len(f) {
|
|
|
|
case 0: // do nothing
|
|
|
|
case 1:
|
|
|
|
return []rune(matchExec(s))
|
|
|
|
default:
|
|
|
|
ret := []rune(f[0])
|
|
|
|
ret = append(ret, ' ')
|
|
|
|
for i := 1; i < len(f); i++ {
|
|
|
|
name := matchFile(f[i])
|
|
|
|
ret = append(ret, []rune(name)...)
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
|
|
|
return acc
|
|
|
|
}
|