github.com/containers/podman/v4@v4.9.4/completions/powershell/podman.ps1 (about)

     1  # powershell completion for podman                               -*- shell-script -*-
     2  
     3  function __podman_debug {
     4      if ($env:BASH_COMP_DEBUG_FILE) {
     5          "$args" | Out-File -Append -FilePath "$env:BASH_COMP_DEBUG_FILE"
     6      }
     7  }
     8  
     9  filter __podman_escapeStringWithSpecialChars {
    10      $_ -replace '\s|#|@|\$|;|,|''|\{|\}|\(|\)|"|`|\||<|>|&','`$&'
    11  }
    12  
    13  [scriptblock]${__podmanCompleterBlock} = {
    14      param(
    15              $WordToComplete,
    16              $CommandAst,
    17              $CursorPosition
    18          )
    19  
    20      # Get the current command line and convert into a string
    21      $Command = $CommandAst.CommandElements
    22      $Command = "$Command"
    23  
    24      __podman_debug ""
    25      __podman_debug "========= starting completion logic =========="
    26      __podman_debug "WordToComplete: $WordToComplete Command: $Command CursorPosition: $CursorPosition"
    27  
    28      # The user could have moved the cursor backwards on the command-line.
    29      # We need to trigger completion from the $CursorPosition location, so we need
    30      # to truncate the command-line ($Command) up to the $CursorPosition location.
    31      # Make sure the $Command is longer then the $CursorPosition before we truncate.
    32      # This happens because the $Command does not include the last space.
    33      if ($Command.Length -gt $CursorPosition) {
    34          $Command=$Command.Substring(0,$CursorPosition)
    35      }
    36      __podman_debug "Truncated command: $Command"
    37  
    38      $ShellCompDirectiveError=1
    39      $ShellCompDirectiveNoSpace=2
    40      $ShellCompDirectiveNoFileComp=4
    41      $ShellCompDirectiveFilterFileExt=8
    42      $ShellCompDirectiveFilterDirs=16
    43      $ShellCompDirectiveKeepOrder=32
    44  
    45      # Prepare the command to request completions for the program.
    46      # Split the command at the first space to separate the program and arguments.
    47      $Program,$Arguments = $Command.Split(" ",2)
    48  
    49      $RequestComp="$Program __complete $Arguments"
    50      __podman_debug "RequestComp: $RequestComp"
    51  
    52      # we cannot use $WordToComplete because it
    53      # has the wrong values if the cursor was moved
    54      # so use the last argument
    55      if ($WordToComplete -ne "" ) {
    56          $WordToComplete = $Arguments.Split(" ")[-1]
    57      }
    58      __podman_debug "New WordToComplete: $WordToComplete"
    59  
    60  
    61      # Check for flag with equal sign
    62      $IsEqualFlag = ($WordToComplete -Like "--*=*" )
    63      if ( $IsEqualFlag ) {
    64          __podman_debug "Completing equal sign flag"
    65          # Remove the flag part
    66          $Flag,$WordToComplete = $WordToComplete.Split("=",2)
    67      }
    68  
    69      if ( $WordToComplete -eq "" -And ( -Not $IsEqualFlag )) {
    70          # If the last parameter is complete (there is a space following it)
    71          # We add an extra empty parameter so we can indicate this to the go method.
    72          __podman_debug "Adding extra empty parameter"
    73          # PowerShell 7.2+ changed the way how the arguments are passed to executables,
    74          # so for pre-7.2 or when Legacy argument passing is enabled we need to use
    75          # `"`" to pass an empty argument, a "" or '' does not work!!!
    76          if ($PSVersionTable.PsVersion -lt [version]'7.2.0' -or
    77              ($PSVersionTable.PsVersion -lt [version]'7.3.0' -and -not [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -or
    78              (($PSVersionTable.PsVersion -ge [version]'7.3.0' -or [ExperimentalFeature]::IsEnabled("PSNativeCommandArgumentPassing")) -and
    79                $PSNativeCommandArgumentPassing -eq 'Legacy')) {
    80               $RequestComp="$RequestComp" + ' `"`"'
    81          } else {
    82               $RequestComp="$RequestComp" + ' ""'
    83          }
    84      }
    85  
    86      __podman_debug "Calling $RequestComp"
    87      # First disable ActiveHelp which is not supported for Powershell
    88      ${env:PODMAN_ACTIVE_HELP}=0
    89  
    90      #call the command store the output in $out and redirect stderr and stdout to null
    91      # $Out is an array contains each line per element
    92      Invoke-Expression -OutVariable out "$RequestComp" 2>&1 | Out-Null
    93  
    94      # get directive from last line
    95      [int]$Directive = $Out[-1].TrimStart(':')
    96      if ($Directive -eq "") {
    97          # There is no directive specified
    98          $Directive = 0
    99      }
   100      __podman_debug "The completion directive is: $Directive"
   101  
   102      # remove directive (last element) from out
   103      $Out = $Out | Where-Object { $_ -ne $Out[-1] }
   104      __podman_debug "The completions are: $Out"
   105  
   106      if (($Directive -band $ShellCompDirectiveError) -ne 0 ) {
   107          # Error code.  No completion.
   108          __podman_debug "Received error from custom completion go code"
   109          return
   110      }
   111  
   112      $Longest = 0
   113      [Array]$Values = $Out | ForEach-Object {
   114          #Split the output in name and description
   115          $Name, $Description = $_.Split("`t",2)
   116          __podman_debug "Name: $Name Description: $Description"
   117  
   118          # Look for the longest completion so that we can format things nicely
   119          if ($Longest -lt $Name.Length) {
   120              $Longest = $Name.Length
   121          }
   122  
   123          # Set the description to a one space string if there is none set.
   124          # This is needed because the CompletionResult does not accept an empty string as argument
   125          if (-Not $Description) {
   126              $Description = " "
   127          }
   128          @{Name="$Name";Description="$Description"}
   129      }
   130  
   131  
   132      $Space = " "
   133      if (($Directive -band $ShellCompDirectiveNoSpace) -ne 0 ) {
   134          # remove the space here
   135          __podman_debug "ShellCompDirectiveNoSpace is called"
   136          $Space = ""
   137      }
   138  
   139      if ((($Directive -band $ShellCompDirectiveFilterFileExt) -ne 0 ) -or
   140         (($Directive -band $ShellCompDirectiveFilterDirs) -ne 0 ))  {
   141          __podman_debug "ShellCompDirectiveFilterFileExt ShellCompDirectiveFilterDirs are not supported"
   142  
   143          # return here to prevent the completion of the extensions
   144          return
   145      }
   146  
   147      $Values = $Values | Where-Object {
   148          # filter the result
   149          $_.Name -like "$WordToComplete*"
   150  
   151          # Join the flag back if we have an equal sign flag
   152          if ( $IsEqualFlag ) {
   153              __podman_debug "Join the equal sign flag back to the completion value"
   154              $_.Name = $Flag + "=" + $_.Name
   155          }
   156      }
   157  
   158      # we sort the values in ascending order by name if keep order isn't passed
   159      if (($Directive -band $ShellCompDirectiveKeepOrder) -eq 0 ) {
   160          $Values = $Values | Sort-Object -Property Name
   161      }
   162  
   163      if (($Directive -band $ShellCompDirectiveNoFileComp) -ne 0 ) {
   164          __podman_debug "ShellCompDirectiveNoFileComp is called"
   165  
   166          if ($Values.Length -eq 0) {
   167              # Just print an empty string here so the
   168              # shell does not start to complete paths.
   169              # We cannot use CompletionResult here because
   170              # it does not accept an empty string as argument.
   171              ""
   172              return
   173          }
   174      }
   175  
   176      # Get the current mode
   177      $Mode = (Get-PSReadLineKeyHandler | Where-Object {$_.Key -eq "Tab" }).Function
   178      __podman_debug "Mode: $Mode"
   179  
   180      $Values | ForEach-Object {
   181  
   182          # store temporary because switch will overwrite $_
   183          $comp = $_
   184  
   185          # PowerShell supports three different completion modes
   186          # - TabCompleteNext (default windows style - on each key press the next option is displayed)
   187          # - Complete (works like bash)
   188          # - MenuComplete (works like zsh)
   189          # You set the mode with Set-PSReadLineKeyHandler -Key Tab -Function <mode>
   190  
   191          # CompletionResult Arguments:
   192          # 1) CompletionText text to be used as the auto completion result
   193          # 2) ListItemText   text to be displayed in the suggestion list
   194          # 3) ResultType     type of completion result
   195          # 4) ToolTip        text for the tooltip with details about the object
   196  
   197          switch ($Mode) {
   198  
   199              # bash like
   200              "Complete" {
   201  
   202                  if ($Values.Length -eq 1) {
   203                      __podman_debug "Only one completion left"
   204  
   205                      # insert space after value
   206                      [System.Management.Automation.CompletionResult]::new($($comp.Name | __podman_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
   207  
   208                  } else {
   209                      # Add the proper number of spaces to align the descriptions
   210                      while($comp.Name.Length -lt $Longest) {
   211                          $comp.Name = $comp.Name + " "
   212                      }
   213  
   214                      # Check for empty description and only add parentheses if needed
   215                      if ($($comp.Description) -eq " " ) {
   216                          $Description = ""
   217                      } else {
   218                          $Description = "  ($($comp.Description))"
   219                      }
   220  
   221                      [System.Management.Automation.CompletionResult]::new("$($comp.Name)$Description", "$($comp.Name)$Description", 'ParameterValue', "$($comp.Description)")
   222                  }
   223               }
   224  
   225              # zsh like
   226              "MenuComplete" {
   227                  # insert space after value
   228                  # MenuComplete will automatically show the ToolTip of
   229                  # the highlighted value at the bottom of the suggestions.
   230                  [System.Management.Automation.CompletionResult]::new($($comp.Name | __podman_escapeStringWithSpecialChars) + $Space, "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
   231              }
   232  
   233              # TabCompleteNext and in case we get something unknown
   234              Default {
   235                  # Like MenuComplete but we don't want to add a space here because
   236                  # the user need to press space anyway to get the completion.
   237                  # Description will not be shown because that's not possible with TabCompleteNext
   238                  [System.Management.Automation.CompletionResult]::new($($comp.Name | __podman_escapeStringWithSpecialChars), "$($comp.Name)", 'ParameterValue', "$($comp.Description)")
   239              }
   240          }
   241  
   242      }
   243  }
   244  
   245  Register-ArgumentCompleter -CommandName 'podman' -ScriptBlock ${__podmanCompleterBlock}
   246  
   247  # This file is generated with "podman completion"; see: podman-completion(1)