Skip to content

Commit

Permalink
Merge pull request #188 from rsteube/bash-completion-locations
Browse files Browse the repository at this point in the history
bash: more completion locations
  • Loading branch information
rsteube committed Feb 20, 2024
2 parents d9c845f + f56dbed commit 566035f
Showing 1 changed file with 83 additions and 8 deletions.
91 changes: 83 additions & 8 deletions pkg/bridges/bash.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package bridges

import (
"fmt"
"os"
"runtime"
"strings"
Expand All @@ -19,14 +20,7 @@ func Bash() []string {

return cache("bash", func() ([]string, error) {
unique := make(map[string]bool)
for _, location := range []string{
"/data/data/com.termux/files/etc/bash_completion.d", // termux
"/data/data/com.termux/files/usr/share/bash-completion/completions", // termux
"/etc/bash_completion.d", // linux
"/usr/local/etc/bash_completion.d", // osx
"/usr/local/share/bash-completion/completions", // osx
"/usr/share/bash-completion/completions", // linux
} {
for _, location := range bashCompletionLocations() {
entries, err := os.ReadDir(location)
if err != nil {
carapace.LOG.Println(err.Error())
Expand All @@ -47,3 +41,84 @@ func Bash() []string {
return completers, nil
})
}

// bashCompletionLocations return folders containing bash completion scripts
//
// https://github.com/scop/bash-completion/blob/7864377cacb7858893a475e69c9c7461c2727e02/bash_completion#L3159C5-L3194C61
func bashCompletionLocations() []string {
locations := []string{
// TODO fix order
"/data/data/com.termux/files/etc/bash_completion.d", // termux
"/etc/bash_completion.d", // linux
"/usr/local/etc/bash_completion.d", // osx
}

// # Lookup order:
// # 1) From BASH_COMPLETION_USER_DIR (e.g. ~/.local/share/bash-completion):
// # User installed completions.
// if [[ ${BASH_COMPLETION_USER_DIR-} ]]; then
// _comp_split -F : paths "$BASH_COMPLETION_USER_DIR" &&
// dirs+=("${paths[@]/%//completions}")
// else
// dirs=("${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion/completions")
// fi
if userDirs, ok := os.LookupEnv("BASH_COMPLETION_USER_DIR"); ok {
for userDir := range strings.Split(userDirs, string(os.PathListSeparator)) {
locations = append(locations, fmt.Sprintf("%v/completions", userDir))
}
} else {
if dataHome, ok := os.LookupEnv("XDG_DATA_HOME"); ok {
locations = append(locations, fmt.Sprintf("%v/.local/share/bash-completion/completions", dataHome))
} else if home, err := os.UserHomeDir(); err == nil {
locations = append(locations, fmt.Sprintf("%v/.local/share/bash-completion/completions", home))
}
}

// # 2) From the location of bash_completion: Completions relative to the main
// # script. This is primarily for run-in-place-from-git-clone setups, where
// # we want to prefer in-tree completions over ones possibly coming with a
// # system installed bash-completion. (Due to usual install layouts, this
// # often hits the correct completions in system installations, too.)
// if [[ $BASH_SOURCE == */* ]]; then
// dirs+=("${BASH_SOURCE%/*}/completions")
// else
// dirs+=(./completions)
// fi
if sourceDir, ok := os.LookupEnv("BASH_SOURCE"); ok {
locations = append(locations, fmt.Sprintf("%v/completions", sourceDir))
} else {
locations = append(locations, "./completions")
}

// # 3) From bin directories extracted from the specified path to the command,
// # the real path to the command, and $PATH
// paths=()
// [[ $cmd == /* ]] && paths+=("${cmd%/*}")
// _comp_realcommand "$cmd" && paths+=("${REPLY%/*}")
// _comp_split -aF : paths "$PATH"
// for dir in "${paths[@]%/}"; do
// [[ $dir == ?*/@(bin|sbin) ]] &&
// dirs+=("${dir%/*}/share/bash-completion/completions")
// done
for _, pathDir := range strings.Split(os.Getenv("$PATH"), string(os.PathListSeparator)) {
locations = append(locations, fmt.Sprintf("%v/share/bash-completion/completions", pathDir))
}

// # 4) From XDG_DATA_DIRS or system dirs (e.g. /usr/share, /usr/local/share):
// # Completions in the system data dirs.
// _comp_split -F : paths "${XDG_DATA_DIRS:-/usr/local/share:/usr/share}" &&
// dirs+=("${paths[@]/%//bash-completion/completions}")
if dataDirs, ok := os.LookupEnv("XDG_DATA_DIRS"); ok {
for _, dataDir := range strings.Split(dataDirs, string(os.PathListSeparator)) {
locations = append(locations, fmt.Sprintf("%v/bash-completion/completions", dataDir))
}
} else {
locations = append(locations,
"/data/data/com.termux/files/usr/share/bash-completion/completions", // termux
"/usr/local/share/bash-completion/completions", // osx
"/usr/share/bash-completion/completions", // linux
)
}

return locations
}

0 comments on commit 566035f

Please sign in to comment.