package prep // This is where the actual autocomplete happens // lots of the fun magic is in here import ( "fmt" "os" "path/filepath" "time" "go.wit.com/dev/alexflint/arg" "go.wit.com/lib/config" "go.wit.com/log" ) func Autocomplete(dest any) *Auto { myAuto = new(AutoArgs) findAppInfo(dest) // parses back to main() for argv info pb := parseArgv(myAuto.appName) // parses os.Args into a protobuf if pb.SetupAuto { // --bash was passed. try to configure bash-completion makeAutocompleteFiles(myAuto.appName) os.Exit(0) } if pb.Debug { // dump debug info pb.PrintDebug() } pb.doHandlePB() // read in the history protobuf file // turn on debugging if duration < 200 milliseconds dur := pb.Duration.AsDuration() if dur < time.Millisecond*200 { pb.Debug = true } // prepart["--gui"] = "andlabs gocui" arg.Register(&argBash) flags := []string{} for _, s := range pb.Argv { if s == "--autodebug" { continue } flags = append(flags, s) } // pb.Debug = true // pb.Debugf("DEBUG: MustParse(%v)", flags) var err error myAuto.pp, err = arg.ParseFlags(flags, dest) if err != nil { pb.Debugf("DEBUG: Parse error: %v", err) } if myAuto.pp == nil { pb.Debugf("DEBUG: myAuto.pp == nil after ParseFlags()") } else { // pb.Debugf("DEBUG: myAuto.pp is ok after ParseFlags()") } if pb.IsAuto { // myAuto.match = make(map[string]string) // myAuto.match["--gui"] = "andlabs gocui" // for key, val := range myAuto.match { if pb.Last == "--gui" { pb.Debugf("DEBUG: last=%s found --gui", pb.Last) pb.Autocomplete2("andlabs gogui") os.Exit(0) } else { // pb.Debugf("DEBUG: NO MATCH last='%s' found key '%s' = %s", pb.Last, key, val) } // } if myAuto.autoFunc == nil { pb.SubCommand(pb.Argv...) } else { myAuto.autoFunc(pb) // run the autocomplete function the user made for their application } if pb.Debug { // TODO: // check here to see if there was any completion text sent // if not, send "reset bash newline\n" to cause bash to redraw PS1 for the user } os.Exit(0) } arg.Register(&argBash) myAuto.pp = arg.MustParse(dest) return pb } // makes a autocomplete file for your command func makeAutocompleteFiles(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) } os.Exit(0) }