From 232ea0b564848d37be0c20990f6057c6bd5b1433 Mon Sep 17 00:00:00 2001 From: Rami Awar Date: Wed, 28 Feb 2024 23:07:24 +0100 Subject: [PATCH] Added multiple parameter support via two character separators --- dialog/params.go | 6 +-- dialog/view.go | 97 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 91 insertions(+), 12 deletions(-) diff --git a/dialog/params.go b/dialog/params.go index 603c49a..b89ae31 100644 --- a/dialog/params.go +++ b/dialog/params.go @@ -18,11 +18,11 @@ var ( // This matches most encountered patterns // Skips match if there is a whitespace at the end ex. // Ignores <, > characters since they're used to match the pattern - patternRegex = `<([^<>]*[^\s])>` + parameterStringRegex = `<([^<>]*[^\s])>` ) func insertParams(command string, filledInParams map[string]string) string { - r := regexp.MustCompile(patternRegex) + r := regexp.MustCompile(parameterStringRegex) matches := r.FindAllStringSubmatch(command, -1) if len(matches) == 0 { @@ -48,7 +48,7 @@ func insertParams(command string, filledInParams map[string]string) string { // SearchForParams returns variables from a command func SearchForParams(command string) [][2]string { - r := regexp.MustCompile(patternRegex) + r := regexp.MustCompile(parameterStringRegex) params := r.FindAllStringSubmatch(command, -1) if len(params) == 0 { diff --git a/dialog/view.go b/dialog/view.go index 6ff602e..0c41ddd 100644 --- a/dialog/view.go +++ b/dialog/view.go @@ -3,6 +3,7 @@ package dialog import ( "fmt" "log" + "regexp" "github.com/awesome-gocui/gocui" ) @@ -10,9 +11,12 @@ import ( var ( layoutStep = 3 curView = -1 + + // This is for matching multiple default values in parameters + parameterMultipleValueRegex = `(\|_.*?_\|)` ) -func generateView(g *gocui.Gui, desc string, fill string, coords []int, editable bool) error { +func generateSingleParameterView(g *gocui.Gui, desc string, defaultParam string, coords []int, editable bool) error { if StringInSlice(desc, views) { return nil } @@ -20,7 +24,7 @@ func generateView(g *gocui.Gui, desc string, fill string, coords []int, editable if err != gocui.ErrUnknownView { return err } - fmt.Fprint(v, fill) + fmt.Fprint(v, defaultParam) } view, _ := g.View(desc) view.Title = desc @@ -33,6 +37,61 @@ func generateView(g *gocui.Gui, desc string, fill string, coords []int, editable return nil } +func generateMultipleParameterView(g *gocui.Gui, desc string, defaultParams []string, coords []int, editable bool) error { + if StringInSlice(desc, views) { + return nil + } + + currentOpt := 0 + maxOpt := len(defaultParams) + + if v, err := g.SetView(desc, coords[0], coords[1], coords[2], coords[3], 0); err != nil { + if err != gocui.ErrUnknownView { + return err + } + g.SetKeybinding(v.Name(), gocui.KeyArrowDown, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { + if maxOpt == 0 { + return nil + } + next := currentOpt + 1 + if next >= maxOpt { + next = currentOpt + } + v.Clear() + fmt.Fprint(v, defaultParams[next]) + currentOpt = next + return nil + }) + g.SetKeybinding(v.Name(), gocui.KeyArrowUp, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { + if maxOpt == 0 { + return nil + } + prev := currentOpt - 1 + if prev < 0 { + prev = currentOpt + } + v.Clear() + fmt.Fprint(v, defaultParams[prev]) + currentOpt = prev + return nil + }) + g.SetKeybinding(v.Name(), gocui.KeyCtrlK, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { + v.Clear() + return nil + }) + + fmt.Fprint(v, defaultParams[currentOpt]) + } + + view, _ := g.View(desc) + view.Title = desc + view.Wrap = false + view.Autoscroll = true + view.Editable = editable + views = append(views, desc) + return nil +} + // GenerateParamsLayout generates CUI to receive params func GenerateParamsLayout(params [][2]string, command string) { g, err := gocui.NewGui(gocui.OutputNormal, false) @@ -51,7 +110,7 @@ func GenerateParamsLayout(params [][2]string, command string) { leftX := (maxX / 2) - (maxX / 3) rightX := (maxX / 2) + (maxX / 3) - generateView(g, "Command(TAB => Select next, ENTER => Execute command):", + generateSingleParameterView(g, "Command(TAB => Select next, ENTER => Execute command):", command, []int{leftX, maxY / 10, rightX, maxY/10 + 5}, false) idx := 0 @@ -59,12 +118,32 @@ func GenerateParamsLayout(params [][2]string, command string) { for _, pair := range params { // Unpack parameter key and value k, v := pair[0], pair[1] - generateView(g, k, v, - []int{leftX, - (maxY / 4) + (idx+1)*layoutStep, - rightX, - (maxY / 4) + 2 + (idx+1)*layoutStep}, - true) + + // Handle multiple default values + r := regexp.MustCompile(parameterMultipleValueRegex) + matches := r.FindAllStringSubmatch(command, -1) + if len(matches) > 0 { + parameters := []string{} + for _, p := range matches { + _, matchedGroup := p[0], p[1] + // Remove the separators + matchedGroup = matchedGroup[2 : len(matchedGroup)-2] + parameters = append(parameters, matchedGroup) + } + generateMultipleParameterView( + g, k, parameters, []int{leftX, + (maxY / 4) + (idx+1)*layoutStep, + rightX, + (maxY / 4) + 2 + (idx+1)*layoutStep}, + true) + } else { + generateSingleParameterView(g, k, v, + []int{leftX, + (maxY / 4) + (idx+1)*layoutStep, + rightX, + (maxY / 4) + 2 + (idx+1)*layoutStep}, + true) + } idx++ }