clap
clap copied to clipboard
Dynamic completion for powershell repeats last word when completing next argument
Please complete the following tasks
- [x] I have searched the discussions
- [x] I have searched the open and rejected issues
Rust Version
rustc 1.88.0-nightly (27d6200a7 2025-05-06)
Clap Version
4.5.38
Minimal reproducible code
use clap::{CommandFactory as _, Parser};
#[derive(Parser, Debug)]
#[command(version, name = "demo")]
struct Args {}
fn main() {
clap_complete::env::CompleteEnv::with_factory(Args::command).complete();
}
Steps to reproduce the bug with the above code
cargo install --path . --example demo
Invoke-Expression (& { (env COMPLETE=powershell C:/Users/user/.cargo/bin/demo | Out-String) })
demo --help <TAB>
Actual Behaviour
demo --help --help
Expected Behaviour
demo --help --
Additional Context
This is because the powershell EnvCompleter determines the argument index based on the parsed args vec, which does not contain an empty element at the end:
https://github.com/clap-rs/clap/blob/e2188d9af318f3287c1c5a52cba6b9dfebe7bb75/clap_complete/src/env/shells.rs#L322
Register-ArgumentCompleter comes with $cursorPosition, but that gives you the actual column index in the command, which you can't trivially turn into an argument index.
Possible Solutions
- in the powershell glue code, select the correct word index based on
$commandAst.ToString()and$cursorPositionand pass that via_CLAP_COMPLETE_INDEX - pass the raw
$commandAst.ToString()and$cursorPositionto the binary and determine the argument index there - If we're at the end of the text, pass an extra empty argument to the binary:
& {completer} -- $commandAst ''. That way it computes the argument index correctly.
Or maybe something I've missed.
Debug Output
No response