From efffba1bb0373268385aafff02ea8e9c108e0abe Mon Sep 17 00:00:00 2001 From: Pedro Augusto Campos Dos Santos <38117637+ppcamp@users.noreply.github.com> Date: Sat, 21 Sep 2024 15:47:56 -0300 Subject: [PATCH] feat: add early eval option support --- dialog/dynamic_options.go | 32 ++++++++++++++++++++++++++++++++ dialog/dynamic_options_test.go | 30 ++++++++++++++++++++++++++++++ dialog/view.go | 21 ++++++++++++++++++++- 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 dialog/dynamic_options.go create mode 100644 dialog/dynamic_options_test.go diff --git a/dialog/dynamic_options.go b/dialog/dynamic_options.go new file mode 100644 index 0000000..4524257 --- /dev/null +++ b/dialog/dynamic_options.go @@ -0,0 +1,32 @@ +package dialog + +import ( + "bytes" + "fmt" + "log" + "os" + "strings" + + runner "github.com/knqyf263/pet/cmd/runner" +) + +// DynamicOptions run a command, split and returns an array of strings. It expect to +// receive command substitions. +// +// Example: +// +// DynamicOptions("$(fd -tf --hidden --no-ignore --max-depth=1 .)") +func DynamicOptions(what string) ([]string, error) { + if what[:2] != "$(" || what[len(what)-1] != ')' { + return nil, fmt.Errorf("no evaluated command found: %v", what) + } + + var w bytes.Buffer + err := runner.Run(what[2:len(what)-1], os.Stdin, &w) + if err != nil { + log.Fatal(what) + return nil, err + } + + return strings.Split(strings.TrimSpace(w.String()), "\n"), nil +} diff --git a/dialog/dynamic_options_test.go b/dialog/dynamic_options_test.go new file mode 100644 index 0000000..4465b5b --- /dev/null +++ b/dialog/dynamic_options_test.go @@ -0,0 +1,30 @@ +package dialog_test + +import ( + "slices" + "testing" + + "github.com/knqyf263/pet/dialog" +) + +const nameOfThisFile = "eval_test.go" + +func TestEvaluator(t *testing.T) { + param := "$(ls)" + + e, err := dialog.DynamicOptions(param) + if err != nil { + t.Log(err) + t.FailNow() + } + + if len(e) == 0 { + t.Log("Expected at least one result, but got none.") + t.FailNow() + } + + if !slices.Contains(e, nameOfThisFile) { + t.Log("it should have the current file in this path") + t.FailNow() + } +} diff --git a/dialog/view.go b/dialog/view.go index 25c44a4..5434cb2 100644 --- a/dialog/view.go +++ b/dialog/view.go @@ -134,7 +134,26 @@ func GenerateParamsLayout(params [][2]string, command string) { r := regexp.MustCompile(parameterMultipleValueRegex) matches := r.FindAllStringSubmatch(parameterValue, -1) - if len(matches) > 0 { + if len(matches) == 1 { + // Extract the default values and generate multiple params view + // using early evaluation context + matchedGroup := matches[0][1] + parameter := matchedGroup[2 : len(matchedGroup)-2] + + options, err := DynamicOptions(parameter) + if err != nil { + // fallback to default evaluation (raw) + options = []string{parameter} + } + + generateMultipleParameterView( + g, parameterKey, options, []int{ + leftX, + (maxY / 4) + (idx+1)*layoutStep, + rightX, + (maxY / 4) + 2 + (idx+1)*layoutStep}, + true) + } else if len(matches) > 0 { // Extract the default values and generate multiple params view parameters := []string{} for _, p := range matches {