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

     1  # fish completion for podman                               -*- shell-script -*-
     2  
     3  function __podman_debug
     4      set -l file "$BASH_COMP_DEBUG_FILE"
     5      if test -n "$file"
     6          echo "$argv" >> $file
     7      end
     8  end
     9  
    10  function __podman_perform_completion
    11      __podman_debug "Starting __podman_perform_completion"
    12  
    13      # Extract all args except the last one
    14      set -l args (commandline -opc)
    15      # Extract the last arg and escape it in case it is a space
    16      set -l lastArg (string escape -- (commandline -ct))
    17  
    18      __podman_debug "args: $args"
    19      __podman_debug "last arg: $lastArg"
    20  
    21      # Disable ActiveHelp which is not supported for fish shell
    22      set -l requestComp "PODMAN_ACTIVE_HELP=0 $args[1] __complete $args[2..-1] $lastArg"
    23  
    24      __podman_debug "Calling $requestComp"
    25      set -l results (eval $requestComp 2> /dev/null)
    26  
    27      # Some programs may output extra empty lines after the directive.
    28      # Let's ignore them or else it will break completion.
    29      # Ref: https://github.com/spf13/cobra/issues/1279
    30      for line in $results[-1..1]
    31          if test (string trim -- $line) = ""
    32              # Found an empty line, remove it
    33              set results $results[1..-2]
    34          else
    35              # Found non-empty line, we have our proper output
    36              break
    37          end
    38      end
    39  
    40      set -l comps $results[1..-2]
    41      set -l directiveLine $results[-1]
    42  
    43      # For Fish, when completing a flag with an = (e.g., <program> -n=<TAB>)
    44      # completions must be prefixed with the flag
    45      set -l flagPrefix (string match -r -- '-.*=' "$lastArg")
    46  
    47      __podman_debug "Comps: $comps"
    48      __podman_debug "DirectiveLine: $directiveLine"
    49      __podman_debug "flagPrefix: $flagPrefix"
    50  
    51      for comp in $comps
    52          printf "%s%s\n" "$flagPrefix" "$comp"
    53      end
    54  
    55      printf "%s\n" "$directiveLine"
    56  end
    57  
    58  # this function limits calls to __podman_perform_completion, by caching the result behind $__podman_perform_completion_once_result
    59  function __podman_perform_completion_once
    60      __podman_debug "Starting __podman_perform_completion_once"
    61  
    62      if test -n "$__podman_perform_completion_once_result"
    63          __podman_debug "Seems like a valid result already exists, skipping __podman_perform_completion"
    64          return 0
    65      end
    66  
    67      set --global __podman_perform_completion_once_result (__podman_perform_completion)
    68      if test -z "$__podman_perform_completion_once_result"
    69          __podman_debug "No completions, probably due to a failure"
    70          return 1
    71      end
    72  
    73      __podman_debug "Performed completions and set __podman_perform_completion_once_result"
    74      return 0
    75  end
    76  
    77  # this function is used to clear the $__podman_perform_completion_once_result variable after completions are run
    78  function __podman_clear_perform_completion_once_result
    79      __podman_debug ""
    80      __podman_debug "========= clearing previously set __podman_perform_completion_once_result variable =========="
    81      set --erase __podman_perform_completion_once_result
    82      __podman_debug "Successfully erased the variable __podman_perform_completion_once_result"
    83  end
    84  
    85  function __podman_requires_order_preservation
    86      __podman_debug ""
    87      __podman_debug "========= checking if order preservation is required =========="
    88  
    89      __podman_perform_completion_once
    90      if test -z "$__podman_perform_completion_once_result"
    91          __podman_debug "Error determining if order preservation is required"
    92          return 1
    93      end
    94  
    95      set -l directive (string sub --start 2 $__podman_perform_completion_once_result[-1])
    96      __podman_debug "Directive is: $directive"
    97  
    98      set -l shellCompDirectiveKeepOrder 32
    99      set -l keeporder (math (math --scale 0 $directive / $shellCompDirectiveKeepOrder) % 2)
   100      __podman_debug "Keeporder is: $keeporder"
   101  
   102      if test $keeporder -ne 0
   103          __podman_debug "This does require order preservation"
   104          return 0
   105      end
   106  
   107      __podman_debug "This doesn't require order preservation"
   108      return 1
   109  end
   110  
   111  
   112  # This function does two things:
   113  # - Obtain the completions and store them in the global __podman_comp_results
   114  # - Return false if file completion should be performed
   115  function __podman_prepare_completions
   116      __podman_debug ""
   117      __podman_debug "========= starting completion logic =========="
   118  
   119      # Start fresh
   120      set --erase __podman_comp_results
   121  
   122      __podman_perform_completion_once
   123      __podman_debug "Completion results: $__podman_perform_completion_once_result"
   124  
   125      if test -z "$__podman_perform_completion_once_result"
   126          __podman_debug "No completion, probably due to a failure"
   127          # Might as well do file completion, in case it helps
   128          return 1
   129      end
   130  
   131      set -l directive (string sub --start 2 $__podman_perform_completion_once_result[-1])
   132      set --global __podman_comp_results $__podman_perform_completion_once_result[1..-2]
   133  
   134      __podman_debug "Completions are: $__podman_comp_results"
   135      __podman_debug "Directive is: $directive"
   136  
   137      set -l shellCompDirectiveError 1
   138      set -l shellCompDirectiveNoSpace 2
   139      set -l shellCompDirectiveNoFileComp 4
   140      set -l shellCompDirectiveFilterFileExt 8
   141      set -l shellCompDirectiveFilterDirs 16
   142  
   143      if test -z "$directive"
   144          set directive 0
   145      end
   146  
   147      set -l compErr (math (math --scale 0 $directive / $shellCompDirectiveError) % 2)
   148      if test $compErr -eq 1
   149          __podman_debug "Received error directive: aborting."
   150          # Might as well do file completion, in case it helps
   151          return 1
   152      end
   153  
   154      set -l filefilter (math (math --scale 0 $directive / $shellCompDirectiveFilterFileExt) % 2)
   155      set -l dirfilter (math (math --scale 0 $directive / $shellCompDirectiveFilterDirs) % 2)
   156      if test $filefilter -eq 1; or test $dirfilter -eq 1
   157          __podman_debug "File extension filtering or directory filtering not supported"
   158          # Do full file completion instead
   159          return 1
   160      end
   161  
   162      set -l nospace (math (math --scale 0 $directive / $shellCompDirectiveNoSpace) % 2)
   163      set -l nofiles (math (math --scale 0 $directive / $shellCompDirectiveNoFileComp) % 2)
   164  
   165      __podman_debug "nospace: $nospace, nofiles: $nofiles"
   166  
   167      # If we want to prevent a space, or if file completion is NOT disabled,
   168      # we need to count the number of valid completions.
   169      # To do so, we will filter on prefix as the completions we have received
   170      # may not already be filtered so as to allow fish to match on different
   171      # criteria than the prefix.
   172      if test $nospace -ne 0; or test $nofiles -eq 0
   173          set -l prefix (commandline -t | string escape --style=regex)
   174          __podman_debug "prefix: $prefix"
   175  
   176          set -l completions (string match -r -- "^$prefix.*" $__podman_comp_results)
   177          set --global __podman_comp_results $completions
   178          __podman_debug "Filtered completions are: $__podman_comp_results"
   179  
   180          # Important not to quote the variable for count to work
   181          set -l numComps (count $__podman_comp_results)
   182          __podman_debug "numComps: $numComps"
   183  
   184          if test $numComps -eq 1; and test $nospace -ne 0
   185              # We must first split on \t to get rid of the descriptions to be
   186              # able to check what the actual completion will be.
   187              # We don't need descriptions anyway since there is only a single
   188              # real completion which the shell will expand immediately.
   189              set -l split (string split --max 1 \t $__podman_comp_results[1])
   190  
   191              # Fish won't add a space if the completion ends with any
   192              # of the following characters: @=/:.,
   193              set -l lastChar (string sub -s -1 -- $split)
   194              if not string match -r -q "[@=/:.,]" -- "$lastChar"
   195                  # In other cases, to support the "nospace" directive we trick the shell
   196                  # by outputting an extra, longer completion.
   197                  __podman_debug "Adding second completion to perform nospace directive"
   198                  set --global __podman_comp_results $split[1] $split[1].
   199                  __podman_debug "Completions are now: $__podman_comp_results"
   200              end
   201          end
   202  
   203          if test $numComps -eq 0; and test $nofiles -eq 0
   204              # To be consistent with bash and zsh, we only trigger file
   205              # completion when there are no other completions
   206              __podman_debug "Requesting file completion"
   207              return 1
   208          end
   209      end
   210  
   211      return 0
   212  end
   213  
   214  # Since Fish completions are only loaded once the user triggers them, we trigger them ourselves
   215  # so we can properly delete any completions provided by another script.
   216  # Only do this if the program can be found, or else fish may print some errors; besides,
   217  # the existing completions will only be loaded if the program can be found.
   218  if type -q "podman"
   219      # The space after the program name is essential to trigger completion for the program
   220      # and not completion of the program name itself.
   221      # Also, we use '> /dev/null 2>&1' since '&>' is not supported in older versions of fish.
   222      complete --do-complete "podman " > /dev/null 2>&1
   223  end
   224  
   225  # Remove any pre-existing completions for the program since we will be handling all of them.
   226  complete -c podman -e
   227  
   228  # this will get called after the two calls below and clear the $__podman_perform_completion_once_result global
   229  complete -c podman -n '__podman_clear_perform_completion_once_result'
   230  # The call to __podman_prepare_completions will setup __podman_comp_results
   231  # which provides the program's completion choices.
   232  # If this doesn't require order preservation, we don't use the -k flag
   233  complete -c podman -n 'not __podman_requires_order_preservation && __podman_prepare_completions' -f -a '$__podman_comp_results'
   234  # otherwise we use the -k flag
   235  complete -k -c podman -n '__podman_requires_order_preservation && __podman_prepare_completions' -f -a '$__podman_comp_results'
   236  
   237  # This file is generated with "podman completion"; see: podman-completion(1)