Skip to content

Commit

Permalink
Add opt.CustomCompletionFn
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidGamba committed Nov 8, 2023
1 parent 6125c26 commit c9c7b3b
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 5 deletions.
15 changes: 11 additions & 4 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ type programTree struct {
CommandFn CommandFn
HelpCommandName string
mode Mode
unknownMode UnknownMode // Unknown option mode
requireOrder bool // stop parsing args as soon as an unknown is found
skipOptionsCopy bool // skips copying options from parent to child. Required when doing wrapper commands.
Suggestions []string // Suggestions used for completions
unknownMode UnknownMode // Unknown option mode
requireOrder bool // stop parsing args as soon as an unknown is found
skipOptionsCopy bool // skips copying options from parent to child. Required when doing wrapper commands.
Suggestions []string // Suggestions used for completions
SuggestionFns []CompletionFn // SuggestionsFns used for completions

mapKeysToLower bool // controls wether or not map keys are normalized to lowercase

Expand Down Expand Up @@ -275,6 +276,12 @@ ARGS_LOOP:
}
}
}
// SuggestionFns
{
for _, fn := range currentProgramNode.SuggestionFns {
completions = append(completions, fn(completionMode, iterator.Value())...)
}
}

// Provide other kinds of completions, like file completions.

Expand Down
11 changes: 11 additions & 0 deletions changelog.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
= Changelog
:toc:

== wip v0.30.0: New Features

As the releases before, this release has 100% test coverage.
Tested with Go 1.16, 1.17, 1.18, 1.19, 1.20 and 1.21.

=== New Features

* add `opt.CustomCompletionFn` which allows to provide a custom completion function that gets lazily called.
+
The completion function receives the target shell (bash or zsh) and the current partial completion.

== v0.29.0: New Features

As the releases before, this release has 100% test coverage.
Expand Down
41 changes: 41 additions & 0 deletions examples/complex/complete/complete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package complete

import (
"context"
"io"
"log"
"strings"

"github.com/DavidGamba/go-getoptions"
)

var Logger = log.New(io.Discard, "log ", log.LstdFlags)

// NewCommand - Populate Options definition
func NewCommand(parent *getoptions.GetOpt) *getoptions.GetOpt {
opt := parent.NewCommand("complete", "Example completions")
opt.SetCommandFn(Run)
opt.CustomCompletion("dev-east", "dev-west", "staging-east", "prod-east", "prod-west", "prod-south")
opt.CustomCompletionFn(func(target, s string) []string {
if strings.HasPrefix("dev-", s) {
return []string{"dev-hola/", "dev-hello"}
}
if strings.HasPrefix("dev-h", s) {
return []string{"dev-hola/", "dev-hello"}
}
if strings.HasPrefix("dev-hello", s) {
return []string{"dev-hello"}
}
if strings.HasPrefix("dev-hola/", s) {
return []string{"dev-hola/a", "dev-hola/b", "dev-hola/" + target}
}
return []string{}
})
return opt
}

// Run - Command entry point
func Run(ctx context.Context, opt *getoptions.GetOpt, args []string) error {
Logger.Printf("args: %v\n", args)
return nil
}
6 changes: 5 additions & 1 deletion examples/complex/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import (
"log"
"os"

"github.com/DavidGamba/go-getoptions"
complexcomplete "github.com/DavidGamba/go-getoptions/examples/complex/complete"
complexgreet "github.com/DavidGamba/go-getoptions/examples/complex/greet"
complexlog "github.com/DavidGamba/go-getoptions/examples/complex/log"
complexlswrapper "github.com/DavidGamba/go-getoptions/examples/complex/lswrapper"
complexshow "github.com/DavidGamba/go-getoptions/examples/complex/show"
complexslow "github.com/DavidGamba/go-getoptions/examples/complex/slow"

"github.com/DavidGamba/go-getoptions"
)

var Logger = log.New(io.Discard, "", log.LstdFlags)
Expand All @@ -34,6 +36,7 @@ func program(args []string) int {
complexlswrapper.NewCommand(opt)
complexshow.NewCommand(opt)
complexslow.NewCommand(opt)
complexcomplete.NewCommand(opt)
opt.HelpCommand("help", opt.Alias("?"))
remaining, err := opt.Parse(args[1:])
if err != nil {
Expand All @@ -47,6 +50,7 @@ func program(args []string) int {
complexlswrapper.Logger.SetOutput(os.Stderr)
complexshow.Logger.SetOutput(os.Stderr)
complexslow.Logger.SetOutput(os.Stderr)
complexcomplete.Logger.SetOutput(os.Stderr)
}
if opt.Called("profile") {
Logger.Printf("profile: %s\n", opt.Value("profile"))
Expand Down
16 changes: 16 additions & 0 deletions user.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,22 @@ func (gopt *GetOpt) CustomCompletion(list ...string) *GetOpt {
return gopt
}

// CompletionFn - Function receiver for custom completions.
// The `target` argument indicates "bash" or "zsh" for the completion targets.
//
// NOTE: Bash completions have = as a special char and results should be trimmed from the = on.
// This should not be done for Zsh.
type CompletionFn func(target, partialCompletion string) []string

// CustomCompletionFn - Allows to define custom completion functions that get lazily called.
//
// NOTE: Bash completions have = as a special char and results should be trimmed from the = on.
// This should not be done for Zsh.
func (gopt *GetOpt) CustomCompletionFn(fn ...CompletionFn) *GetOpt {
gopt.programTree.SuggestionFns = append(gopt.programTree.SuggestionFns, fn...)
return gopt
}

// UnsetOptions - Unsets inherited options from parent program and parent commands.
// This is useful when writing wrappers around other commands.
//
Expand Down

0 comments on commit c9c7b3b

Please sign in to comment.