nushell: type extern positionals as glob, not string

A `string`-typed parameter in an `export extern` makes nushell stop
tilde- and glob-expanding that argument, unlike a bareword argument to an
unknown external (which expands both). The generated completions therefore
changed runtime parsing: a command like `nh os switch ~/cfg` reached the
program as a literal `~/cfg` once its extern was loaded. Fall back to
`glob` for positionals — it expands tilde and globs exactly like a native
external arg, so the extern still only adds completions without altering
how arguments are passed. Flag values are left as `string` since those are
frequently literal text.
This commit is contained in:
Amaan Qureshi 2026-05-24 21:51:41 -04:00 committed by atagen
parent 2682ed958b
commit 8d67380c44
2 changed files with 7 additions and 4 deletions

View file

@ -284,7 +284,10 @@ pub fn format_positional(name: &str, p: &Positional) -> String {
.collect();
let prefix = if p.variadic { "..." } else { "" };
let suffix = if p.optional && !p.variadic { "?" } else { "" };
let typ = nushell_type_of_param(&name.to_ascii_uppercase());
let typ = match nushell_type_of_param(&name.to_ascii_uppercase()) {
"string" => "glob",
other => other,
};
format!(" {prefix}{name_underscored}{suffix}: {typ}")
}

View file

@ -339,8 +339,8 @@ Print a short usage summary and exit.
);
let nu = generate_extern("getent", &r);
assert!(nu.contains("database: string"), "nu = {nu}");
assert!(nu.contains("...key: string"), "nu = {nu}");
assert!(nu.contains("database: glob"), "nu = {nu}");
assert!(nu.contains("...key: glob"), "nu = {nu}");
assert!(nu.contains("--service(-s): string"), "nu = {nu}");
assert!(!nu.contains("--servicedatabase"), "nu = {nu}");
assert!(nu.contains("export extern \"getent passwd\""), "nu = {nu}");
@ -781,7 +781,7 @@ fn positional_order_survives_cache_and_generation() {
let nu = generate_extern("git clone", &cached);
let repository = nu
.find("repository: string")
.find("repository: glob")
.expect("repository positional");
let directory = nu.find("directory?: path").expect("directory positional");
assert!(repository < directory, "nu = {nu}");