Skip to content

Commit

Permalink
Merge pull request #12 from tucksaun/fix/rollback-posener-v1
Browse files Browse the repository at this point in the history
Autocompletion: fix panic by downgrading posener/complete to v1
  • Loading branch information
fabpot authored Jun 14, 2024
2 parents 9139849 + b206b17 commit 4bda854
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 74 deletions.
38 changes: 25 additions & 13 deletions completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import (
"os"
"runtime/debug"

"github.com/posener/complete/v2"
"github.com/pkg/errors"
"github.com/posener/complete"
"github.com/rs/zerolog"
"github.com/symfony-cli/terminal"
)

func init() {
Expand Down Expand Up @@ -47,41 +50,50 @@ func registerAutocompleteCommands(a *Application) {
}

func AutocompleteAppAction(c *Context) error {
// connect posener/complete logger to our logging facilities
logger := terminal.Logger.WithLevel(zerolog.DebugLevel)
complete.Log = func(format string, args ...interface{}) {
logger.Msgf("completion | "+format, args...)
}

cmd := complete.Command{
Flags: map[string]complete.Predictor{},
Sub: map[string]*complete.Command{},
GlobalFlags: make(complete.Flags),
Sub: make(complete.Commands),
}

// transpose registered commands and flags to posener/complete equivalence
for _, command := range c.App.VisibleCommands() {
subCmd := command.convertToPosenerCompleteCommand(c)

for _, name := range command.Names() {
cmd.Sub[name] = &subCmd
cmd.Sub[name] = subCmd
}
}

for _, f := range c.App.VisibleFlags() {
if vf, ok := f.(*verbosityFlag); ok {
vf.addToPosenerFlags(c, cmd.Flags)
vf.addToPosenerFlags(c, cmd.GlobalFlags)
continue
}

predictor := ContextPredictor{f, c}

for _, name := range f.Names() {
name = fmt.Sprintf("%s%s", prefixFor(name), name)
cmd.Flags[name] = predictor
cmd.GlobalFlags[name] = predictor
}
}

cmd.Complete(c.App.HelpName)
if !complete.New(c.App.HelpName, cmd).Complete() {
return errors.New("Could not run auto-completion")
}

return nil
}

func (c *Command) convertToPosenerCompleteCommand(ctx *Context) complete.Command {
command := complete.Command{
Flags: map[string]complete.Predictor{},
Flags: make(complete.Flags, 0),
}

for _, f := range c.VisibleFlags() {
Expand All @@ -98,16 +110,16 @@ func (c *Command) convertToPosenerCompleteCommand(ctx *Context) complete.Command
return command
}

func (c *Command) PredictArgs(ctx *Context, prefix string) []string {
func (c *Command) PredictArgs(ctx *Context, a complete.Args) []string {
if c.ShellComplete != nil {
return c.ShellComplete(ctx, prefix)
return c.ShellComplete(ctx, a)
}

return nil
}

type Predictor interface {
PredictArgs(*Context, string) []string
PredictArgs(*Context, complete.Args) []string
}

// ContextPredictor determines what terms can follow a command or a flag
Expand All @@ -119,6 +131,6 @@ type ContextPredictor struct {
}

// Predict invokes the predict function and implements the Predictor interface
func (p ContextPredictor) Predict(prefix string) []string {
return p.predictor.PredictArgs(p.ctx, prefix)
func (p ContextPredictor) Predict(a complete.Args) []string {
return p.predictor.PredictArgs(p.ctx, a)
}
3 changes: 2 additions & 1 deletion completion_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"text/template"

"github.com/pkg/errors"
"github.com/posener/complete"
"github.com/symfony-cli/terminal"
)

Expand All @@ -27,7 +28,7 @@ var shellAutoCompleteInstallCommand = &Command{
{Name: "completion"},
},
Usage: "Dumps the completion script for the current shell",
ShellComplete: func(*Context, string) []string {
ShellComplete: func(context *Context, c complete.Args) []string {
return []string{"bash", "zsh", "fish"}
},
Description: `The <info>{{.HelpName}}</> command dumps the shell completion script required
Expand Down
3 changes: 2 additions & 1 deletion flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"time"

"github.com/pkg/errors"
"github.com/posener/complete"
"github.com/symfony-cli/terminal"
)

Expand Down Expand Up @@ -93,7 +94,7 @@ func (f FlagsByName) Swap(i, j int) {
type Flag interface {
fmt.Stringer

PredictArgs(*Context, string) []string
PredictArgs(*Context, complete.Args) []string
Validate(*Context) error
// Apply Flag settings to the given flag set
Apply(*flag.FlagSet)
Expand Down
Loading

0 comments on commit 4bda854

Please sign in to comment.