ITADN

Some visible aliases missing in dynamic completion

#6317Opennekomoyi 创建于 2026-03-26
C-bugA-completionS-triage
N
nekomoyicommented
### Please complete the following tasks - [x] I have searched the [discussions](https://github.com/clap-rs/clap/discussions) - [x] I have searched the [open](https://github.com/clap-rs/clap/issues) and [rejected](https://github.com/clap-rs/clap/issues?q=is%3Aissue+label%3AS-wont-fix+is%3Aclosed) issues ### Rust Version rustc 1.94.0 (4a4ef493e 2026-03-02) ### Clap Version clap 4.5.60 clap_complete 4.6.0 ### Minimal reproducible code ```rust use clap::{CommandFactory, Parser, Subcommand}; use clap_complete::engine::complete; use std::ffi::OsString; #[derive(Parser)] #[command(name = "test")] struct Cli { #[command(subcommand)] command: Option<Commands>, } #[derive(Subcommand)] enum Commands { #[command(name = "install", visible_alias = "i")] Install, #[command(name = "remove", visible_alias = "rm")] Remove, } fn main() { let mut cmd = Cli::command(); println!("Completions for `cli-name`:"); let args: Vec<OsString> = vec![OsString::from("cli-name"), OsString::from("")]; let completions = complete(&mut cmd, args, 1, None).unwrap(); for c in &completions { println!(" {}", c.get_value().to_string_lossy()); } println!("Completions for `cli-name i`:"); let args: Vec<OsString> = vec![OsString::from("cli-name"), OsString::from("i")]; let completions = complete(&mut cmd, args, 1, None).unwrap(); for c in &completions { println!(" {}", c.get_value().to_string_lossy()); } println!("Completions for `cli-name in`"); let args: Vec<OsString> = vec![OsString::from("cli-name"), OsString::from("in")]; let completions = complete(&mut cmd, args, 1, None).unwrap(); for c in &completions { println!(" {}", c.get_value().to_string_lossy()); } } ``` ### Steps to reproduce the bug with the above code cargo run ### Actual Behaviour When using dynamic completion with `clap_complete::engine::complete()`, visible aliases for subcommands are not all shown. For example, with a subcommand named `install` and visible alias `i`: - Typing `i<TAB>` shows only `i` - Typing `in<TAB>` shows `install` This happens because after sorting candidates alphabetically (`i` comes before `install`), the dedup logic removes `install` since it shares the same `id`. ### Expected Behaviour Both the primary command name and all its visible aliases should appear in the completion list when the input matches them. For `install` with alias `i`: - Typing `i<TAB>` should show both `i` and `install` - Typing `in<TAB>` should show `install` This matches the behavior of static completion (`clap_complete::generate()`), which correctly includes all visible aliases. ### Additional Context In `clap_complete/src/engine/complete.rs`: 1. `populate_command_candidate()` assigns the same `id` to a subcommand and all its visible aliases: https://github.com/clap-rs/clap/blob/70f3bb31874ff24233f18c394982407ca90d0dcc/clap_complete/src/engine/complete.rs#L578-L587 2. `complete_subcommand` then sorts it https://github.com/clap-rs/clap/blob/70f3bb31874ff24233f18c394982407ca90d0dcc/clap_complete/src/engine/complete.rs#L453 2. complete_arg() then deduplicates by id, keeping only the first occurrence which is subject to that sort https://github.com/clap-rs/clap/blob/70f3bb31874ff24233f18c394982407ca90d0dcc/clap_complete/src/engine/complete.rs#L202-L209 ### Debug Output _No response_
3 条评论