diff --git a/clap_complete/src/env/mod.rs b/clap_complete/src/env/mod.rs index 9d7f59cf5a1..8902484a57d 100644 --- a/clap_complete/src/env/mod.rs +++ b/clap_complete/src/env/mod.rs @@ -52,7 +52,9 @@ //! //! Powershell //! ```powershell -//! echo "COMPLETE=powershell your_program | Invoke-Expression" >> $PROFILE +//! $env:COMPLETE = "powershell" +//! echo "your_program | Out-String | Invoke-Expression" >> $PROFILE +//! Remove-Item Env:\COMPLETE //! ``` //! //! Zsh diff --git a/clap_complete/src/env/shells.rs b/clap_complete/src/env/shells.rs index 5600927d9c9..427e214917b 100644 --- a/clap_complete/src/env/shells.rs +++ b/clap_complete/src/env/shells.rs @@ -274,13 +274,25 @@ impl EnvCompleter for Powershell { let completer = shlex::try_quote(completer).unwrap_or(std::borrow::Cow::Borrowed(completer)); + // `completer` may or may not be surrounded by double quotes, enclosing + // the expression in a here-string ensures the whole thing is + // interpreted as the first argument to the call operator writeln!( buf, r#" Register-ArgumentCompleter -Native -CommandName {bin} -ScriptBlock {{ param($wordToComplete, $commandAst, $cursorPosition) - $results = Invoke-Expression "{var}=powershell &{completer} -- $($commandAst.ToString())"; + $prev = $env:{var}; + $env:{var} = "powershell"; + $results = Invoke-Expression @" +& {completer} -- $commandAst +"@; + if ($null -eq $prev) {{ + Remove-Item Env:\{var}; + }} else {{ + $env:{var} = $prev; + }} $results | ForEach-Object {{ $split = $_.Split("`t"); $cmd = $split[0];