From dc423bfbed00b98cd4f3f90c2aa9c817fb4e0482 Mon Sep 17 00:00:00 2001 From: Ethan Dickson Date: Wed, 21 Aug 2024 11:37:49 +0000 Subject: [PATCH 1/2] chore: hide flag completions by default --- completion.go | 29 ++++++++++++++++++----------- completion_test.go | 16 ++++++++-------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/completion.go b/completion.go index 1da93a0..fde50c9 100644 --- a/completion.go +++ b/completion.go @@ -1,6 +1,8 @@ package serpent import ( + "strings" + "github.com/spf13/pflag" ) @@ -14,19 +16,24 @@ func (inv *Invocation) IsCompletionMode() bool { return ok } -// DefaultCompletionHandler is a handler that prints all known flags and -// subcommands that haven't been exhaustively set. +// DefaultCompletionHandler is a handler that prints all the subcommands, or +// all the options that haven't been exhaustively set, if the current word +// starts with a dash. func DefaultCompletionHandler(inv *Invocation) []string { + _, cur := inv.CurWords() var allResps []string - for _, cmd := range inv.Command.Children { - allResps = append(allResps, cmd.Name()) - } - for _, opt := range inv.Command.Options { - _, isSlice := opt.Value.(pflag.SliceValue) - if opt.ValueSource == ValueSourceNone || - opt.ValueSource == ValueSourceDefault || - isSlice { - allResps = append(allResps, "--"+opt.Flag) + if strings.HasPrefix(cur, "-") { + for _, opt := range inv.Command.Options { + _, isSlice := opt.Value.(pflag.SliceValue) + if opt.ValueSource == ValueSourceNone || + opt.ValueSource == ValueSourceDefault || + isSlice { + allResps = append(allResps, "--"+opt.Flag) + } + } + } else { + for _, cmd := range inv.Command.Children { + allResps = append(allResps, cmd.Name()) } } return allResps diff --git a/completion_test.go b/completion_test.go index f1527be..43d6e1b 100644 --- a/completion_test.go +++ b/completion_test.go @@ -25,7 +25,7 @@ func TestCompletion(t *testing.T) { io := fakeIO(i) err := i.Run() require.NoError(t, err) - require.Equal(t, "altfile\nfile\nrequired-flag\ntoupper\n--prefix\n--verbose\n", io.Stdout.String()) + require.Equal(t, "altfile\nfile\nrequired-flag\ntoupper\n", io.Stdout.String()) }) t.Run("SubcommandNoPartial", func(t *testing.T) { @@ -35,7 +35,7 @@ func TestCompletion(t *testing.T) { io := fakeIO(i) err := i.Run() require.NoError(t, err) - require.Equal(t, "altfile\nfile\nrequired-flag\ntoupper\n--prefix\n--verbose\n", io.Stdout.String()) + require.Equal(t, "altfile\nfile\nrequired-flag\ntoupper\n", io.Stdout.String()) }) t.Run("SubcommandComplete", func(t *testing.T) { @@ -50,7 +50,7 @@ func TestCompletion(t *testing.T) { t.Run("ListFlags", func(t *testing.T) { t.Parallel() - i := cmd().Invoke("required-flag", "") + i := cmd().Invoke("required-flag", "-") i.Environ.Set(serpent.CompletionModeEnv, "1") io := fakeIO(i) err := i.Run() @@ -60,7 +60,7 @@ func TestCompletion(t *testing.T) { t.Run("ListFlagsAfterArg", func(t *testing.T) { t.Parallel() - i := cmd().Invoke("altfile", "") + i := cmd().Invoke("altfile", "-") i.Environ.Set(serpent.CompletionModeEnv, "1") io := fakeIO(i) err := i.Run() @@ -70,7 +70,7 @@ func TestCompletion(t *testing.T) { t.Run("FlagExhaustive", func(t *testing.T) { t.Parallel() - i := cmd().Invoke("required-flag", "--req-bool", "--req-string", "foo bar", "--req-array", "asdf", "--req-array", "qwerty") + i := cmd().Invoke("required-flag", "--req-bool", "--req-string", "foo bar", "--req-array", "asdf", "--req-array", "qwerty", "-") i.Environ.Set(serpent.CompletionModeEnv, "1") io := fakeIO(i) err := i.Run() @@ -80,7 +80,7 @@ func TestCompletion(t *testing.T) { t.Run("FlagShorthand", func(t *testing.T) { t.Parallel() - i := cmd().Invoke("required-flag", "-b", "-s", "foo bar", "-a", "asdf") + i := cmd().Invoke("required-flag", "-b", "-s", "foo bar", "-a", "asdf", "-") i.Environ.Set(serpent.CompletionModeEnv, "1") io := fakeIO(i) err := i.Run() @@ -90,12 +90,12 @@ func TestCompletion(t *testing.T) { t.Run("NoOptDefValueFlag", func(t *testing.T) { t.Parallel() - i := cmd().Invoke("--verbose", "") + i := cmd().Invoke("--verbose", "-") i.Environ.Set(serpent.CompletionModeEnv, "1") io := fakeIO(i) err := i.Run() require.NoError(t, err) - require.Equal(t, "altfile\nfile\nrequired-flag\ntoupper\n--prefix\n", io.Stdout.String()) + require.Equal(t, "--prefix\n", io.Stdout.String()) }) t.Run("EnumOK", func(t *testing.T) { From 49306f972001fdc8086f30f9e6501c57fb7723c8 Mon Sep 17 00:00:00 2001 From: Ethan Dickson Date: Thu, 22 Aug 2024 02:47:41 +0000 Subject: [PATCH 2/2] review --- completion.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/completion.go b/completion.go index fde50c9..d82a06e 100644 --- a/completion.go +++ b/completion.go @@ -31,10 +31,10 @@ func DefaultCompletionHandler(inv *Invocation) []string { allResps = append(allResps, "--"+opt.Flag) } } - } else { - for _, cmd := range inv.Command.Children { - allResps = append(allResps, cmd.Name()) - } + return allResps + } + for _, cmd := range inv.Command.Children { + allResps = append(allResps, cmd.Name()) } return allResps }