tidy up extractions and dynamic completion placement

This commit is contained in:
atagen 2026-05-21 21:02:59 +10:00
parent 2dab68fe03
commit aed5e5c8bc
7 changed files with 600 additions and 104 deletions

View file

@ -1912,7 +1912,11 @@ fn cmd_complete(
None => Vec::new(),
Some((matched_name, r, depth)) => {
let mut scored: Vec<(i32, String)> = Vec::new();
// subcommand candidates (skip if match is too shallow)
// subcommand candidates (skip if match is too shallow). when the
// typed token *exactly* equals a candidate we drop it — the user
// has already written the full word; echoing it back masks any
// dynamic completer downstream (e.g. systemctl unit names after
// `systemctl status`).
if *depth >= lookup_depth.saturating_sub(1) {
let subs: Vec<ManpageSubcommand> = if !r.subcommands.is_empty() {
r.subcommands.clone()
@ -1920,6 +1924,9 @@ fn cmd_complete(
subcommands_of(&dirs, matched_name)
};
for sc in &subs {
if !last_token.is_empty() && last_token == sc.name {
continue;
}
let s = fuzzy_score(&last_token, &sc.name);
if s > 0 {
scored.push((s, completion_json(&sc.name, &sc.desc)));
@ -1961,6 +1968,9 @@ fn cmd_complete(
}
}
};
if !last_token.is_empty() && last_token == flag {
continue;
}
let s = fuzzy_score(&last_token, &flag);
if s > 0 {
scored.push((s, completion_json(&flag, &desc)));