{Core} Proof of concept for PowerShell argument completion#13576
{Core} Proof of concept for PowerShell argument completion#13576tibortakacs wants to merge 2 commits intoAzure:devfrom
Conversation
|
Nice PoC to support PowerShell argument completion |
|
+ Azure PowerShell owner of auto-complete @isra-fel |
|
FYI, this is the corresponding Bash script to enable auto-complete using argcomplete: $ register-python-argcomplete az
# Run something, muting output or redirecting it to the debug stream
# depending on the value of _ARC_DEBUG.
__python_argcomplete_run() {
if [[ -z "$_ARC_DEBUG" ]]; then
"$@" 8>&1 9>&2 1>/dev/null 2>&1
else
"$@" 8>&1 9>&2 1>&9 2>&1
fi
}
_python_argcomplete() {
local IFS=$'\013'
local SUPPRESS_SPACE=0
if compopt +o nospace 2> /dev/null; then
SUPPRESS_SPACE=1
fi
COMPREPLY=( $(IFS="$IFS" \
COMP_LINE="$COMP_LINE" \
COMP_POINT="$COMP_POINT" \
COMP_TYPE="$COMP_TYPE" \
_ARGCOMPLETE_COMP_WORDBREAKS="$COMP_WORDBREAKS" \
_ARGCOMPLETE=1 \
_ARGCOMPLETE_SUPPRESS_SPACE=$SUPPRESS_SPACE \
__python_argcomplete_run "$1") )
if [[ $? != 0 ]]; then
unset COMPREPLY
elif [[ $SUPPRESS_SPACE == 1 ]] && [[ "$COMPREPLY" =~ [=/:]$ ]]; then
compopt -o nospace
fi
}
complete -o nospace -o default -o bashdefault -F _python_argcomplete az |
|
An idea about how to enable autocomplete on startup: we can tell the user to add a line to their powershell profile, to be specific:
And I think a more official(pro) way is to publish this as a powershell module for example
|
src/azure-cli/az.completion.ps1
Outdated
| # If there is only one completion item, it will be immediately used. In this case | ||
| # a trailing space is important to show the user that the complition for the current | ||
| # item is ready. | ||
| $items = $completionResult.Split() |
There was a problem hiding this comment.
If Invoke-Expression failed, $completionResult will not have a Split() method and will error out.
There was a problem hiding this comment.
Valid point. However, PowerShell argument completion engine hides all error, but you are right, it is better to cause any unexpected error. I have added a simple check there.
|
Hi, |
| # Since the environment variables are set, the argcomplete.autocomplete(...) function will be executed. | ||
| # The result will be printed on the standard output (see the details in the Python file). | ||
| try { | ||
| Invoke-Expression $AzCommand -OutVariable completionResult -ErrorVariable errorOut -ErrorAction SilentlyContinue | Out-Null |
There was a problem hiding this comment.
There's no need to use Invoke-Expression here, instead, you should use:
| Invoke-Expression $AzCommand -OutVariable completionResult -ErrorVariable errorOut -ErrorAction SilentlyContinue | Out-Null | |
| $completionResult = & $AzCommand |
There was a problem hiding this comment.
This comment is no longer applicable with the larger comment above, but leaving here as informing when not to use Invoke-Expression
SteveL-MSFT
left a comment
There was a problem hiding this comment.
Very interesting approach, some rework on the PowerShell side of things
| } | ||
|
|
||
| # Mock bash with environment variable settings | ||
| New-Item -Path Env: -Name _ARGCOMPLETE -Value 1 | Out-Null # Enables tab complition in argcomplete |
There was a problem hiding this comment.
This is a very creative approach using the bash completer, however, since these env vars are for the process and gets inherited by az and then removed, it would be better to use .NET API to start the process and leveraging https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.environmentvariables?view=net-6.0#system-diagnostics-processstartinfo-environmentvariables
It would look something like:
$env = @{
_ARGCOMPLETE = 1
COMP_TYPE = 9
_ARGCOMPLETE_IFS = " "
}
$psi = [System.Diagnostics.ProcessStartInfo]::new($AzCommand)
$psi.RedirectStandardError = $true
$psi.RedirectStandardOutput = $true
foreach ($var in $env.keys) {
$psi.Environment.Add($var, $env.$var)
}
$az = [System.Diagnostics.Process]::Start($psi)
$az.Start()
$az.WaitForExit()
$completionResult = $az.StandardOutput.ReadToEnd()| # Since the environment variables are set, the argcomplete.autocomplete(...) function will be executed. | ||
| # The result will be printed on the standard output (see the details in the Python file). | ||
| try { | ||
| Invoke-Expression $AzCommand -OutVariable completionResult -ErrorVariable errorOut -ErrorAction SilentlyContinue | Out-Null |
There was a problem hiding this comment.
This comment is no longer applicable with the larger comment above, but leaving here as informing when not to use Invoke-Expression
| @@ -0,0 +1,67 @@ | |||
| $AzCommand = "az" | |||
There was a problem hiding this comment.
This whole script should probably be in a Enable-AzCompletion cmdlet and shouldn't be repeated in both a ps1 and psm1
|
Thank you for this contribution @tibortakacs. Please see the feedback above. |
|
Following up @tibortakacs |
Resolve #2324
Require kislyuk/argcomplete#302
This is a proof of concept implementation of Azure CLI argument completion in PowerShell.
Not ready to be merged.
It is based on this approach, please find the details there:
https://github.com/tibortakacs/powershell-argcomplete
How to use:
. az.completion.ps1(Dot source the completion script).taborctrl+spaceto invoke argument completion on PowerShell.