Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/_v2/guides/05-built-in-features/03-shell-completion.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
"log"
"fmt"
"github.com/napalu/goopt/v2"
c "github.com/napalu/goopt/v2/completion"
comp "github.com/napalu/goopt/v2/completion"
)

func main() {
Expand All @@ -36,7 +36,7 @@ func main() {
parser.AddCommand(goopt.NewCommand(
goopt.WithName("completion"),
goopt.WithCommandDescription("Generate shell completion script"),
goopt.WithCallback(func(p *goopt.Parser, c *goopt.Command) error {
goopt.WithCallback(func(p *goopt.Parser, _ *goopt.Command) error {
// In a real app, you'd let the user specify the shell
// as an argument to this command (e.g., 'completion bash').
shell := "bash"
Expand All @@ -46,7 +46,7 @@ func main() {
return err
}

manager, err := c.NewManager(shell, exec)
manager, err := comp.NewManager(shell, exec)
if err != nil {
return err
}
Expand Down
9 changes: 9 additions & 0 deletions v2/command_config_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,12 @@ func WithExecuteOnParse(cmdExecOnParse bool) ConfigureCommandFunc {
command.ExecOnParse = cmdExecOnParse
}
}

// WithGreedy sets the Greedy property of the command. If true, any further ags will not be evaluated but are added as
// unbound positionals - this is useful for passthrough commands that are only used to invoke other commands,
// e.g. `git branch` or `git checkout`.
func WithGreedy(beGreedy bool) ConfigureCommandFunc {
return func(command *Command) {
command.Greedy = beGreedy
}
}
8 changes: 4 additions & 4 deletions v2/completion/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ type FlagType int

const (
// Single denotes a flag accepting a string value
FlagTypeSingle FlagType = 0
FlagTypeSingle FlagType = 1
// Chained denotes a flag accepting a string value which should be evaluated as a list
FlagTypeChained FlagType = 1
FlagTypeChained FlagType = 2
// Standalone denotes a boolean flag (does not accept a value)
FlagTypeStandalone FlagType = 2
FlagTypeStandalone FlagType = 3
// File denotes a flag which is evaluated as a path
FlagTypeFile FlagType = 3
FlagTypeFile FlagType = 4
)

// FlagPair represents a short and long version of the same flag
Expand Down
5 changes: 4 additions & 1 deletion v2/definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,11 @@ type Command struct {
ExecOnParse bool
Description string
DescriptionKey string
Greedy bool // Greedy if true any further commands and flags will be consumed as unbound positionals
topLevel bool
path string
callbackLocation reflect.Value // stores reference to a field which may contain a CommandFunc in the future

}

// FlagInfo is used to store information about a flag
Expand All @@ -129,7 +131,7 @@ type HelpStyle int
const (
HelpStyleFlat HelpStyle = iota // PrintUsage
HelpStyleGrouped // PrintUsageWithGroups
HelpStyleGroupedClean // PrintUsageWithGroups, clean (no ** markers)
HelpStyleGroupedClean // Deprecated: alias for HelpStyleGrouped (now uses clean formatting by default)
HelpStyleCompact // Deduplicated, minimal
HelpStyleHierarchical // Command-focused, drill-down
HelpStyleSmart // Auto-detect based on CLI size
Expand Down Expand Up @@ -231,6 +233,7 @@ type Parser struct {
treatUnknownAsPositionals bool // If true, treat unknown flags and their values as positionals
mu sync.Mutex
envVarPrefix string // Prefix for environment variables
greedyAfterPos int // Position of the first arg after which all remaining args are greedily consumed as positionals
}

// CompletionData is used to store information for command line completion
Expand Down
2 changes: 1 addition & 1 deletion v2/examples/i18n-load-system-locales/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func demoLocales(parser *goopt.Parser, cfg *Config) {

printSection("🧭 RTL Language Features", i18n.IsRTL(currentLang), func() {
fmt.Println(" ➤ Direction: Right-to-Left")
fmt.Println(" ➤ Note: Terminal rendering for RTL may vary across platforms\n")
fmt.Println(" ➤ Note: Greedy rendering for RTL may vary across platforms\n")
})

printSection("🗣️ Sample Translations", true, func() {
Expand Down
19 changes: 11 additions & 8 deletions v2/goopt.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func NewParserFromInterface(i interface{}, config ...ConfigureCmdLineFunc) (*Par
// SetEnvVarPrefix sets the prefix for environment variables.
func (p *Parser) SetEnvVarPrefix(prefix string) {
if !strings.HasSuffix(prefix, "_") {
prefix = prefix + "_"
prefix += "_"
}
p.envVarPrefix = prefix
}
Expand Down Expand Up @@ -697,7 +697,7 @@ func (p *Parser) Parse(args []string, defaults ...string) bool {

} else {
// Parse the next command
terminating := p.parseCommand(state, cmdQueue, &commandPathSlice)
terminating, cmd := p.parseCommand(state, cmdQueue, &commandPathSlice)
currentCommandPath = strings.Join(commandPathSlice, " ")
// Inject relevant environment variables for the current command context
if instanceCount, exists := envInserted[currentCommandPath]; !exists || instanceCount < cmdQueue.Len() {
Expand All @@ -722,6 +722,11 @@ func (p *Parser) Parse(args []string, defaults ...string) bool {
lastCommandPath = currentCommandPath
commandPathSlice = commandPathSlice[:0]
}

if cmd != nil && cmd.Greedy {
p.greedyAfterPos = state.Pos() + 1
break
}
}
}

Expand Down Expand Up @@ -1717,8 +1722,8 @@ func (p *Parser) GetCompletionData() completion.CompletionData {
cmd := ""
flagName := flag
if len(flagParts) > 1 {
cmd = flagParts[0]
flagName = flagParts[1]
flagName = flagParts[0]
cmd = flagParts[1]
}

addFlagToCompletionData(&data, cmd, flagName, flagInfo, p.renderer)
Expand Down Expand Up @@ -2046,10 +2051,8 @@ func (p *Parser) PrintHelp(writer io.Writer) {
switch style {
case HelpStyleFlat:
p.printFlatHelp(writer)
case HelpStyleGrouped:
case HelpStyleGrouped, HelpStyleGroupedClean:
p.printGroupedHelp(writer)
case HelpStyleGroupedClean:
p.printGroupedCleanHelp(writer)
case HelpStyleCompact:
p.printCompactHelp(writer)
case HelpStyleHierarchical:
Expand All @@ -2072,7 +2075,7 @@ func (p *Parser) DefaultPrettyPrintConfig() *PrettyPrintConfig {
NewCommandPrefix: " + ",
DefaultPrefix: " ├─ ",
TerminalPrefix: " └─ ",
InnerLevelBindPrefix: " ** ",
InnerLevelBindPrefix: " ",
OuterLevelBindPrefix: " │ ",
}
}
Expand Down
Loading
Loading