2022-02-27 23:17:51 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
"os"
|
|
|
|
)
|
|
|
|
|
|
|
|
func fileComplete(query, ctx string, fields []string) []string {
|
|
|
|
var completions []string
|
|
|
|
|
|
|
|
prefixes := []string{"./", "../", "/", "~/"}
|
|
|
|
for _, prefix := range prefixes {
|
|
|
|
if strings.HasPrefix(query, prefix) {
|
|
|
|
completions, _ = matchPath(strings.Replace(query, "~", curuser.HomeDir, 1), query)
|
|
|
|
}
|
|
|
|
}
|
2022-03-05 19:59:00 +00:00
|
|
|
|
2022-02-27 23:17:51 +00:00
|
|
|
if len(completions) == 0 && len(fields) > 1 {
|
|
|
|
completions, _ = matchPath("./" + query, query)
|
|
|
|
}
|
|
|
|
|
|
|
|
return completions
|
|
|
|
}
|
|
|
|
|
2022-03-05 19:59:00 +00:00
|
|
|
func binaryComplete(query, ctx string, fields []string) ([]string, string) {
|
|
|
|
var completions []string
|
|
|
|
|
|
|
|
prefixes := []string{"./", "../", "/", "~/"}
|
|
|
|
for _, prefix := range prefixes {
|
|
|
|
if strings.HasPrefix(query, prefix) {
|
|
|
|
fileCompletions := fileComplete(query, ctx, fields)
|
|
|
|
if len(fileCompletions) != 0 {
|
|
|
|
for _, f := range fileCompletions {
|
|
|
|
name := strings.Replace(query + f, "~", curuser.HomeDir, 1)
|
|
|
|
if info, err := os.Stat(name); err == nil && info.Mode().Perm() & 0100 == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
completions = append(completions, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return completions, ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// filter out executables, but in path
|
|
|
|
for _, dir := range filepath.SplitList(os.Getenv("PATH")) {
|
|
|
|
// print dir to stderr for debugging
|
|
|
|
// search for an executable which matches our query string
|
|
|
|
if matches, err := filepath.Glob(filepath.Join(dir, query + "*")); err == nil {
|
|
|
|
// get basename from matches
|
|
|
|
for _, match := range matches {
|
|
|
|
// check if we have execute permissions for our match
|
|
|
|
if info, err := os.Stat(match); err == nil && info.Mode().Perm() & 0100 == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// get basename from match
|
|
|
|
name := filepath.Base(match)
|
|
|
|
// add basename to completions
|
|
|
|
completions = append(completions, name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// add lua registered commands to completions
|
|
|
|
for cmdName := range commands {
|
|
|
|
if strings.HasPrefix(cmdName, query) {
|
|
|
|
completions = append(completions, cmdName)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return completions, query
|
|
|
|
}
|
|
|
|
|
2022-02-27 23:17:51 +00:00
|
|
|
func matchPath(path, pref string) ([]string, error) {
|
|
|
|
var entries []string
|
|
|
|
matches, err := filepath.Glob(path + "*")
|
|
|
|
if err == nil {
|
|
|
|
args := []string{
|
|
|
|
"\"", "\\\"",
|
|
|
|
"'", "\\'",
|
|
|
|
"`", "\\`",
|
|
|
|
" ", "\\ ",
|
2022-02-27 23:19:00 +00:00
|
|
|
"(", "\\(",
|
|
|
|
")", "\\)",
|
|
|
|
"[", "\\[",
|
2022-02-27 23:24:02 +00:00
|
|
|
"]", "\\]",
|
2022-02-27 23:17:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
r := strings.NewReplacer(args...)
|
|
|
|
for _, match := range matches {
|
|
|
|
name := filepath.Base(match)
|
|
|
|
p := filepath.Base(pref)
|
|
|
|
if pref == "" {
|
|
|
|
p = ""
|
|
|
|
}
|
|
|
|
name = strings.TrimPrefix(name, p)
|
|
|
|
matchFull, _ := filepath.Abs(match)
|
|
|
|
if info, err := os.Stat(matchFull); err == nil && info.IsDir() {
|
|
|
|
name = name + string(os.PathSeparator)
|
|
|
|
}
|
|
|
|
name = r.Replace(name)
|
|
|
|
entries = append(entries, name)
|
|
|
|
}
|
|
|
|
}
|
2022-03-05 19:59:00 +00:00
|
|
|
|
2022-02-27 23:17:51 +00:00
|
|
|
return entries, err
|
|
|
|
}
|