fix: file completions changes

changed the way file completions are handed
completely, which fixes #130 and makes the
full name appear in the completion menu instead
of it being cut off
pull/147/head
TorchedSammy 2022-04-20 13:06:46 -04:00
parent 6ccb9ebeff
commit 1458ecdcab
Signed by: sammyette
GPG Key ID: 904FC49417B44DCD
3 changed files with 54 additions and 51 deletions

2
api.go
View File

@ -154,7 +154,7 @@ func luaFileComplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
return nil, err return nil, err
} }
completions := fileComplete(query, ctx, fds) completions, _ := fileComplete(query, ctx, fds)
luaComps := rt.NewTable() luaComps := rt.NewTable()
for i, comp := range completions { for i, comp := range completions {

View File

@ -6,21 +6,8 @@ import (
"os" "os"
) )
func fileComplete(query, ctx string, fields []string) []string { func fileComplete(query, ctx string, fields []string) ([]string, string) {
var completions []string return matchPath(query)
prefixes := []string{"./", "../", "/", "~/"}
for _, prefix := range prefixes {
if strings.HasPrefix(query, prefix) {
completions, _ = matchPath(strings.Replace(query, "~", curuser.HomeDir, 1), query)
}
}
if len(completions) == 0 && len(fields) > 1 {
completions, _ = matchPath("./" + query, query)
}
return completions
} }
func binaryComplete(query, ctx string, fields []string) ([]string, string) { func binaryComplete(query, ctx string, fields []string) ([]string, string) {
@ -29,17 +16,17 @@ func binaryComplete(query, ctx string, fields []string) ([]string, string) {
prefixes := []string{"./", "../", "/", "~/"} prefixes := []string{"./", "../", "/", "~/"}
for _, prefix := range prefixes { for _, prefix := range prefixes {
if strings.HasPrefix(query, prefix) { if strings.HasPrefix(query, prefix) {
fileCompletions := fileComplete(query, ctx, fields) fileCompletions, filePref := matchPath(query)
if len(fileCompletions) != 0 { if len(fileCompletions) != 0 {
for _, f := range fileCompletions { for _, f := range fileCompletions {
name := strings.Replace(query + f, "~", curuser.HomeDir, 1) fullPath, _ := filepath.Abs(expandHome(query + strings.TrimPrefix(f, filePref)))
if err := findExecutable(name, false, true); err != nil { if err := findExecutable(fullPath, false, true); err != nil {
continue continue
} }
completions = append(completions, f) completions = append(completions, f)
} }
} }
return completions, "" return completions, filePref
} }
} }
@ -75,10 +62,35 @@ func binaryComplete(query, ctx string, fields []string) ([]string, string) {
return completions, query return completions, query
} }
func matchPath(path, pref string) ([]string, error) { func matchPath(query string) ([]string, string) {
var entries []string var entries []string
matches, err := filepath.Glob(path + "*") var baseName string
if err == nil {
path, _ := filepath.Abs(expandHome(filepath.Dir(query)))
if string(query) == "" {
// filepath base below would give us "."
// which would cause a match of only dotfiles
path, _ = filepath.Abs(".")
} else if !strings.HasSuffix(query, string(os.PathSeparator)) {
baseName = filepath.Base(query)
}
files, _ := os.ReadDir(path)
for _, file := range files {
if strings.HasPrefix(file.Name(), baseName) {
entry := file.Name()
if file.IsDir() {
entry = entry + string(os.PathSeparator)
}
entry = escapeFilename(entry)
entries = append(entries, entry)
}
}
return entries, baseName
}
func escapeFilename(fname string) string {
args := []string{ args := []string{
"\"", "\\\"", "\"", "\\\"",
"'", "\\'", "'", "\\'",
@ -88,24 +100,14 @@ func matchPath(path, pref string) ([]string, error) {
")", "\\)", ")", "\\)",
"[", "\\[", "[", "\\[",
"]", "\\]", "]", "\\]",
"$", "\\$",
"&", "\\&",
"*", "\\*",
">", "\\>",
"<", "\\<",
"|", "\\|",
} }
r := strings.NewReplacer(args...) r := strings.NewReplacer(args...)
for _, match := range matches { return r.Replace(fname)
name := filepath.Base(match)
p := filepath.Base(pref)
if pref == "" || 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)
}
}
return entries, err
} }

9
rl.go
View File

@ -86,7 +86,6 @@ func newLineReader(prompt string, noHist bool) *lineReader {
} }
rl.TabCompleter = func(line []rune, pos int, _ readline.DelayedTabContext) (string, []*readline.CompletionGroup) { rl.TabCompleter = func(line []rune, pos int, _ readline.DelayedTabContext) (string, []*readline.CompletionGroup) {
ctx := string(line) ctx := string(line)
var completions []string
var compGroup []*readline.CompletionGroup var compGroup []*readline.CompletionGroup
@ -237,12 +236,14 @@ func newLineReader(prompt string, noHist bool) *lineReader {
} }
if len(compGroup) == 0 { if len(compGroup) == 0 {
completions = fileComplete(query, ctx, fields) completions, p := fileComplete(query, ctx, fields)
compGroup = append(compGroup, &readline.CompletionGroup{ fcompGroup := []*readline.CompletionGroup{{
TrimSlash: false, TrimSlash: false,
NoSpace: true, NoSpace: true,
Suggestions: completions, Suggestions: completions,
}) }}
return p, fcompGroup
} }
} }
return "", compGroup return "", compGroup