attempt to autocomplete --gui

This commit is contained in:
Jeff Carr 2025-09-21 23:22:53 -05:00
parent 3c096fec0f
commit 1dbf1a561b
5 changed files with 65 additions and 39 deletions

View File

@ -21,6 +21,7 @@ message Auto { // `autogenpb:marshal` `
bool setupAuto = 11; // is true if '--bash' is set // setup bash autocomplete here bool setupAuto = 11; // is true if '--bash' is set // setup bash autocomplete here
bool debug = 12; // print debugging info if true bool debug = 12; // print debugging info if true
bool newline = 13; // was a newline was sent to STDERR? bool newline = 13; // was a newline was sent to STDERR?
string last = 14; // the last arg
} }
message Autos { // `autogenpb:marshal` `autogenpb:sort` `autogenpb:nomutex` message Autos { // `autogenpb:marshal` `autogenpb:sort` `autogenpb:nomutex`

View File

@ -26,13 +26,15 @@ type ArgsBash struct {
// try this struct out (?) // try this struct out (?)
var myAuto *AutoArgs var myAuto *AutoArgs
// this is a work in progress
type AutoArgs struct { type AutoArgs struct {
id int // should be unique id int // should be unique
hidden bool // don't update the toolkits when it's hidden hidden bool // don't update the toolkits when it's hidden
Auto func([]string) Auto func([]string) // the function for shell autocomplete
appName string // a good way to track the name of the binary ? appName string // a good way to track the name of the binary ?
pp *arg.Parser // for parsing the command line args. Yay to alexf lint! pp *arg.Parser // for parsing the command line args. Yay to alexf lint!
autoFunc func(*Auto) autoFunc func(*Auto) // also a function for autocomplete
match map[string]string // maps for strings
} }
// argname is the name of the executable // argname is the name of the executable
@ -60,7 +62,6 @@ func Bash(argname string, autocomplete func([]string)) *AutoArgs {
func (pb *Auto) PrintDebug() { func (pb *Auto) PrintDebug() {
dur := pb.Duration.AsDuration() dur := pb.Duration.AsDuration()
pb.Debugf("AUTOCOMPLETE: arg0='%s' arg1='%s' partial='%s' cmd='%s' age=%s argv=%v\n", pb.Arg0, pb.Arg1, pb.Partial, pb.Cmd, shell.FormatDuration(dur), pb.Argv) pb.Debugf("AUTOCOMPLETE: arg0='%s' arg1='%s' partial='%s' cmd='%s' age=%s argv=%v\n", pb.Arg0, pb.Arg1, pb.Partial, pb.Cmd, shell.FormatDuration(dur), pb.Argv)
// fmt.Println("--all --gui --verbose --force")
} }
// returns the last command (is blank if the current arg is not blank) // returns the last command (is blank if the current arg is not blank)

View File

@ -82,7 +82,9 @@ func (pb *Auto) doHandlePB() error {
dur := time.Since(found.Ctime.AsTime()) dur := time.Since(found.Ctime.AsTime())
pb.Duration = durationpb.New(dur) pb.Duration = durationpb.New(dur)
// found.PrintDebug() // found.PrintDebug()
pb.Debugf("AUTO HISTORY: age=%s cmd='%s' partial='%s' argv='%v'", shell.FormatDuration(dur), found.Cmd, found.Partial, found.Argv) cmd := fmt.Sprintf("cmd='%s'", found.Cmd)
arglast := fmt.Sprintf("last='%s'", found.Last)
pb.Debugf("AUTO HISTORY: age=%-6.6s %-18.18s %-18.18s partial='%s' argv='%v'", shell.FormatDuration(dur), cmd, arglast, found.Partial, found.Argv)
last = found last = found
} }
} }
@ -208,60 +210,71 @@ func (pb *Auto) Autocomplete2(sendthis string) {
} }
func parseArgv(argname string) *Auto { func parseArgv(argname string) *Auto {
newauto := new(Auto) pb := new(Auto)
newauto.Argname = argname pb.Argname = argname
if len(os.Args) == 0 { if len(os.Args) == 0 {
return newauto return pb
} }
if len(os.Args) > 1 && os.Args[1] == "--bash" { if len(os.Args) > 1 && os.Args[1] == "--bash" {
newauto.SetupAuto = true pb.SetupAuto = true
return newauto return pb
} }
// HACK: set debug flag if --autodebug is passed // HACK: set debug flag if --autodebug is passed
for _, s := range os.Args { for _, s := range os.Args {
if s == "--autodebug" { if s == "--autodebug" {
newauto.Debug = true pb.Debug = true
} }
} }
// should we do auto complete here? // should we do auto complete here?
if len(os.Args) > 1 && os.Args[1] == "--auto-complete" { if len(os.Args) > 1 && os.Args[1] == "--auto-complete" {
newauto.IsAuto = true pb.IsAuto = true
newauto.Arg0 = os.Args[0] pb.Arg0 = os.Args[0]
newauto.Arg1 = os.Args[1] pb.Arg1 = os.Args[1]
newauto.Partial = os.Args[2] pb.Partial = os.Args[2]
newauto.Arg3 = os.Args[3] pb.Arg3 = os.Args[3]
if len(os.Args) < 5 { if len(os.Args) < 5 {
// the user is doing autocomplete on the command itself // the user is doing autocomplete on the command itself
newauto.Partial = "" pb.Partial = ""
newauto.Cmd = "" pb.Cmd = ""
newauto.Argv = []string{""} pb.Argv = []string{""}
return newauto return pb
} }
newauto.Argv = os.Args[4:] pb.Argv = os.Args[4:]
if newauto.Partial == "''" { if pb.Partial == "''" {
newauto.Partial = "" pb.Partial = ""
newauto.Cmd = "todo:findme" pb.Cmd = "todo:findme"
} }
// set pb.Cmd to the first thing that doesn't have a '-' arg // set pb.Cmd to the first thing that doesn't have a '-' arg
for _, s := range newauto.Argv { for _, s := range pb.Argv {
if strings.HasPrefix(s, "-") { if strings.HasPrefix(s, "-") {
continue continue
} }
newauto.Cmd = s pb.Cmd = s
break break
} }
if newauto.Partial == "'"+newauto.Cmd+"'" { if pb.Partial == "'"+pb.Cmd+"'" {
// not really a command, it's just a partially inputed string from the user // not really a command, it's just a partially inputed string from the user
newauto.Cmd = "" pb.Cmd = ""
} }
// if newauto.Cmd == "" { // try to figure out what the last argv is
// newauto.Cmd = strings.Join(newauto.Argv, "BLAH") for _, s := range pb.Argv {
p := fmt.Sprintf("'%s'", s)
if pb.Partial == p {
pb.Debugf("DEBUG: MATCH Partial %s %s", s, p)
continue
} else {
pb.Debugf("DEBUG: NO MATCH Partial %s %s", s, p)
}
pb.Last = s
}
// if pb.Cmd == "" {
// pb.Cmd = strings.Join(pb.Argv, "BLAH")
// } // }
} }
return newauto return pb
} }
// also try to parse/send cur (?) // also try to parse/send cur (?)
@ -301,9 +314,7 @@ func Bash2(argname string, appAutoFunc func(*Auto)) *Auto {
// func Bash3(appAutoFunc func(*Auto), dest any) *Auto { // func Bash3(appAutoFunc func(*Auto), dest any) *Auto {
func Bash3(dest any) *Auto { func Bash3(dest any) *Auto {
myAuto = new(AutoArgs) myAuto = new(AutoArgs)
// myAuto.appName = argname findAppInfo(dest) // parses back to main() for argv info
// myAuto.autoFunc = appAutoFunc
newTest(dest)
pb := parseArgv(myAuto.appName) pb := parseArgv(myAuto.appName)
if pb.SetupAuto { if pb.SetupAuto {
@ -312,6 +323,9 @@ func Bash3(dest any) *Auto {
os.Exit(0) os.Exit(0)
} }
myAuto.match = make(map[string]string)
myAuto.match["--gui"] = "andlabs gocui"
if pb.Debug { if pb.Debug {
// dump debug info // dump debug info
pb.PrintDebug() pb.PrintDebug()
@ -325,6 +339,8 @@ func Bash3(dest any) *Auto {
pb.Debug = true pb.Debug = true
} }
// prepart["--gui"] = "andlabs gocui"
arg.Register(&argBash) arg.Register(&argBash)
flags := []string{} flags := []string{}
for _, s := range pb.Argv { for _, s := range pb.Argv {
@ -348,6 +364,15 @@ func Bash3(dest any) *Auto {
} }
if pb.IsAuto { if pb.IsAuto {
for key, val := range myAuto.match {
if pb.Last == key {
pb.Debugf("DEBUG: last=%s found key %s = %s", pb.Last, key, val)
pb.Autocomplete2(val)
os.Exit(0)
} else {
pb.Debugf("DEBUG: NO MATCH last='%s' found key '%s' = %s", pb.Last, key, val)
}
}
myAuto.autoFunc(pb) // run the autocomplete function the user made for their application myAuto.autoFunc(pb) // run the autocomplete function the user made for their application
if pb.Debug { if pb.Debug {
// TODO: // TODO:

View File

@ -56,7 +56,7 @@ type AutoFuncd interface {
} }
// Described is the interface that the destination struct should implement to // Described is the interface that the destination struct should implement to
func newTest(tmp interface{}) { func findAppInfo(tmp interface{}) {
if tmp, ok := tmp.(Appnamed); ok { if tmp, ok := tmp.(Appnamed); ok {
myAuto.appName = tmp.Appname() myAuto.appName = tmp.Appname()
} else { } else {

1
gui.go
View File

@ -86,7 +86,6 @@ func Gui() *GuiPrep {
prepGui = new(GuiPrep) prepGui = new(GuiPrep)
prepGui.rootn = gui.PreInit(postMustParse) prepGui.rootn = gui.PreInit(postMustParse)
return prepGui return prepGui
} }