Skip to content

Commit

Permalink
fix zshell completions after = symbol
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidGamba committed Sep 29, 2023
1 parent af5a9cf commit 24025a3
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 7 deletions.
15 changes: 10 additions & 5 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ type completions []string
// parseCLIArgs - Given the root node tree and the cli args it returns a populated tree of the node that was called.
// For example, if a command is called, then the returned node is that of the command with the options that were set updated with their values.
// Additionally, when in completion mode, it returns the possible completions
func parseCLIArgs(completionMode bool, tree *programTree, args []string, mode Mode) (*programTree, completions, error) {
func parseCLIArgs(completionMode string, tree *programTree, args []string, mode Mode) (*programTree, completions, error) {
// Design: This function could return an array or CLIargs as a parse result
// or I could do one level up and have a root CLIarg type with the name of
// the program. Having the root level might be helpful with help generation.
Expand All @@ -177,14 +177,14 @@ func parseCLIArgs(completionMode bool, tree *programTree, args []string, mode Mo

ARGS_LOOP:
for iterator.Next() ||
(completionMode && len(args) == 0) { // enter at least once if running in completion mode.
(completionMode != "" && len(args) == 0) { // enter at least once if running in completion mode.

///////////////////////////////////
// Completions
///////////////////////////////////

// We only generate completions when we reached the end of the provided args
if completionMode && (iterator.IsLast() || len(args) == 0) {
if completionMode != "" && (iterator.IsLast() || len(args) == 0) {
completions := []string{}

// Options
Expand Down Expand Up @@ -220,8 +220,13 @@ ARGS_LOOP:
for _, e := range lastOpt.SuggestedValues {
c := fmt.Sprintf("--%s=%s", k, e)
if strings.HasPrefix(c, iterator.Value()) {
tc := strings.SplitN(c, "=", 2)[1]
completions = append(completions, tc)
// NOTE: Bash completions have = as a special char and results should be trimmed form the = on.
if completionMode == "bash" {
tc := strings.SplitN(c, "=", 2)[1]
completions = append(completions, tc)
} else {
completions = append(completions, c)
}
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions user.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ func (gopt *GetOpt) SetCommandFn(fn CommandFn) *GetOpt {
func (gopt *GetOpt) Parse(args []string) ([]string, error) {
compLine := os.Getenv("COMP_LINE")
if compLine != "" {
completionMode := "bash"
zsh := os.Getenv("ZSHELL")
if zsh != "" {
completionMode = "zsh"
}
// COMP_LINE has a single trailing space when the completion isn't complete and 2 when it is
re := regexp.MustCompile(`\s+`)
compLineParts := re.Split(compLine, -1)
Expand All @@ -311,7 +316,7 @@ func (gopt *GetOpt) Parse(args []string) ([]string, error) {
// NOTE: Bash completions have = as a special char and results should be trimmed form the = on.
Logger.SetPrefix("\n")
Logger.Printf("COMP_LINE: '%s', parts: %#v, args: %#v\n", compLine, compLineParts, args)
_, completions, err := parseCLIArgs(true, gopt.programTree, compLineParts, Normal)
_, completions, err := parseCLIArgs(completionMode, gopt.programTree, compLineParts, Normal)
if err != nil {
fmt.Fprintf(Writer, "\nERROR: %s\n", err)
exitFn(124) // programmable completion restarts from the beginning, with an attempt to find a new compspec for that command.
Expand All @@ -332,7 +337,7 @@ func (gopt *GetOpt) Parse(args []string) ([]string, error) {
// I came up with the conclusion that dispatch provides a bunch of flexibility and explicitness.

// TODO: parseCLIArgs needs to return the remaining array
node, _, err := parseCLIArgs(false, gopt.programTree, args, gopt.programTree.mode)
node, _, err := parseCLIArgs("", gopt.programTree, args, gopt.programTree.mode)
gopt.finalNode = node
if err != nil {
return nil, err
Expand Down

0 comments on commit 24025a3

Please sign in to comment.