package argvpb // makes the needed bash completion in the bash standard paths import ( "fmt" "io/ioutil" "os" "path/filepath" "strings" "go.wit.com/lib/config" "go.wit.com/log" ) func MakeBashCompleteFiles(argname string) { fmt.Println(makeBashCompletionText2(argname)) homeDir, err := os.UserHomeDir() if err != nil { log.Printf("# %v\n", err) os.Exit(0) } filename := filepath.Join(homeDir, ".local/share/bash-completion/completions", argname) if config.Exists(filename) { log.Fprintln(os.Stderr, "# file already exists", filename) // os.Exit(0) } basedir, _ := filepath.Split(filename) if !config.IsDir(basedir) { os.MkdirAll(basedir, os.ModePerm) } if f, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err == nil { f.Write([]byte(makeBashCompletionText2(argname))) f.Close() } else { log.Fprintln(os.Stderr, "# open file error", filename, err) } } // deprecate this func Bash3(dest any) *Argv { return Autocomplete(dest) } // deprecate this func Bash(dest any) *Argv { return Autocomplete(dest) } func makeCompletionText(argname string) string { sh := getParentProcessName() return fmt.Sprintf("# shell might be %s", sh) } func makeBashCompletionText(argname string) string { var out string out += fmt.Sprintf("# add this in your bashrc:\n") out += fmt.Sprintf("\n") out += fmt.Sprintf("# todo: add this to go-arg as a 'hidden' go-arg option --bash\n") out += fmt.Sprintf("#\n") out += fmt.Sprintf("# Put the below in the file: ~/.local/share/bash-completion/completions/%s\n", argname) out += fmt.Sprintf("#\n") out += fmt.Sprintf("# todo: make this output work/parse with:\n") out += fmt.Sprintf("# complete -C %s --bash go\n", argname) out += fmt.Sprintf("\n") out += fmt.Sprintf("_%s_complete()\n", argname) out += fmt.Sprintf("{\n") out += fmt.Sprintf(" # sets local to this func vars\n") out += fmt.Sprintf(" local cur prev all\n") out += fmt.Sprintf(" cur=${COMP_WORDS[COMP_CWORD]}\n") out += fmt.Sprintf(" prev=${COMP_WORDS[COMP_CWORD-1]}\n") out += fmt.Sprintf(" all=${COMP_WORDS[@]}\n") out += fmt.Sprintf("\n") out += fmt.Sprintf(" # this is where we generate the go-arg output\n") out += fmt.Sprintf(" GOARGS=$(%s --auto-complete $prev \\'$cur\\' $all)\n", argname) out += fmt.Sprintf("\n") out += fmt.Sprintf(" # this compares the command line input from the user\n") out += fmt.Sprintf(" # to whatever strings we output\n") out += fmt.Sprintf(" COMPREPLY=( $(compgen -W \"$GOARGS\" -- $cur) ) # THIS WORKS\n") out += fmt.Sprintf(" return 0\n") out += fmt.Sprintf("}\n") out += fmt.Sprintf("complete -F _%s_complete %s\n", argname, argname) out += fmt.Sprintf("\n") out += fmt.Sprintf("# copy and paste the above into your bash shell should work\n") return out } func makeBashCompletionText2(argname string) string { var out string out += fmt.Sprintf("# add this in your bashrc:\n") out += fmt.Sprintf("\n") out += fmt.Sprintf("# todo: add this to go-arg as a 'hidden' go-arg option --bash\n") out += fmt.Sprintf("#\n") out += fmt.Sprintf("# Put the below in the file: ~/.local/share/bash-completion/completions/%s\n", argname) out += fmt.Sprintf("#\n") out += fmt.Sprintf("# todo: make this output work/parse with:\n") out += fmt.Sprintf("# complete -C %s --bash go\n", argname) out += fmt.Sprintf("\n") out += fmt.Sprintf("_%s_complete()\n", argname) out += fmt.Sprintf("{\n") out += fmt.Sprintf(" # sets local to this func vars\n") out += fmt.Sprintf(" local cur prev all\n") out += fmt.Sprintf(" cur=${COMP_WORDS[COMP_CWORD]}\n") out += fmt.Sprintf(" # prev=${COMP_WORDS[COMP_CWORD-1]}\n") out += fmt.Sprintf(" all=${COMP_WORDS[@]}\n") out += fmt.Sprintf("\n") out += fmt.Sprintf(" # this is where we generate the go-arg output\n") out += fmt.Sprintf(" GOARGS=$(%s --auto-complete \\'$cur\\' $all)\n", argname) out += fmt.Sprintf("\n") out += fmt.Sprintf(" # this compares the command line input from the user\n") out += fmt.Sprintf(" # to whatever strings we output\n") out += fmt.Sprintf(" COMPREPLY=( $(compgen -W \"$GOARGS\" -- $cur) ) # THIS WORKS\n") out += fmt.Sprintf(" return 0\n") out += fmt.Sprintf("}\n") out += fmt.Sprintf("complete -F _%s_complete %s\n", argname, argname) out += fmt.Sprintf("\n") out += fmt.Sprintf("# copy and paste the above into your bash shell should work\n") return out } func getParentProcessName() string { ppid := os.Getppid() // On Linux, the command name is in /proc//comm commPath := fmt.Sprintf("/proc/%d/comm", ppid) content, err := ioutil.ReadFile(commPath) if err != nil { return "unknown" } // The file content has a trailing newline, so trim it. return strings.TrimSpace(string(content)) }