Skip to content

fix: complete the long alias of a short flag and the inverse of a bool flag - #2530

Open
vidigoat wants to merge 1 commit into
urfave:mainfrom
vidigoat:fix/complete-long-alias-and-inverse
Open

vidigoat wants to merge 1 commit into
urfave:mainfrom
vidigoat:fix/complete-long-alias-and-inverse

Conversation

@vidigoat

@vidigoat vidigoat commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

What type of PR is this?

  • bug

What this PR does / why we need it:

The dynamic shell completion only offers a flag's first name, and after -- it skips a flag whose first name is one letter. So two kinds of flags can't be completed in their long form:

cmd := &cli.Command{
	Name:                  "app",
	EnableShellCompletion: true,
	Flags: []cli.Flag{
		&cli.BoolFlag{Name: "v", Aliases: []string{"verbose"}, Usage: "verbose output"},
		&cli.BoolWithInverseFlag{Name: "color", Usage: "use color"},
	},
	Action: func(context.Context, *cli.Command) error { return nil },
}

In bash 5.3 with bash-completion and the script from app completion bash:

typed main with this change
app --ver<TAB> nothing --verbose
app --no<TAB> nothing --no-color
app --<TAB> --color --help --verbose --color --no-color --help

The fish script from ToFishCompletion already offers both, with complete … -s v -l verbose and complete … -l color -l no-color.

  • help.go: printFlagSuggestions gets the names to offer from a new completionNames. That is the flag's first name as before, except that after -- a flag whose first name is one letter offers its first long alias (and is still skipped if it has none). A BoolWithInverseFlag also offers the inverse of that name, with its InversePrefix. After a single -, a flag named v is still offered as -v.
  • help_test.go: four cases in TestDefaultCompleteWithFlags: the long alias after --; -v still offered after -; --no completing --no-color and --no-dry-run (the inverse of a long alias); and a custom InversePrefix.

Which issue(s) this PR fixes:

None, found while comparing the dynamic completion with the fish script.

Testing

  • Three of the new cases fail on main. The -v case passes on both, since it checks what doesn't change.
  • Checked in bash 5.3 with bash-completion, as above.
  • make all, make test GFLAGS='--tags urfave_cli_no_template', make lint, make diffcheck and make v3diff pass, and so do the urfave_cli_no_docs and urfave_cli_no_suggest tags.
  • check-binary-size: the example CLI (linux/amd64, Go 1.27.3, -s -w, minus hello world) goes from 2.261MB to 2.265MB, which still rounds to 2.3MB.

Release Notes

Shell completion now offers the long alias of a flag whose name is one letter after "--", and the inverse form of a BoolWithInverseFlag, such as --no-color.

🤖 Generated with Claude Code

…l flag

The completion only offered a flag's first name, and skipped it after
"--" when it is one letter. So a flag named "v" with the alias
"verbose" could not be completed as --verbose, and a
BoolWithInverseFlag's --no-color was never offered. The fish completion
offers both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vidigoat
vidigoat requested a review from a team as a code owner November 7, 2026 18:07

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant