fix: tab complete absolute path binaries properly

dev
TorchedSammy 2021-11-22 22:52:14 -05:00
parent 80dcfc362b
commit 4aafddfdb1
Signed by: sammyette
GPG Key ID: 904FC49417B44DCD
1 changed files with 12 additions and 37 deletions

49
rl.go
View File

@ -44,46 +44,21 @@ func NewLineReader(prompt string) *LineReader {
} }
if len(fields) == 1 { if len(fields) == 1 {
prefixes := []string{"./", "../"} fileCompletions := append(completions, readline.FilenameCompleter(query, ctx)...)
for _, prefix := range prefixes { // filter out executables
if strings.HasPrefix(query, prefix) { for _, f := range fileCompletions {
if matches, err := filepath.Glob(query + "*"); err == nil { name := strings.Replace(f, "~", homedir, 1)
for _, match := range matches { if info, err := os.Stat(name); err == nil && info.Mode().Perm() & 0100 == 0 {
if info, err := os.Stat(match); err == nil && info.Mode().Perm() & 0100 == 0 { continue
continue
}
name := filepath.Base(match)
completions = append(completions, name)
}
}
if len(completions) == 1 {
// we have add the base dir of query since the completion entries are basename
// why? so readline will display just that
// and we want to complete the full path when its the only completion entry
// query will be incomplete so adding it will be broken
// also Dir doesn't have a trailing slash so we need to filepath join
// to account to windows
// AND ANOTHER THING is it returns . if the arg is ./ and Join will
// ignore that so we have to check and just add the prefix instead
if prefix != "./" {
completions[0] = filepath.Join(filepath.Dir(query), completions[0])
} else {
dirNest := strings.Count(query, "/")
if dirNest > 1 {
completions[0] = prefix + filepath.Join(filepath.Dir(query), completions[0])
} else {
completions[0] = prefix + completions[0]
}
}
if info, err := os.Stat(strings.Replace(completions[0], "~", homedir, 1)); err == nil && info.IsDir() {
completions[0] += "/"
}
}
return completions
} }
completions = append(completions, f)
} }
if len(completions) != 0 {
return completions
}
// filter out executables, but in path
for _, dir := range filepath.SplitList(os.Getenv("PATH")) { for _, dir := range filepath.SplitList(os.Getenv("PATH")) {
// print dir to stderr for debugging // print dir to stderr for debugging
// search for an executable which matches our query string // search for an executable which matches our query string