Skip to content

feat: dynamic shell completion, starting with bash - #1422

Open
cachelous wants to merge 18 commits into
CLIUtils:mainfrom
cachelous:feat/completion
Open

feat: dynamic shell completion, starting with bash#1422
cachelous wants to merge 18 commits into
CLIUtils:mainfrom
cachelous:feat/completion

Conversation

@cachelous

@cachelous cachelous commented Aug 2, 2026

Copy link
Copy Markdown

Part of #343. For now only bash is supported, I will work on zsh/fish on later PRs.

Instead of generating a static script that encodes the app's options, the script is a small fixed adaptor: it re-invokes the binary with the line being completed, and the binary replies with candidates and a directive. Rationale in #343. A detailed explanation is included in book/chapters/completion.md.

How to try it out

To see the current state of completion in action (from a bash shell with bash-completion):

cmake --workflow default && cd build
PATH="$PWD/examples:$PATH"
source <(completion --completion bash)
completion <TAB>
# and start playing around with different args

To see the wire protocol directly, without a shell in the way:

$ CLI11_COMPLETE=bash CLI11_COMPLETE_INDEX=1 CLI11_COMPLETE_PROTO=1 completion --l
--level       How hard to try
:2

Status

Working end to end for bash:

  • Subcommands, including nested ones and aliases
  • Option names, with their descriptions
  • Values from validators
  • --opt=value, and values written onto short names and bundles
  • Path completion, delegated to the shell
  • -- and ++
  • Positionals, at both multiplicities
  • /flag:value under allow_windows_style_options
  • Options and positionals declared in nameless option groups
  • Name matching that honours ignore_case and ignore_underscore the way a parse does

Deliberately not in this PR, happy to follow up:

  • zsh, fish and powershell generators
  • Per Option completion callbacks
  • Candidate grouping
  • Dot notation (teaching completion that --sub.opt takes a value)

Reviewing commit-by-commit will be easier than the squashed diff, as each commit is one capability with its own tests.

@henryiii

henryiii commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Let me know if you want any help rebasing. Sorry for the conflicts, I'm done for a bit (was working on improving compile time performance).

@cachelous
cachelous force-pushed the feat/completion branch 5 times, most recently from a16b16f to 37c1234 Compare August 7, 2026 08:08
- Guard the option group tests that use IsMember behind the extra
  validators macro.
- Rename the locals and the parameter that shadow App's own name(),
  alias() and disabled(), which gcc 4.8 rejects under -Werror=shadow.
- Strip a trailing carriage return from each reply line in the generated
  script: a program built for Windows writes CRLF, and the return only
  showed on a candidate that carries no description.
- Drive the script with eval rather than source <(...), which reads
  nothing under the bash 3.2 that macOS ships.
- Add the includes cpplint asks for, mark completion_test.sh executable
  so its shebang stops failing pre-commit, and take the cmake-format and
  module export ordering pre-commit asked for.
- Reduce the scope of test argument vectors.
@cachelous

Copy link
Copy Markdown
Author

No worries! Almost no conflicts 😄

The PR is ready for review now. Just one thing, not sure how to handle the 7 unusedStructMember warnings from cppcheck on the new completion structs (the members are only read from the _inl.hpp files, which cppcheck doesn't see. Any preference on how to deal with this?

@cachelous
cachelous marked this pull request as ready for review August 7, 2026 08:31
@cachelous

Copy link
Copy Markdown
Author

Went ahead and silenced the unusedStructMember warnings with cppcheck-suppress inline comments, as they are used after all. No rush on the review, I know it's a big diff. If it helps, I am happy to split it into smaller PRs

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.

2 participants