Please complete the following tasks
Rust Version
1.96.0
Clap Version
clap 4.6.1 and clap_complete 4.6.5
Minimal reproducible code
use clap::{CommandFactory, Parser};
use clap_complete::{Shell, generate};
use std::io;
#[derive(Parser)]
struct Args {
arg: Option<String>,
}
fn main() {
generate(
Shell::Bash,
&mut Args::command(),
"clap_bug",
&mut io::stdout(),
);
}
Steps to reproduce the bug with the above code
In Bash:
source <(cargo run --quiet)
shopt -s failglob
- Type "clap_bug " (including the space) and trigger completion with tab
Actual Behaviour
There are 3 variations on the behavior: Bash default, nullglob enabled, and failglob enabled.
In all 3 cases, when showing the completion, an optional argument enclosed in square brackets is treated as a pattern matching bracket expression. This will attempt to match any single character contained within the brackets. As this is a filename expansion context, it will attempt to match filenames in the current directory. For example, in this case the completion generated by clap is [ARG], and so it will match the filenames A, R, and G:

If there are no matching filenames, the behavior depends on the current configuration:
If both failglob and nullglob are disabled, it will appear to work "correctly" and it is treated as a literal string:

If nullglob is enabled, the argument will just be missing from the completion:

If failglob is enabled, it will immediately abort completion with an error:

Expected Behaviour
It should always be a literal string, instead of a match pattern, so that it behaves consistently across these 3 modes and is not affected by directory contents.
Additional Context
I tried modifying the generated completion in a few ways to fix this (various combinations of backslashes and single quotes) and couldn't find anything that worked consistently. I think really the completion just should not be including placeholders like this, since it's not actually a valid argument. For example, I found this through bob, where it tried to show [VERSION] as a completion option for bob uninstall. If bob uninstall had no other completion candidates, fixing this issue would mean that it would complete with the literal text [VERSION], which isn't actually a valid argument for that program. It would also then trigger pattern matching if I were to hit enter without deleting that text:
I don't know much about non-Bash shells but I wouldn't be surprised if this affects Zsh as well.
Edit: It looks like clap's generated completions for Zsh instead have it just fall back to the default completion of filenames for these cases instead of trying to use a placeholder.
Debug Output
No response
Please complete the following tasks
Rust Version
1.96.0
Clap Version
clap 4.6.1 and clap_complete 4.6.5
Minimal reproducible code
Steps to reproduce the bug with the above code
In Bash:
source <(cargo run --quiet)shopt -s failglobActual Behaviour
There are 3 variations on the behavior: Bash default, nullglob enabled, and failglob enabled.
In all 3 cases, when showing the completion, an optional argument enclosed in square brackets is treated as a pattern matching bracket expression. This will attempt to match any single character contained within the brackets. As this is a filename expansion context, it will attempt to match filenames in the current directory. For example, in this case the completion generated by clap is

[ARG], and so it will match the filenames A, R, and G:If there are no matching filenames, the behavior depends on the current configuration:

If both failglob and nullglob are disabled, it will appear to work "correctly" and it is treated as a literal string:
If nullglob is enabled, the argument will just be missing from the completion:

If failglob is enabled, it will immediately abort completion with an error:

Expected Behaviour
It should always be a literal string, instead of a match pattern, so that it behaves consistently across these 3 modes and is not affected by directory contents.
Additional Context
I tried modifying the generated completion in a few ways to fix this (various combinations of backslashes and single quotes) and couldn't find anything that worked consistently. I think really the completion just should not be including placeholders like this, since it's not actually a valid argument. For example, I found this through bob, where it tried to show
[VERSION]as a completion option forbob uninstall. Ifbob uninstallhad no other completion candidates, fixing this issue would mean that it would complete with the literal text[VERSION], which isn't actually a valid argument for that program. It would also then trigger pattern matching if I were to hit enter without deleting that text:I don't know much about non-Bash shells but I wouldn't be surprised if this affects Zsh as well.Edit: It looks like clap's generated completions for Zsh instead have it just fall back to the default completion of filenames for these cases instead of trying to use a placeholder.
Debug Output
No response