fix(complete): bash dynamic engine passes tokenized $2 instead of raw cursor word
A-completion
## Summary
The bash glue script emitted by the dynamic completion engine (`CompleteEnv` / `write_registration` in `clap_complete/src/env/shells.rs`) uses `words[COMP_CWORD]="$2"` to capture the word under the cursor. This is incorrect: `$2` is bash's tokenized word, which word-splits on spaces. As a result, completion breaks for arguments that contain spaces.
## Reproduction
Any CLI using `CompleteEnv` with an argument that can contain spaces — for example a `--reader` flag whose value is a reader name like `"Yubico YubiKey OTP+FIDO+CCID 00 00"`:
```bash
$ mycli --reader "Yubico YubiKey <TAB>
# completer receives "YubiKey" instead of "Yubico YubiKey "
# completion fails or produces wrong results
```
## Root cause
The bash-4 guard in the generated script:
```bash
if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
words[COMP_CWORD]="$2"
fi
```
`$2` in a completion function is the word under the cursor as tokenized by readline — it splits on whitespace. For space-containing arguments, this loses the portion before the last space.
## Fix
Read `COMP_LINE` up to `COMP_POINT` and strip the last word-break prefix, exactly as the **static** bash generator already does since `clap_complete` 4.4.6:
```bash
if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
local _cur="${COMP_LINE:0:${COMP_POINT}}"
_cur="${_cur##* }"
words[COMP_CWORD]="${_cur}"
fi
```
This fix was applied to the static generator (`aot/shells/bash.rs`) in 4.4.6 but was never ported to the dynamic engine (`env/shells.rs`).
## PR
A fix is proposed in https://github.com/douzebis/clap/tree/fix-bash-dynamic-completion-words-compopt — PR to follow.
关闭于 2026-05-06 1 条评论