Skip to content

Improve shell completions for buf flags#4416

Open
stefanvanburen wants to merge 3 commits intomainfrom
svanburen/flag-completions
Open

Improve shell completions for buf flags#4416
stefanvanburen wants to merge 3 commits intomainfrom
svanburen/flag-completions

Conversation

@stefanvanburen
Copy link
Copy Markdown
Member

This takes a pass at improving the shell completions provided by buf by wiring into cobra's completion system.

This:

  • Adds completions for "enum" based flags (provides the potential values; disables flags & generally orders from most-used to least-used)
  • Adds directory-only completions for --output in generate and export
  • Adds file-extension completions for --template (yaml extensions) and --binary (wasm)
  • Disables file completions for free-form string flags like --label, --source-control-url, --header, etc. where it's unlikely that a user would want to supply a local file name

Implementation-wise, this is all wired up under ModifyCobra, so we need the latest version of app-go which fixes that working on subcommands. It generally uses errors.Join just to simplify the error cases, which should not occur. Shared completions are in private/buf/bufcli/completions.go.

Vaguely related to #4402, which is aiming to add more dynamic completions. In that PR, I mentioned further improvements to completions for more dynamic situations, but this should shore up the "base case" of the relatively straightforward static-ish completions.

The first commit also fixes rendering in a command's --help to be consistent with how we display other "enum" flags.

Ref: https://cobra.dev/docs/how-to-guides/shell-completion/

To match the others, which do `option1,option2,option3`, instead of
`option1 option2 option3`.
This takes a pass at improving the shell completions provided by `buf`
by wiring into cobra's completion system.

This:

* Adds completions for "enum" based flags (provides the potential
  values; disables flags & generally orders from most-used to least-used)
* Adds directory-only completions for `--output` in generate and export
* Adds file-extension completions for `--template` (yaml extensions) and
  `--binary` (wasm)
* Disables file completions for free-form string flags like `--label`,
  `--source-control-url`, `--header`, etc. where it's unlikely that
  a user would want to supply a local file name

Implementation-wise, this is all wired up under ModifyCobra, so we need
the latest version of app-go which fixes that working on subcommands. It
generally uses `errors.Join` just to simplify the error cases, which
should not occur. Shared completions are in
`private/buf/bufcli/completions.go`.

Vaguely related to #4402, which is aiming to add more dynamic
completions. In that PR, I mentioned further improvements to completions
for more dynamic situations, but this should shore up the "base case" of
the relatively straightforward static-ish completions.

Ref: https://cobra.dev/docs/how-to-guides/shell-completion/
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 26, 2026

The latest Buf updates on your PR. Results from workflow Buf CI / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedMar 26, 2026, 2:55 PM

@stefanvanburen
Copy link
Copy Markdown
Member Author

Similar demo gif from #4402

completions

tape:

Output .tmp/completions.gif

Set Shell fish
Set FontSize 14
Set Width 1100
Set Height 500
Set Padding 16
Set Theme "Github"

Env PATH "/Users/stefanvanburen/src/buf/.tmp:/Users/stefanvanburen/.cache/buf/Darwin/arm64/gobin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"

Hide
Sleep 1s
Type "buf completion fish | source"
Enter
Sleep 500ms
Show
Ctrl+L
Sleep 300ms

# --error-format: 6+ values with descriptions
Type "buf lint --error-format "
Sleep 500ms
Tab
Sleep 2500ms
Ctrl+C
Sleep 800ms
Ctrl+L
Sleep 300ms

# --version: v2 first (KeepOrder)
Type "buf config ls-lint-rules --version "
Sleep 500ms
Tab
Sleep 2000ms
Ctrl+C
Sleep 800ms
Ctrl+L
Sleep 300ms

# --visibility: public/private
Type "buf registry module create buf.build/acme/petapis --visibility "
Sleep 500ms
Tab
Sleep 2000ms
Ctrl+C
Sleep 800ms
Ctrl+L
Sleep 300ms

# --format on registry commands: text/json with descriptions
Type "buf registry module info buf.build/acme/petapis --format "
Sleep 500ms
Tab
Sleep 2000ms
Ctrl+C
Sleep 800ms
Ctrl+L
Sleep 300ms

# buf curl --protocol: connect/grpc/grpcweb with descriptions
Type "buf curl --protocol "
Sleep 500ms
Tab
Sleep 2000ms
Ctrl+C
Sleep 800ms
Ctrl+L
Sleep 300ms

# buf generate --template: FilterFileExt (.yaml/.yml/.json)
Type "buf generate --template "
Sleep 500ms
Tab
Sleep 2000ms
Ctrl+C
Sleep 500ms

@stefanvanburen stefanvanburen marked this pull request as ready for review March 26, 2026 14:36
For the most part, these are duplicative; they add noise to the output
without much additional signal. There are only a couple values that may
not be obvious in context; leaving those in for now.
@stefanvanburen
Copy link
Copy Markdown
Member Author

stefanvanburen commented Mar 26, 2026

Removed most of the descriptions in eaee6ba; updated demo gif:

completions

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