I've written a command line utility in Rust, with argument completion provided by the clap_complete
crate. This generates Bash and PowerShell completion scripts:
$ ex --completion=bash
_ex() {
local i cur prev opts cmd
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
cmd=""
opts=""
...
$ ex --completion=ps
using namespace System.Management.Automation
using namespace System.Management.Automation.Language
Register-ArgumentCompleter -Native -CommandName 'ex' -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
...
I can support argument completion in new interactive Bash sessions by updating my .bashrc
file with this line, which uses process substitution to evaluate the command output:
source <(ex --completion=bash)
How can I do the same thing in PowerShell? I've done a lot of Googling, and found plenty of pages describing how to call external scripts, such as with the Invoke-Expression
cmdlet, but nothing that tells me how to eval the output of external scripts.
Invoke-Expression
doesn't call a script, it evaluates a string. So the first step is to evaluate, which is basically the same as in bash.
ex --completion=ps
If this was one line, this would be a string, but it's multiple lines, so this returns an array of strings. You need to join them. Out-String
is one way of doing that.
ex --completion=ps | Out-String
This can be fed into Invoke-Expression
.
ex --completion=ps | Out-String | Invoke-Expression
You can put this line in your powershell profile.