diff --git a/Cargo.lock b/Cargo.lock index 37c5759015e..c563d087d3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -503,6 +503,7 @@ dependencies = [ "clap_lex 0.7.4", "completest", "completest-pty", + "home", "is_executable", "shlex", "snapbox", diff --git a/clap_complete/Cargo.toml b/clap_complete/Cargo.toml index 6cb6f10cb7d..be5aaed57a3 100644 --- a/clap_complete/Cargo.toml +++ b/clap_complete/Cargo.toml @@ -40,6 +40,7 @@ is_executable = { version = "1.0.1", optional = true } shlex = { version = "1.3.0", optional = true } completest = { version = "0.4.2", optional = true } completest-pty = { version = "0.5.5", optional = true } +home = { version = "0.5.0", optional = true } [dev-dependencies] snapbox = { version = "0.6.0", features = ["diff", "dir", "examples"] } @@ -55,7 +56,7 @@ required-features = ["unstable-dynamic"] [features] default = [] unstable-doc = ["unstable-dynamic"] # for docs.rs -unstable-dynamic = ["dep:clap_lex", "dep:shlex", "dep:is_executable", "clap/unstable-ext"] +unstable-dynamic = ["dep:clap_lex", "dep:shlex", "dep:is_executable", "dep:home", "clap/unstable-ext"] unstable-shell-tests = ["dep:completest", "dep:completest-pty"] debug = ["clap/debug"] diff --git a/clap_complete/src/engine/custom.rs b/clap_complete/src/engine/custom.rs index a81f0b02848..1ba9332f0b1 100644 --- a/clap_complete/src/engine/custom.rs +++ b/clap_complete/src/engine/custom.rs @@ -274,7 +274,19 @@ impl ValueCompleter for PathCompleter { current_dir_actual = std::env::current_dir().ok(); current_dir_actual.as_deref() }); - let mut candidates = complete_path(current, current_dir, filter); + + let Some(current) = current.to_str() else { + return vec![]; + }; + + #[cfg(unix)] + if current.starts_with("~") { + if let Some(home) = home_dir() { + current.replace_range(..1, &home.to_string_lossy()); + } + } + + let mut candidates = complete_path(¤t, current_dir, filter); if self.stdio && current.is_empty() { candidates.push(CompletionCandidate::new("-").help(Some("stdio".into()))); } @@ -283,7 +295,7 @@ impl ValueCompleter for PathCompleter { } pub(crate) fn complete_path( - value_os: &OsStr, + value_os: &str, current_dir: Option<&std::path::Path>, is_wanted: &dyn Fn(&std::path::Path) -> bool, ) -> Vec {