diff options
| author | Jeff Carr <[email protected]> | 2025-10-25 01:24:29 -0500 |
|---|---|---|
| committer | Jeff Carr <[email protected]> | 2025-10-25 01:24:29 -0500 |
| commit | 27e0ddeaf127f561ca7fd5a8083ab52eba6ca2fb (patch) | |
| tree | 432ed35a59d85782153993ccc4c8932171eac65a /theMagicOfAutocomplete.go | |
| parent | f7a1de79b1c115bddbf3d323a6fd7786d878efd9 (diff) | |
first stab at making an argv binary
Diffstat (limited to 'theMagicOfAutocomplete.go')
| -rw-r--r-- | theMagicOfAutocomplete.go | 68 |
1 files changed, 38 insertions, 30 deletions
diff --git a/theMagicOfAutocomplete.go b/theMagicOfAutocomplete.go index b48d1b9..5b5370b 100644 --- a/theMagicOfAutocomplete.go +++ b/theMagicOfAutocomplete.go @@ -17,8 +17,11 @@ import ( timestamppb "google.golang.org/protobuf/types/known/timestamppb" ) +// This function behaves oddly. It works in several different ways. It can: +// - Initialize a protobuf and returns it to the application +// - Help a user generate shell completion support & os.Exit +// - figures out what to print to Stdout & Stderr and then does os.Exit() func Autocomplete(dest any) *Argv { - var err error me = new(AutoArgs) // todo: redo this me.pb = new(Argv) @@ -27,7 +30,7 @@ func Autocomplete(dest any) *Argv { me.pb.Ctime = timestamppb.New(now) // makes sure the application has the - // needed functions defined, otherwise panics + // needed functions defined, otherwise dies verifyApplication(dest) // gets APPNAME, BUILDTIME and VERSION from the application @@ -40,10 +43,10 @@ func Autocomplete(dest any) *Argv { env.Init(me.pb.AppInfo.APPNAME, me.pb.AppInfo.VERSION, cobol.Time(me.pb.AppInfo.BUILDTIME), me.pb.Real, GoodExit, BadExit) // loads the argv autocomplete history file - all := NewArgvs() + me.all = NewArgvs() fullname := config.MakeCacheFilename("argv", me.pb.AppInfo.APPNAME) - err = config.LoadFromFilename(all, fullname) - if err != nil { + me.Err = config.LoadFromFilename(me.all, fullname) + if me.Err != nil { // there is no history. // todo: initialize the history file // todo: check if this is automatically done already @@ -76,25 +79,31 @@ func Autocomplete(dest any) *Argv { } } - // not autocompleting. return go-arg & the application - if !me.isAuto { - // save the pb & history - all.Clone(me.pb) - errors.Join(err, all.Save()) - - // me.pp = arg.MustParse(dest) - me.err = me.mustParseFunc() - return me.pb + if me.isAuto { + // do autocomplete and exit + doAutocomplete() + os.Exit(0) } - // EVERYTHING PAST HERE IS FOR AUTOCOMPLETE - // everything sent to STDOUT and STDERR matters past this point + // not autocompleting. return to the application + // save the pb & history + me.all.Clone(me.pb) + errors.Join(me.Err, me.all.Save()) + + // me.pp = arg.MustParse(dest) + me.Err = errors.Join(me.Err, me.mustParseFunc()) + return me.pb +} +// prints what is needed to Stdout & Stderr, then exits +// EVERYTHING PAST HERE IS FOR AUTOCOMPLETE +// everything sent to STDOUT and STDERR matters past this point +func doAutocomplete() { // set the duration since the last auto complete // find the last entry. this is dumb way to do it me.last = new(Argv) me.last.Ctime = timestamppb.New(time.Now().Add(-time.Second)) - for found := range all.IterAll() { + for found := range me.all.IterAll() { me.last = found } dur := time.Since(me.last.Ctime.AsTime()) @@ -103,15 +112,15 @@ func Autocomplete(dest any) *Argv { if me.debug { // dump debug info me.pb.PrintDebug() - all.PrintHistory() + me.all.PrintHistory() } // roll the autocomplete file - if all.Len() > 15 { - me.pb.Debugf("DEBUG: trim() history is over 100 len=%d vs new=%d", all.Len(), all.Len()-90) - all.Argvs = all.Argvs[all.Len()-10:] - // newall.Autos = all.Autos[0:10] - // for _, found := range all.Autos[0:10] { + if me.all.Len() > 15 { + me.pb.Debugf("DEBUG: trim() history is over 100 len=%d vs new=%d", me.all.Len(), me.all.Len()-90) + me.all.Argvs = me.all.Argvs[me.all.Len()-10:] + // newall.Autos = me.all.Autos[0:10] + // for _, found := range me.all.Autos[0:10] { // newall.Append(found) // } } @@ -180,15 +189,15 @@ func Autocomplete(dest any) *Argv { if len(flags) == 0 { // error is normal if there are no command line args } else { - if err != nil { + if me.Err != nil { // users has command line arguments that won't parse with go-args - me.pb.Debugf("DEBUG: Parse error: %v flags%v", err, flags) + me.pb.Debugf("DEBUG: Parse error: %v flags%v", me.Err, flags) } } // save now. this is near the end probably - all.Clone(me.pb) - errors.Join(err, all.Save()) + me.all.Clone(me.pb) + errors.Join(me.Err, me.all.Save()) if me.pb.Fast { if me.last.Fast { @@ -197,10 +206,10 @@ func Autocomplete(dest any) *Argv { } else { // this means the user is pressing tab. no longer doing stderr if me.pb.GetCmd() == "" { - // me.pp.WriteHelp(os.Stderr) + // me.pp.WriteHelp(Stderr) me.writeHelpFunc() } else { - // me.pp.WriteHelpForSubcommand(os.Stderr, me.pb.Cmd) + // me.pp.WriteHelpForSubcommand(Stderr, me.pb.Cmd) me.writeHelpForSubcommandFunc(me.pb.GetCmd()) } } @@ -218,5 +227,4 @@ func Autocomplete(dest any) *Argv { // if not, send "reset bash newline\n" to cause bash to redraw PS1 for the user } os.Exit(0) - return nil } |
