diff options
author | Paul Holzinger <paul.holzinger@web.de> | 2020-11-08 21:50:51 +0100 |
---|---|---|
committer | Paul Holzinger <paul.holzinger@web.de> | 2020-11-12 11:40:29 +0100 |
commit | ae3816614de1c2a0c9ab9cd05afebc5b1dda6429 (patch) | |
tree | 11deb2f5b2bb87d1869f7258b8f2e9cc46b57e00 /completions | |
parent | b5d1d89a377e38762a75c2042dcc50a370ba6707 (diff) | |
download | podman-ae3816614de1c2a0c9ab9cd05afebc5b1dda6429.tar.gz podman-ae3816614de1c2a0c9ab9cd05afebc5b1dda6429.tar.bz2 podman-ae3816614de1c2a0c9ab9cd05afebc5b1dda6429.zip |
Install the new shell completion logic
Add a new make target (completion) to generate the shell
completion scripts. This will generate the scripts for bash,
zsh and fish for both podman and podman-remote with `podman completion`.
The scripts are put into the completions directory and can be
installed system wide with `sudo make install.completions`.
This commit replaces the current handwritten scripts for bash and zsh.
The `validate.completion` target has been adjusted to make sure nobody
edits these scripts directly.
Signed-off-by: Paul Holzinger <paul.holzinger@web.de>
Diffstat (limited to 'completions')
-rw-r--r-- | completions/Readme.md | 7 | ||||
-rw-r--r-- | completions/bash/podman | 3830 | ||||
-rw-r--r-- | completions/bash/podman-remote | 271 | ||||
-rw-r--r-- | completions/fish/podman-remote.fish | 182 | ||||
-rw-r--r-- | completions/fish/podman.fish | 182 | ||||
-rw-r--r-- | completions/zsh/_podman | 502 | ||||
-rw-r--r-- | completions/zsh/_podman-remote | 181 |
7 files changed, 1225 insertions, 3930 deletions
diff --git a/completions/Readme.md b/completions/Readme.md new file mode 100644 index 000000000..9a3eac480 --- /dev/null +++ b/completions/Readme.md @@ -0,0 +1,7 @@ +# Shell completion scripts + +Podman offers shell completion scripts for bash, zsh and fish. The completion scripts are available for both `podman` and `podman-remote`. + +The shell completion scripts are generated by `make completion`, do not edit these files directly. To install them you can run `sudo make install.completions`. + +For information about these sripts see [`man podman-completion`](../docs/source/markdown/podman-completion.1.md) diff --git a/completions/bash/podman b/completions/bash/podman index c08bb3352..17d1e86b7 100644 --- a/completions/bash/podman +++ b/completions/bash/podman @@ -1,3601 +1,271 @@ -# -# This bash script was originally copied and converted from the upstream -# github.com:docker/docker project -# -: ${PROG:=$(basename ${BASH_SOURCE})} +# bash completion for podman -*- shell-script -*- - -__podman_previous_extglob_setting=$(shopt -p extglob) -shopt -s extglob - -__podman_q() { - podman ${host:+-H "$host"} ${config:+--config "$config"} 2>/dev/null "$@" -} - -# __podman_containers returns a list of containers. Additional options to -# `podman ps` may be specified in order to filter the list, e.g. -# `__podman_containers --filter status=running` -# By default, only names are returned. -# Set PODMAN_COMPLETION_SHOW_CONTAINER_IDS=yes to also complete IDs. -# An optional first option `--id|--name` may be used to limit the -# output to the IDs or names of matching items. This setting takes -# precedence over the environment setting. -__podman_containers() { - local format - if [ "$1" = "--id" ] ; then - format='{{.ID}}' - shift - elif [ "$1" = "--name" ] ; then - format='{{.Names}}' - shift - elif [ "${PODMAN_COMPLETION_SHOW_CONTAINER_IDS}" = yes ] ; then - format='{{.ID}} {{.Names}}' - else - format='{{.Names}}' - fi - __podman_q ps --format "$format" "$@" -} - -__podman_list_registries() { - sed -n -e '/registries.*=/ {s/.*\[\([^]]*\).*/\1/p;q}' /etc/containers/registries.conf | sed -e "s/[,']//g" -} - -# __podman_pods returns a list of pods. Additional options to -# `podman pod ps` may be specified in order to filter the list, e.g. -# `__podman_containers --filter status=running` -# By default, only names are returned. -# Set PODMAN_COMPLETION_SHOW_CONTAINER_IDS=yes to also complete IDs. -# An optional first option `--id|--name` may be used to limit the -# output to the IDs or names of matching items. This setting takes -# precedence over the environment setting. -__podman_pods() { - local format - if [ "$1" = "--id" ] ; then - format='{{.ID}}' - shift - elif [ "$1" = "--name" ] ; then - format='{{.Name}}' - shift - else - format='{{.Name}}' - fi - __podman_q pod ps --format "$format" "$@" -} - -# __podman_complete_containers applies completion of containers based on the current -# value of `$cur` or the value of the optional first option `--cur`, if given. -# Additional filters may be appended, see `__podman_containers`. -__podman_complete_containers() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__podman_containers "$@")" -- "$current") ) -} - -# __podman_complete_pods applies completion of pods based on the current -# value of `$cur` or the value of the optional first option `--cur`, if given. -# Additional filters may be appended, see `__podman_pods`. -__podman_complete_pods() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__podman_pods "$@")" -- "$current") ) -} - -__podman_complete_pod_names() { - local names=( $(__podman_q pod ps --format={{.Name}}) ) - COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") ) -} - -__podman_complete_containers_all() { - __podman_complete_containers "$@" --all -} - -__podman_complete_containers_created() { - __podman_complete_containers "$@" --all --filter status=created -} - -__podman_complete_containers_running() { - __podman_complete_containers "$@" --filter status=running -} - -__podman_complete_containers_stopped() { - __podman_complete_containers "$@" --all --filter status=exited -} - -__podman_complete_containers_unpauseable() { - __podman_complete_containers "$@" --all --filter status=paused -} - -__podman_complete_container_names() { - local containers=( $(__podman_q ps -aq --no-trunc) ) - local names=( $(__podman_q inspect --format '{{.Name}}' "${containers[@]}") ) - names=( "${names[@]#/}" ) # trim off the leading "/" from the container names - COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") ) -} - -__podman_complete_container_ids() { - local containers=( $(__podman_q ps -aq) ) - COMPREPLY=( $(compgen -W "${containers[*]}" -- "$cur") ) -} - -__podman_images() { - local images_args="" - - case "$PODMAN_COMPLETION_SHOW_IMAGE_IDS" in - all) - images_args="--no-trunc -a" - ;; - non-intermediate) - images_args="--no-trunc" - ;; - esac - - local repo_print_command - if [ "${PODMAN_COMPLETION_SHOW_TAGS:-yes}" = "yes" ]; then - repo_print_command='print $1; print $1":"$2' - else - repo_print_command='print $1' - fi - - local awk_script - case "$PODMAN_COMPLETION_SHOW_IMAGE_IDS" in - all|non-intermediate) - awk_script='NR>1 { print $3; if ($1 != "<none>") { '"$repo_print_command"' } }' - ;; - none|*) - awk_script='NR>1 && $1 != "<none>" { '"$repo_print_command"' }' - ;; - esac - - __podman_q images $images_args | awk "$awk_script" | grep -v '<none>$' -} - -__podman_complete_images() { - COMPREPLY=( $(compgen -W "$(__podman_images)" -- "$cur") ) - __ltrim_colon_completions "$cur" -} - -__podman_complete_image_repos() { - local repos="$(__podman_q images | awk 'NR>1 && $1 != "<none>" { print $1 }')" - COMPREPLY=( $(compgen -W "$repos" -- "$cur") ) -} - -__podman_complete_image_repos_and_tags() { - local reposAndTags="$(__podman_q images | awk 'NR>1 && $1 != "<none>" { print $1; print $1":"$2 }')" - COMPREPLY=( $(compgen -W "$reposAndTags" -- "$cur") ) - __ltrim_colon_completions "$cur" -} - -# __podman_networks returns a list of all networks. Additional options to -# `podman network ls` may be specified in order to filter the list, e.g. -# `__podman_networks --filter type=custom` -# By default, only names are returned. -# Set PODMAN_COMPLETION_SHOW_NETWORK_IDS=yes to also complete IDs. -# An optional first option `--id|--name` may be used to limit the -# output to the IDs or names of matching items. This setting takes -# precedence over the environment setting. -__podman_networks() { - local format - if [ "$1" = "--id" ] ; then - format='{{.ID}}' - shift - elif [ "$1" = "--name" ] ; then - format='{{.Name}}' - shift - elif [ "${PODMAN_COMPLETION_SHOW_NETWORK_IDS}" = yes ] ; then - format='{{.ID}} {{.Name}}' - else - format='{{.Name}}' - fi - __podman_q network ls --format "$format" "$@" -} - -# __podman_complete_networks applies completion of networks based on the current -# value of `$cur` or the value of the optional first option `--cur`, if given. -# Additional filters may be appended, see `__podman_networks`. -__podman_complete_networks() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__podman_networks "$@")" -- "$current") ) -} - -__podman_complete_containers_in_network() { - local containers=$(__podman_q network inspect -f '{{range $i, $c := .Containers}}{{$i}} {{$c.Name}} {{end}}' "$1") - COMPREPLY=( $(compgen -W "$containers" -- "$cur") ) -} - -__podman_runtimes() { - __podman_q info | sed -n 's/^Runtimes: \(.*\)/\1/p' -} - -__podman_complete_runtimes() { - COMPREPLY=( $(compgen -W "$(__podman_runtimes)" -- "$cur") ) -} - -# __podman_services returns a list of all services. Additional options to -# `podman service ls` may be specified in order to filter the list, e.g. -# `__podman_services --filter name=xxx` -# By default, only node names are returned. -# Set PODMAN_COMPLETION_SHOW_SERVICE_IDS=yes to also complete IDs. -# An optional first option `--id|--name` may be used to limit the -# output to the IDs or names of matching items. This setting takes -# precedence over the environment setting. -__podman_services() { - local fields='$2' # default: service name only - [ "${PODMAN_COMPLETION_SHOW_SERVICE_IDS}" = yes ] && fields='$1,$2' # ID & name - - if [ "$1" = "--id" ] ; then - fields='$1' # IDs only - shift - elif [ "$1" = "--name" ] ; then - fields='$2' # names only - shift - fi - __podman_q service ls "$@" | awk "NR>1 {print $fields}" -} - -# __podman_complete_services applies completion of services based on the current -# value of `$cur` or the value of the optional first option `--cur`, if given. -# Additional filters may be appended, see `__podman_services`. -__podman_complete_services() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__podman_services "$@")" -- "$current") ) -} - -# __podman_append_to_completions appends the word passed as an argument to every -# word in `$COMPREPLY`. -# Normally you do this with `compgen -S` while generating the completions. -# This function allows you to append a suffix later. It allows you to use -# the __podman_complete_XXX functions in cases where you need a suffix. -__podman_append_to_completions() { - COMPREPLY=( ${COMPREPLY[@]/%/"$1"} ) -} - -# __podman_pos_first_nonflag finds the position of the first word that is neither -# option nor an option's argument. If there are options that require arguments, -# you should pass a glob describing those options, e.g. "--option1|-o|--option2" -# Use this function to restrict completions to exact positions after the argument list. -__podman_pos_first_nonflag() { - local argument_flags=$1 - - local counter=$((${subcommand_pos:-${command_pos}} + 1)) - while [ $counter -le $cword ]; do - if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then - (( counter++ )) - # eat "=" in case of --option=arg syntax - [ "${words[$counter]}" = "=" ] && (( counter++ )) - else - case "${words[$counter]}" in - -*) - ;; - *) - break - ;; - esac - fi - - # Bash splits words at "=", retaining "=" as a word, examples: - # "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words - while [ "${words[$counter + 1]}" = "=" ] ; do - counter=$(( counter + 2)) - done - - (( counter++ )) - done - - echo $counter -} - -# __podman_map_key_of_current_option returns `key` if we are currently completing the -# value of a map option (`key=value`) which matches the extglob given as an argument. -# This function is needed for key-specific completions. -__podman_map_key_of_current_option() { - local glob="$1" - - local key glob_pos - if [ "$cur" = "=" ] ; then # key= case - key="$prev" - glob_pos=$((cword - 2)) - elif [[ $cur == *=* ]] ; then # key=value case (OSX) - key=${cur%=*} - glob_pos=$((cword - 1)) - elif [ "$prev" = "=" ] ; then - key=${words[$cword - 2]} # key=value case - glob_pos=$((cword - 3)) - else - return - fi - - [ "${words[$glob_pos]}" = "=" ] && ((glob_pos--)) # --option=key=value syntax - - [[ ${words[$glob_pos]} == @($glob) ]] && echo "$key" -} - -# __podman_value_of_option returns the value of the first option matching `option_glob`. -# Valid values for `option_glob` are option names like `--log-level` and globs like -# `--log-level|-l` -# Only positions between the command and the current word are considered. -__podman_value_of_option() { - local option_extglob=$(__podman_to_extglob "$1") - - local counter=$((command_pos + 1)) - while [ $counter -lt $cword ]; do - case ${words[$counter]} in - $option_extglob ) - echo ${words[$counter + 1]} - break - ;; - esac - (( counter++ )) - done -} - -# __podman_to_alternatives transforms a multiline list of strings into a single line -# string with the words separated by `|`. -# This is used to prepare arguments to __podman_pos_first_nonflag(). -__podman_to_alternatives() { - local parts=( $1 ) - local IFS='|' - echo "${parts[*]}" -} - -# __podman_to_extglob transforms a multiline list of options into an extglob pattern -# suitable for use in case statements. -__podman_to_extglob() { - local extglob=$( __podman_to_alternatives "$1" ) - echo "@($extglob)" -} - -# __podman_subcommands processes subcommands -# Locates the first occurrence of any of the subcommands contained in the -# first argument. In case of a match, calls the corresponding completion -# function and returns 0. -# If no match is found, 1 is returned. The calling function can then -# continue processing its completion. -# -# TODO if the preceding command has options that accept arguments and an -# argument is equal to one of the subcommands, this is falsely detected as -# a match. -__podman_subcommands() { - local subcommands="$1" - - local counter=$(($command_pos + 1)) - - while [ $counter -lt $cword ]; do - case "${words[$counter]}" in - $(__podman_to_extglob "$subcommands") ) - subcommand_pos=$counter - local subcommand=${words[$counter]} - local completions_func=_podman_${command}_${subcommand} - declare -F $completions_func >/dev/null && $completions_func - return 0 - ;; - esac - (( counter++ )) - done - return 1 -} - -# __podman_nospace suppresses trailing whitespace -__podman_nospace() { - # compopt is not available in ancient bash versions - type compopt &>/dev/null && compopt -o nospace -} - -__podman_complete_resolved_hostname() { - command -v host >/dev/null 2>&1 || return - COMPREPLY=( $(host 2>/dev/null "${cur%:}" | awk '/has address/ {print $4}') ) -} - -__podman_local_interfaces() { - command -v ip >/dev/null 2>&1 || return - ip addr show scope global 2>/dev/null | sed -n 's| \+inet \([0-9.]\+\).* \([^ ]\+\)|\1 \2|p' -} - -__podman_complete_restart() { - case "$prev" in - --restart) - COMPREPLY=( $( compgen -W "always no on-failure unless-stopped" -- "$cur") ) - return - ;; - esac - return 1 -} - -__podman_complete_local_interfaces() { - local additional_interface - if [ "$1" = "--add" ] ; then - additional_interface="$2" - fi - - COMPREPLY=( $( compgen -W "$(__podman_local_interfaces) $additional_interface" -- "$cur" ) ) -} - -__podman_complete_capabilities() { - # The list of capabilities is defined in types.go, ALL was added manually. - COMPREPLY=( $( compgen -W " - ALL - AUDIT_CONTROL - AUDIT_WRITE - AUDIT_READ - BLOCK_SUSPEND - CHOWN - DAC_OVERRIDE - DAC_READ_SEARCH - FOWNER - FSETID - IPC_LOCK - IPC_OWNER - KILL - LEASE - LINUX_IMMUTABLE - MAC_ADMIN - MAC_OVERRIDE - MKNOD - NET_ADMIN - NET_BIND_SERVICE - NET_BROADCAST - NET_RAW - SETFCAP - SETGID - SETPCAP - SETUID - SYS_ADMIN - SYS_BOOT - SYS_CHROOT - SYSLOG - SYS_MODULE - SYS_NICE - SYS_PACCT - SYS_PTRACE - SYS_RAWIO - SYS_RESOURCE - SYS_TIME - SYS_TTY_CONFIG - WAKE_ALARM - " -- "$cur" ) ) -} - -__podman_complete_detach_keys() { - case "$prev" in - --detach-keys) - case "$cur" in - *,) - COMPREPLY=( $( compgen -W "${cur}ctrl-" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "ctrl-" -- "$cur" ) ) - ;; - esac - - __podman_nospace - return 0 - ;; - esac - return 1 -} - -__podman_complete_log_drivers() { - COMPREPLY=( $( compgen -W " - awslogs - etwlogs - fluentd - gcplogs - gelf - journald - json-file - logentries - none - splunk - syslog - k8s-file - " -- "$cur" ) ) -} - -__podman_complete_log_options() { - # see docs/reference/logging/index.md - local awslogs_options="awslogs-region awslogs-group awslogs-stream" - local fluentd_options="env fluentd-address fluentd-async-connect fluentd-buffer-limit fluentd-retry-wait fluentd-max-retries labels tag" - local gcplogs_options="env gcp-log-cmd gcp-project labels" - local gelf_options="env gelf-address gelf-compression-level gelf-compression-type labels tag" - local journald_options="env labels tag" - local json_file_options="env labels max-file max-size" - local logentries_options="logentries-token" - local syslog_options="env labels syslog-address syslog-facility syslog-format syslog-tls-ca-cert syslog-tls-cert syslog-tls-key syslog-tls-skip-verify tag" - local splunk_options="env labels splunk-caname splunk-capath splunk-format splunk-gzip splunk-gzip-level splunk-index splunk-insecureskipverify splunk-source splunk-sourcetype splunk-token splunk-url splunk-verify-connection tag" - local k8s_file_options="env labels max-file max-size" - - local all_options="$fluentd_options $gcplogs_options $gelf_options $journald_options $logentries_options $json_file_options $syslog_options $splunk_options" - - case $(__podman_value_of_option --log-driver) in - '') - COMPREPLY=( $( compgen -W "$all_options" -S = -- "$cur" ) ) - ;; - awslogs) - COMPREPLY=( $( compgen -W "$awslogs_options" -S = -- "$cur" ) ) - ;; - fluentd) - COMPREPLY=( $( compgen -W "$fluentd_options" -S = -- "$cur" ) ) - ;; - gcplogs) - COMPREPLY=( $( compgen -W "$gcplogs_options" -S = -- "$cur" ) ) - ;; - gelf) - COMPREPLY=( $( compgen -W "$gelf_options" -S = -- "$cur" ) ) - ;; - journald) - COMPREPLY=( $( compgen -W "$journald_options" -S = -- "$cur" ) ) - ;; - json-file) - COMPREPLY=( $( compgen -W "$json_file_options" -S = -- "$cur" ) ) - ;; - k8s-file) - COMPREPLY=( $( compgen -W "$k8s_file_options" -S = -- "$cur" ) ) - ;; - logentries) - COMPREPLY=( $( compgen -W "$logentries_options" -S = -- "$cur" ) ) - ;; - syslog) - COMPREPLY=( $( compgen -W "$syslog_options" -S = -- "$cur" ) ) - ;; - splunk) - COMPREPLY=( $( compgen -W "$splunk_options" -S = -- "$cur" ) ) - ;; - *) - return - ;; - esac - - __podman_nospace -} - -__podman_complete_log_driver_options() { - local key=$(__podman_map_key_of_current_option '--log-opt') - case "$key" in - fluentd-async-connect) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - gelf-address) - COMPREPLY=( $( compgen -W "udp" -S "://" -- "${cur##*=}" ) ) - __podman_nospace - return - ;; - gelf-compression-level) - COMPREPLY=( $( compgen -W "1 2 3 4 5 6 7 8 9" -- "${cur##*=}" ) ) - return - ;; - gelf-compression-type) - COMPREPLY=( $( compgen -W "gzip none zlib" -- "${cur##*=}" ) ) - return - ;; - syslog-address) - COMPREPLY=( $( compgen -W "tcp:// tcp+tls:// udp:// unix://" -- "${cur##*=}" ) ) - __podman_nospace - __ltrim_colon_completions "${cur}" - return - ;; - syslog-facility) - COMPREPLY=( $( compgen -W " - auth - authpriv - cron - daemon - ftp - kern - local0 - local1 - local2 - local3 - local4 - local5 - local6 - local7 - lpr - mail - news - syslog - user - uucp - " -- "${cur##*=}" ) ) - return - ;; - syslog-format) - COMPREPLY=( $( compgen -W "rfc3164 rfc5424 rfc5424micro" -- "${cur##*=}" ) ) - return - ;; - syslog-tls-ca-cert|syslog-tls-cert|syslog-tls-key) - _filedir - return - ;; - syslog-tls-skip-verify) - COMPREPLY=( $( compgen -W "true" -- "${cur##*=}" ) ) - return - ;; - splunk-url) - COMPREPLY=( $( compgen -W "http:// https://" -- "${cur##*=}" ) ) - __podman_nospace - __ltrim_colon_completions "${cur}" - return - ;; - splunk-gzip|splunk-insecureskipverify|splunk-verify-connection) - COMPREPLY=( $( compgen -W "false true" -- "${cur##*=}" ) ) - return - ;; - splunk-format) - COMPREPLY=( $( compgen -W "inline json raw" -- "${cur##*=}" ) ) - return - ;; - esac - return 1 -} - -__podman_complete_log_levels() { - COMPREPLY=( $( compgen -W "debug info warn error fatal" -- "$cur" ) ) -} - -# __podman_complete_signals returns a subset of the available signals that is most likely -# relevant in the context of podman containers -__podman_complete_signals() { - local signals=( - SIGCONT - SIGHUP - SIGINT - SIGKILL - SIGQUIT - SIGSTOP - SIGTERM - SIGUSR1 - SIGUSR2 - ) - COMPREPLY=( $( compgen -W "${signals[*]} ${signals[*]#SIG}" -- "$( echo $cur | tr '[:lower:]' '[:upper:]')" ) ) -} - -__podman_complete_user_group() { - if [[ $cur == *:* ]] ; then - COMPREPLY=( $(compgen -g -- "${cur#*:}") ) - else - COMPREPLY=( $(compgen -u -S : -- "$cur") ) - __podman_nospace - fi -} - -__podman_list_images() { - COMPREPLY=($(compgen -W "$(podman images -q)" -- $cur)) -} - -__podman_list_containers() { - COMPREPLY=($(compgen -W "$(podman ps -aq)" -- $cur)) -} - -__podman_images() { - local images_args="" - - case "$PODMAN_COMPLETION_SHOW_IMAGE_IDS" in - all) - images_args="--no-trunc -a" - ;; - non-intermediate) - images_args="--no-trunc" - ;; - esac - - local repo_print_command - if [ "${PODMAN_COMPLETION_SHOW_TAGS:-yes}" = "yes" ]; then - repo_print_command='print $1; print $1":"$2' - else - repo_print_command='print $1' - fi - - local awk_script - case "$PODMAN_COMPLETION_SHOW_IMAGE_IDS" in - all|non-intermediate) - awk_script='NR>1 { print $3; if ($1 != "<none>") { '"$repo_print_command"' } }' - ;; - none|*) - awk_script='NR>1 && $1 != "<none>" { '"$repo_print_command"' }' - ;; - esac - - __podman_q images $images_args | awk "$awk_script" | grep -v '<none>$' -} - -_podman_auto_update() { - local options_with_args=" - --authfile - " - - local boolean_options=" - --help - -h - " - - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_volume_names - ;; - esac -} - -# __podman_complete_volumes applies completion of volumes based on the current -# value of `$cur` or the value of the optional first option `--cur`, if given. -__podman_complete_volumes() { - local current="$cur" - if [ "$1" = "--cur" ] ; then - current="$2" - shift 2 - fi - COMPREPLY=( $(compgen -W "$(__podman_volume "$@")" -- "$current") ) -} - -__podman_complete_volume_names() { - local names=( $(__podman_q volume ls --quiet) ) - COMPREPLY=( $(compgen -W "${names[*]}" -- "$cur") ) -} - - -_podman_attach() { - local options_with_args=" - --detach-keys - " - local boolean_options=" - --help -h - --latest -l - --no-stdin - --sig-proxy - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_containers_running - ;; - esac -} - -_podman_container_attach() { - _podman_attach -} - -_podman_container_checkpoint() { - local options_with_args=" - -e - --export - " - local boolean_options=" - --all -a - --help -h - --ignore-rootfs - --keep -k - --latest -l - --leave-running -R - --tcp-established - " - case "$prev" in - -e|--export) - _filedir - return - ;; - esac - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_containers_running - ;; - esac -} - -_podman_container_commit() { - _podman_commit -} - -_podman_container_cp() { - _podman_cp -} - -_podman_container_create() { - _podman_create -} - -_podman_container_diff() { - _podman_diff -} - -_podman_container_exec() { - _podman_exec -} - -_podman_container_export() { - _podman_export -} - -_podman_container_init() { - _podman_init -} - -_podman_container_inspect() { - _podman_inspect -} - -_podman_container_kill() { - _podman_kill -} - -_podman_container_list() { - _podman_ls -} - -_podman_container_ls() { - _podman_ls -} - -_podman_container_logs() { - _podman_logs -} - -_podman_container_mount() { - _podman_mount -} - -_podman_container_pause() { - _podman_pause -} - -_podman_container_port() { - _podman_port -} - -_podman_container_ps() { - _podman_ls -} - -_podman_container_refresh() { - local options_with_args=" - " - local boolean_options=" - --help - -h - " - _complete_ "$options_with_args" "$boolean_options" -} - -_podman_container_restart() { - _podman_restart -} - -_podman_container_restore() { - local options_with_args=" - -i - --import - -n - --name - " - local boolean_options=" - --all -a - --help -h - --ignore-rootfs - --ignore-static-ip - --ignore-static-mac - --keep -k - --latest -l - --tcp-established - " - case "$prev" in - -i|--import) - _filedir - return - ;; - esac - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_containers_created - ;; - esac -} - -_podman_container_rm() { - _podman_rm -} - -_podman_container_start() { - _podman_start -} - -_podman_container_stats() { - _podman_stats -} - -_podman_container_stop() { - _podman_stop -} - -_podman_container_top() { - _podman_top -} - -_podman_container_umount() { - _podman_umount -} - -_podman_container_unmount() { - _podman_unmount -} - -_podman_container_unpause() { - _podman_unpause -} - -_podman_container_wait() { - _podman_wait -} - -_podman_healthcheck() { - local boolean_options=" - --help - -h - " - subcommands=" - run - " - __podman_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_podman_network() { - local boolean_options=" - --help - -h - " - subcommands=" - create - inspect - ls - rm - " - __podman_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_podman_network_create() { - local options_with_args=" - -d - --driver - --gateway - --ip-range - --macvlan - --subnet - " - local boolean_options=" - --disable-dns - --help -h - --internal - " - _complete_ "$options_with_args" "$boolean_options" - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - esac -} - -_podman_network_inspect() { - local options_with_args=" - --format - -f - " - local boolean_options=" - --help - -h - " - _complete_ "$options_with_args" "$boolean_options" - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - esac -} - -_podman_network_ls() { - local options_with_args=" - --filter - --format -f - " - local boolean_options=" - --help - -h - --quiet - -q - " - _complete_ "$options_with_args" "$boolean_options" - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - esac -} - -_podman_network_rm() { - local options_with_args=" - " - local boolean_options=" - --force -f - --help -h - " - _complete_ "$options_with_args" "$boolean_options" - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - esac -} - -_podman_generate() { - local boolean_options=" - --help - -h - " - subcommands=" - kube - systemd - " - __podman_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_podman_play() { - local boolean_options=" - --help - -h - " - subcommands=" - kube - " - __podman_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} -_podman_container() { - local boolean_options=" - --help - -h - " - subcommands=" - attach - checkpoint - commit - cp - create - diff - exec - exists - export - inspect - kill - list - logs - mount - pause - port - prune - refresh - restart - restore - rm - run - runlabel - start - stats - stop - top - umount - unmount - unpause - wait - " - local aliases=" - list - ps - " - __podman_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_podman_system_reset() { - local options_with_args=" - " - local boolean_options=" - -h - --help - --force - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - esac -} - -_podman_system_df() { - local options_with_args=" - --format - --verbose - " - local boolean_options=" - -h - --help - --verbose - -v - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - esac -} - -_podman_system_info() { - _podman_info -} - -_podman_system_prune() { - local options_with_args=" - " - - local boolean_options=" - --all -a - --force -f - --help -h - --volumes - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - esac -} - -_podman_system_service() { - local options_with_args=" - -t - --timeout - " - local boolean_options=" - --help - -h - --varlink - " - _complete_ "$options_with_args" "$boolean_options" -} - -_podman_system() { - local boolean_options=" - --help - -h - " - subcommands=" - df - info - migrate - prune - renumber - reset - service - " - __podman_subcommands "$subcommands" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_podman_commit() { - local options_with_args=" - --author - -a - --change - -c - --message - -m - --iidfile - " - local boolean_options=" - --help -h - --pause -p - --quiet -q - " - _complete_ "$options_with_args" "$boolean_options" - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_container_names - ;; - esac -} - -_podman_build() { - local boolean_options=" - --force-rm - --help -h - --layers - --no-cache - --pull - --pull-always - --pull-never - --quiet -q - --rm - --squash - --squash-all - --tls-verify - " - - local options_with_args=" - --add-host - --annotation - --authfile - --build-arg - --cap-add - --cap-drop - --cgroup-parent - --cni-config-dir - --cni-plugin-path - --cpu-period - --cpu-quota - --cpu-shares - --cpuset-cpus - --cpuset-mems - --creds - --file -f - --format - --iidfile - --ipc - --label - --memory -m - --memory-swap - --mount - --net - --network - --pid - --runtime-flag - --security-opt - --shm-size - --tag -t - --ulimit - --userns - --userns-gid-map - --userns-gid-map-group - --userns-uid-map - --userns-uid-map-user - --uts - --volume -v - " - - case "$prev" in - --file|-f) - COMPREPLY=($(compgen -W "`ls`" -- "$cur")) - ;; - esac - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - esac -} - -_podman_diff() { - local options_with_args=" - --format - " - local boolean_options=" - --help - -h - " - _complete_ "$options_with_args" "$boolean_options" - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_container_names - ;; - esac -} - -_podman_exec() { - local options_with_args=" - --detach-keys - -e - --env - --env-file - --user - -u - --workdir - -w - " - local boolean_options=" - --help -h - --latest -l - --privileged - --tty -t - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_containers_running - ;; - esac - -} -_podman_export() { - local options_with_args=" - --output - -o - " - local boolean_options=" - --help - -h - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$options_with_args" -- "$cur")) - ;; - *) - __podman_complete_container_names - ;; - esac -} - -_podman_history() { - local options_with_args=" - --format - " - local boolean_options=" - --help -h - --human -H - --no-trunc - --quiet -q - " - _complete_ "$options_with_args" "$boolean_options" - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images --id - ;; - esac -} - - -_podman_import() { - local options_with_args=" - --change - -c - --message - -m - " - local boolean_options=" - --help - -h - --quiet - -q - " - case "$prev" in - --change|-c|--message|-m) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - local counter=$(__podman_pos_first_nonflag '--change|-c|--message|-m') - if [ "$cword" -eq "$counter" ]; then - _filedir - return - elif [ "$cword" -eq "$((counter + 1))" ]; then - __podman_complete_images --repo --tag - return - fi - ;; - esac -} - -_podman_info() { - local boolean_options=" - --help - -h - --debug - " - local options_with_args=" - -f - --format - " - - local all_options="$options_with_args $boolean_options" - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_list_images - ;; - esac -} - -_podman_image_umount() { - _podman_image_unmount -} - -_podman_image_unmount() { - local boolean_options=" - --all -a - --help -h - --force -f - " - local options_with_args=" - " - - local all_options="$options_with_args $boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images --force-tag --id - ;; - esac -} - -_podman_image_mount() { - local boolean_options=" - --all -a - --help -h - " - - local options_with_args=" - --format - " - - local all_options="$options_with_args $boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images --force-tag --id - ;; - esac -} - -_podman_image_build() { - _podman_build -} - -_podman_image_history() { - _podman_history -} - -_podman_image_import() { - _podman_import -} - -_podman_image_inspect() { - _podman_inspect -} - -_podman_image_load() { - _podman_load -} - -_podman_image_list() { - _podman_images -} - -_podman_image_ls() { - _podman_images -} - -_podman_image_pull() { - _podman_pull -} - -_podman_image_push() { - _podman_push -} - -_podman_image_rm() { - _podman_rmi -} - -_podman_image_save() { - _podman_save -} - -_podman_image_tag() { - _podman_tag -} - - -_podman_image_untag() { - _podman_untag -} - -_podman_image() { - local boolean_options=" - --help - -h - " - subcommands=" - build - exists - history - import - inspect - load - ls - mount - prune - pull - push - rm - save - sign - tag - trust - umount - unmount - untag - " - local aliases=" - list - " - __podman_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_podman_images() { - local boolean_options=" - --all -a - --digests - --filter -f - --help -h - --history - --no-trunc - --noheading - --notruncate -n - --quiet -q - " - local options_with_args=" - --format - --sort - " - - local all_options="$options_with_args $boolean_options" - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images --id - ;; - esac -} - -_podman_inspect() { - local boolean_options=" - --help -h - --latest -l - " - local options_with_args=" - --format - -f - --type - -t - --size - -s - " - - local all_options="$options_with_args $boolean_options" - - local preselected_type - local type - - if [ "$1" = "--type" ] ; then - preselected_type=yes - type="$2" - else - type=$(__podman_value_of_option --type) - fi - - case "$prev" in - --format|-f) - return - ;; - --type) - if [ -z "$preselected_type" ] ; then - COMPREPLY=( $( compgen -W "container image" -- "$cur" ) ) - return - fi - ;; - esac - - case "$cur" in - -*) - local options="--format -f --help --size -s" - if [ -z "$preselected_type" ] ; then - options+=" --type" - fi - COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) - ;; - *) - case "$type" in - '') - COMPREPLY=( $( compgen -W " - $(__podman_containers --all) - $(__podman_images --force-tag --id) - " -- "$cur" ) ) - __ltrim_colon_completions "$cur" - ;; - container) - __podman_complete_containers_all - ;; - image) - __podman_complete_images --force-tag --id - ;; - esac - esac -} - -_podman_kill() { - local options_with_args=" - --signal -s - " - local boolean_options=" - --all -a - --help -h - --latest -l - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_containers_running - ;; - esac -} - -_podman_logs() { - local options_with_args=" - --since - --tail - " - local boolean_options=" - --follow -f - --help -h - --latest -l - --timestamps -t - " - _complete_ "$options_with_args" "$boolean_options" - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_list_containers - ;; - esac -} - -_podman_manifest() { - local boolean_options=" - --help - -h - " - subcommands=" - add - create - inspect - push - remove - " - __podman_subcommands "$subcommands" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_podman_manifest_add() { - local options_with_args=" - --annotation - --arch - --authfile - --cert-dir - --creds - --features - --os - --os-version - --variant - " - - local boolean_options=" - --all - --help - -h - --tls-verify - " - - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images --id - ;; - esac -} - -_podman_manifest_annotate() { - local options_with_args=" - --annotation - --arch - --features - --os - --os-features - --os-version - --variant - " - - local boolean_options=" - --help - -h - " - - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images --id - ;; - esac -} - -_podman_manifest_create() { - local boolean_options=" - --all - --help - -h - " - - _complete_ "$boolean_options" -} - -_podman_manifest_inspect() { - local options_with_args=" - " - - local boolean_options=" - " - - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images --id - - ;; - esac -} - -_podman_manifest_push() { - local options_with_args=" - --authfile - --cert-dir - --creds - --digestfile - --format -f - --sign-by - --signature-policy, - " - - local boolean_options=" - --all - --help -h - --purge - --quiet - --remove-signatures - --tls-verify - " - - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images --id - ;; - esac -} - -_podman_manifest_remove() { - local options_with_args=" - " - - local boolean_options=" - " - - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images --id - ;; - esac -} - -_podman_pull() { - local options_with_args=" - --authfile - --cert-dir - --creds - --override-arch - --override-os - --override-variant - " - local boolean_options=" - --all-tags -a - --disable-content-trust - --help -h - --quiet -q - --tls-verify - " - _complete_ "$options_with_args" "$boolean_options" -} - -_podman_search() { - local options_with_args=" - --authfile - --filter -f - --format - --limit - " - local boolean_options=" - --help - -h - --no-trunc - --list-tags - " - _complete_ "$options_with_args" "$boolean_options" -} - -_podman_unmount() { - _podman_umount $@ -} - -_podman_umount() { - local boolean_options=" - --all -a - --help -h - --force -f - --latest -l - " - local options_with_args=" - " - - local all_options="$options_with_args $boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_container_names - ;; - esac -} - -_podman_mount() { - local boolean_options=" - --all -a - --help -h - --latest -l - --notruncate - " - - local options_with_args=" - --format - " - - local all_options="$options_with_args $boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_container_names - ;; - esac -} - -_podman_push() { - local boolean_options=" - --compress - --digestflag - --help -h - --quiet -q - --tls-verify - " - - local options_with_args=" - --authfile - --cert-dir - --creds - --format - --sign-by - " - - local all_options="$options_with_args $boolean_options" - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images --id - ;; - esac -} - -_podman_container_run() { - local options_with_args=" - --add-host - --annotation - --attach -a - --blkio-weight - --blkio-weight-device - --builtin-volume - --cap-add - --cap-drop - --cgroup-conf - --cgroup-parent - --cidfile - --conmon-pidfile - --cpu-period - --cpu-quota - --cpu-rt-period - --cpu-rt-runtime - --cpu-shares -c - --cpus - --cpuset-cpus - --cpuset-mems - --device - --device-cgroup-rule - --device-read-bps - --device-read-iops - --device-write-bps - --device-write-iops - --dns - --dns-option - --dns-search - --entrypoint - --env -e - --env-file - --env-host - --expose - --gidmap - --group-add - --health-cmd - --health-interval - --health-retries - --health-start-period - --health-timeout - --hostname -h - --http-proxy - --image-volume - --init-path - --ip - --ipc - --kernel-memory - --label -l - --label-file - --log-driver - --log-opt - --mac-address - --memory -m - --memory-reservation - --memory-swap - --memory-swappiness - --name - --network - --no-healthcheck - --no-hosts - --oom-score-adj - --override-arch - --override-os - --override-variant - --pid - --pids-limit - --pod - --pod-id-file - --preserve-fds - --publish -p - --pull - --restart - --rootfs - --runtime - --security-opt - --shm-size - --stop-signal - --stop-timeout - --subgidname - --subuidname - --sysctl - --systemd - --tmpfs - --tz - --uidmap - --ulimit - --umask - --user -u - --userns - --uts - --volume -v - --volumes-from - --workdir -w - " - - local boolean_options=" - --disable-content-trust=false - --help -h - --init - --interactive -i - --oom-kill-disable - --privileged - --publish-all -P - --quiet - --read-only - --read-only-tmpfs - --tty -t - " - - if [ "$command" = "run" -o "$subcommand" = "run" ] ; then - options_with_args="$options_with_args - --detach-keys - --health-cmd - --health-interval - --health-retries - --health-start-period - --health-timeout - " - boolean_options="$boolean_options - --detach -d - --rm - --rmi - --sig-proxy=false - " - __podman_complete_detach_keys && return - __podman_complete_restart && return - fi - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - return - ;; - *) - __podman_complete_images --id - ;; - esac - - - __podman_complete_log_driver_options && return - - local key=$(__podman_map_key_of_current_option '--security-opt') - case "$key" in - label) - [[ $cur == *: ]] && return - COMPREPLY=( $( compgen -W "user: role: type: level: disable" -- "${cur##*=}") ) - if [ "${COMPREPLY[*]}" != "disable" ] ; then - __podman_nospace - fi - return - ;; - seccomp) - local cur=${cur##*=} - _filedir - COMPREPLY+=( $( compgen -W "unconfined" -- "$cur" ) ) - return - ;; - esac - - case "$prev" in - --add-host) - case "$cur" in - *:) - __podman_complete_resolved_hostname - return - ;; - esac - ;; - --attach|-a) - COMPREPLY=( $( compgen -W 'stdin stdout stderr' -- "$cur" ) ) - return - ;; - --cap-add|--cap-drop) - __podman_complete_capabilities - return - ;; - --cidfile|--env-file|--init-path|--label-file|--pod-id-file) - _filedir - return - ;; - --device|--tmpfs|--volume|-v) - case "$cur" in - *:*) - # TODO somehow do _filedir for stuff inside the image, if it's already specified (which is also somewhat difficult to determine) - ;; - '') - COMPREPLY=( $( compgen -W '/' -- "$cur" ) ) - __podman_nospace - ;; - /*) - _filedir - __podman_nospace - ;; - esac - return - ;; - --env|-e) - # we do not append a "=" here because "-e VARNAME" is legal syntax, too - COMPREPLY=( $( compgen -e -- "$cur" ) ) - __podman_nospace - return - ;; - --ipc) - case "$cur" in - *:*) - cur="${cur#*:}" - __podman_complete_containers_running - ;; - *) - COMPREPLY=( $( compgen -W 'host private container:' -- "$cur" ) ) - if [ "$COMPREPLY" = "container:" ]; then - __podman_nospace - fi - ;; - esac - return - ;; - --log-driver) - __podman_complete_log_drivers - return - ;; - --log-opt) - __podman_complete_log_options - return - ;; - --network) - case "$cur" in - container:*) - __podman_complete_containers_all --cur "${cur#*:}" - ;; - *) - COMPREPLY=( $(compgen -W "bridge none host ns: private slirp4netns $(__podman_networks) container:" -- "$cur")) - if [ "${COMPREPLY[*]}" = "container:" ] ; then - __podman_nospace - fi - ;; - esac - return - ;; - --pod) - __podman_complete_pod_names - return - ;; - --pid) - case "$cur" in - *:*) - __podman_complete_containers_running --cur "${cur#*:}" - ;; - *) - COMPREPLY=( $( compgen -W 'host container: private' -- "$cur" ) ) - if [ "$COMPREPLY" = "container:" ]; then - __podman_nospace - fi - ;; - esac - return - ;; - --runtime) - __podman_complete_runtimes - return - ;; - --security-opt) - COMPREPLY=( $( compgen -W "apparmor= label= no-new-privileges seccomp=" -- "$cur") ) - if [ "${COMPREPLY[*]}" != "no-new-privileges" ] ; then - __podman_nospace - fi - return - ;; - --storage-opt) - COMPREPLY=( $( compgen -W "size" -S = -- "$cur") ) - __podman_nospace - return - ;; - --user|-u) - __podman_complete_user_group - return - ;; - --userns) - COMPREPLY=( $( compgen -W "auto container: host keep-id ns: private" -- "$cur" ) ) - return - ;; - --volumes-from) - __podman_complete_containers_all - return - ;; - $(__podman_to_extglob "$options_with_args") ) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$all_options" -- "$cur" ) ) - ;; - *) - local counter=$( __podman_pos_first_nonflag $( __podman_to_alternatives "$options_with_args" ) ) - if [ $cword -eq $counter ]; then - __podman_complete_images - fi - ;; - esac -} - - -_podman_create() { - _podman_container_run -} - - -_podman_run() { - _podman_container_run -} - -_podman_restart() { - local options_with_args=" - --time -t - " - local boolean_options=" - --all -a - --help -h - --latest -l - --running - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_containers_running - ;; - esac -} - -_podman_rm() { - local boolean_options=" - --all -a - --cidfile - --force -f - --help -h - --ignore -i - --latest -l - --volumes -v - " - - local options_with_args=" - " - - local all_options="$options_with_args $boolean_options" - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_container_names - ;; - esac -} - -_podman_rmi() { - local boolean_options=" - --all -a - --force -f - --help -h - " - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images --id - ;; - esac -} - -_podman_stats() { - local boolean_options=" - --all -a - --format - --help -h - --no-reset - --no-stream - " - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_containers_running - ;; - esac -} - -_podman_tag() { - local options_with_args=" - " - local boolean_options=" - --help - -h - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images - ;; - esac -} - -_podman_untag() { - local options_with_args=" - " - local boolean_options=" - --help - -h - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images - ;; - esac -} - -__podman_top_descriptors() { - podman top --list-descriptors -} - -__podman_complete_top_descriptors() { - COMPREPLY=($(compgen -W "$(__podman_top_descriptors)" -- "$cur")) -} - -_podman_top() { - local options_with_args=" - " - local boolean_options=" - --help - -h - --latest - -l - " - - # podman-top works on only *one* container, which means that when we have - # three or more arguments, we can complete with top descriptors. - if [[ "${COMP_CWORD}" -ge 3 ]]; then - __podman_complete_top_descriptors - return +__podman_debug() +{ + if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then + echo "$*" >> "${BASH_COMP_DEBUG_FILE}" fi - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_containers_running - ;; - esac -} - -_podman_version() { - local boolean_options=" - --help - -h - " - local options_with_args=" - --format - -f - " - local all_options="$options_with_args $boolean_options" - - _complete_ "$options_with_args" "$boolean_options" -} - -_podman_save() { - local options_with_args=" - --output -o - --format - " - local boolean_options=" - --compress - --help -h - --quiet -q - " - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images --id - ;; - esac -} - -_podman_pause() { - local boolean_options=" - --all - -a - --help - -h - " - local options_with_args=" - " - local boolean_options="" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_containers_running - ;; - esac -} - -_podman_port() { - local options_with_args=" - " - local boolean_options=" - --all -a - --help -h - --latest -l - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_container_names - ;; - esac -} - -_podman_ls() { - _podman_ps -} - -_podman_ps() { - local options_with_args=" - --filter -f - --format - --last -n - --sort - --watch -w - " - local boolean_options=" - --all -a - --external - --help -h - --latest -l - --namespace --ns - --no-trunc - --pod -p - --quiet -q - --size -s - --sync - " - _complete_ "$options_with_args" "$boolean_options" -} - -_podman_init() { - local boolean_options=" - --all - -a - --help - -h - --latest - -l - " - local options_with_args=" - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_containers_unpauseable - ;; - esac } -_podman_start() { - local options_with_args=" - --detach-keys - " - - local boolean_options=" - --attach -a - --help -h - --interactive -i - --latest -l - --sig-proxy - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_containers_stopped - ;; - esac -} -_podman_stop() { - local options_with_args=" - --time -t - " - local boolean_options=" - --all -a - --cidfile - --help -h - --ignore -i - --latest -l - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_containers_running - ;; - esac -} - -_podman_unpause() { - local boolean_options=" - --all - -a - --help - -h - " - local options_with_args=" - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_containers_unpauseable - ;; - esac -} - -_podman_varlink() { - local options_with_args=" - --timeout -t - " - local boolean_options=" - --help - -h - " - _complete_ "$options_with_args" "$boolean_options" -} - -_podman_wait() { - local options_with_args="" - local boolean_options=" - --help -h - --interval -i - --latest -l - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_container_names - ;; - esac -} - -_complete_() { - local options_with_args=$1 - local boolean_options="$2 -h --help" - - case "$prev" in - $options_with_args) - return - ;; - esac - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) - ;; - esac -} - -_podman_load() { - local options_with_args=" - --input -i - " - local boolean_options=" - --help -h - --quiet -q - " - _complete_ "$options_with_args" "$boolean_options" -} - -_podman_cp() { - local boolean_options=" - --extract - --help -h - --pause - " - _complete_ "$boolean_options" -} - -_podman_login() { - local options_with_args=" - --authfile - --get-login - --password -p - --username -u - " - local boolean_options=" - --help - -h - --password-stdin - " - _complete_ "$options_with_args" "$boolean_options" -} - -_podman_logout() { - local options_with_args=" - --authfile - " - local boolean_options=" - --all - -a - --help - -h - " - _complete_ "$options_with_args" "$boolean_options" -} - -_podman_healthcheck_run() { - local options_with_args="" - - local boolean_options=" - -h - --help - " - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - COMPREPLY=( $( compgen -W " - $(__podman_containers --all) - " -- "$cur" ) ) - __ltrim_colon_completions "$cur" - ;; - esac -} - -_podman_generate_kube() { - local options_with_args=" - --filename -f - " - - local boolean_options=" - -h - --help - -s - --service - " - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - COMPREPLY=( $( compgen -W " - $(__podman_containers --all) - $(__podman_pods) - " -- "$cur" ) ) - __ltrim_colon_completions "$cur" - ;; - esac -} - -_podman_generate_systemd() { - local options_with_args=" - --restart-policy - -t - --time - --container-prefix - --pod-prefix - --separator" - - local boolean_options=" - -h - --help - -n - --name - " - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - COMPREPLY=( $( compgen -W " - $(__podman_containers --all) - " -- "$cur" ) ) - __ltrim_colon_completions "$cur" - ;; - esac -} - -_podman_play_kube() { - local options_with_args=" - --authfile - --cert-dir - --creds - --network - " - - local boolean_options=" - --help -h - --quiet -q - --seccomp-profile-root - --tls-verify - " - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - _filedir - ;; - esac -} - -_podman_events() { - local options_with_args=" - --filter - --format - --help -h - --since - --until - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$options_with_args" -- "$cur")) - ;; - esac -} - -_podman_container_runlabel() { - local options_with_args=" - --authfile - --cert-dir - --creds - --name - " - - local boolean_options=" - --display - --help -h - --quiet -q - --replace - --tls-verify - " - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images --id - ;; - esac -} - -_podman_image_sign() { - local options_with_args=" - --cert-dir - --directory -d - --sign-by - " - local boolean_options=" - --help - -h - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images - ;; - esac -} - -_podman_image_trust_set() { - echo hello - local options_with_args=" - --pubkeysfile -f - --type -t - " - local boolean_options=" - --help - -h - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - COMPREPLY=($(compgen -W "default $( __podman_list_registries )" -- "$cur")) - ;; - esac -} - -_podman_image_trust_show() { - local options_with_args=" - " - local boolean_options=" - --help -h - --json -j - --raw - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images - ;; - esac -} - -_podman_image_trust() { - local boolean_options=" - --help - -h - " - subcommands=" - set - show - " - local aliases=" - list - " - command=image_trust - __podman_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_podman_images_prune() { - local options_with_args=" - " - - local boolean_options=" - --all -a - --help -h - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - esac -} - -_podman_container_prune() { - local options_with_args=" - --filter - " - - local boolean_options=" - --force -f - --help -h - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - esac -} - -_podman_container_exists() { - local options_with_args=" - " - - local boolean_options=" - --external - --help -h - " - - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_images - ;; - esac - -} - -_podman_pod_exists() { - local options_with_args=" - " - - local boolean_options=" - " -} - -_podman_image_exists() { - local options_with_args=" - " - - local boolean_options=" - " -} - -_podman_pod_create() { - local options_with_args=" - --add-host - --cgroup-parent - --dns - --dns-opt - --dns-search - --infra-command - --infra-conmon-pidfile - --infra-image - --ip - --label-file - --label - -l - --mac-address - --name - --network - --no-hosts - --podidfile - --publish - -p - --share - " - - local boolean_options=" - --help -h - --infra - --replace - " - _complete_ "$options_with_args" "$boolean_options" -} - -_podman_pod_kill() { - local options_with_args=" - " - - local boolean_options=" - --all -a - --help -h - --latest -l - --signal -s - " - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_pod_names - ;; - esac -} - -__podman_pod_ps() { - local options_with_args=" - --filter -f - --format - --sort - " - - local boolean_options=" - --cgroup - --ctr-ids - --ctr-names - --ctr-status - --help -h - --labels - --latest -l - --no-trunc - --quiet -q - " - _complete_ "$options_with_args" "$boolean_options" -} - -_podman_pod_ls() { - __podman_pod_ps -} - -_podman_pod_list() { - __podman_pod_ps -} - -_podman_pod_ps() { - __podman_pod_ps -} - -_podman_pod_prune() { - local options_with_args=" - " - - local boolean_options=" - -f - -h - --help - " - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - esac -} - -_podman_pod_restart() { - local options_with_args=" - " - - local boolean_options=" - --all -a - --help -h - --latest -l - " - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_pod_names - ;; - esac -} - -_podman_pod_rm() { - local options_with_args=" - --pod-id-file - " - - local boolean_options=" - --all -a - --force -f - --help -h - --ignore -i - --latest -l - " - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_pod_names - ;; - esac -} - -_podman_pod_start() { - local options_with_args=" - --pod-id-file - " - - local boolean_options=" - --all -a - --help -h - --latest -l - " - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_pod_names - ;; - esac -} - -_podman_pod_stop() { - local options_with_args=" - --pod-id-file - --time -t - " - - local boolean_options=" - --all -a - --cleanup - --help -h - --ignore -i - --latest -l - " - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_pod_names - ;; - esac -} - -_podman_pod_pause() { - local options_with_args=" - " - - local boolean_options=" - --all -a - --help -h - --latest -l - " - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_pod_names - ;; - esac -} - -_podman_pod_unpause() { - local options_with_args=" - " - - local boolean_options=" - --all -a - --help -h - --latest -l - " - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_pod_names - ;; - esac -} - -_podman_pod_inspect() { - local options_with_args=" - --format -f - --latest -l - " - - _complete_ "$options_with_args" -} - - -_podman_pod() { - local boolean_options=" - --help - -h - " - subcommands=" - create - inspect - kill - pause - ps - restart - rm - start - stats - stop - top - unpause - " - local aliases=" - list - ls - " - __podman_subcommands "$subcommands $aliases" && return - - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac -} - -_podman_volume_create() { - local options_with_args=" - --driver - --label -l - --opt -o - " - - local boolean_options=" - --help - -h - " - - _complete_ "$options_with_args" "$boolean_options" -} - -_podman_volume_ls() { - local options_with_args=" - --filter - --format -f - " - - local boolean_options=" - --help -h - --quiet -q - " - - _complete_ "$options_with_args" "$boolean_options" -} - -_podman_volume_inspect() { - local options_with_args=" - --format - -f - " - - local boolean_options=" - --all -a - --help -h - " +__podman_perform_completion() +{ + __podman_debug + __podman_debug "========= starting completion logic ==========" + __podman_debug "cur is ${cur}, words[*] is ${words[*]}, #words[@] is ${#words[@]}, cword is $cword" + + # The user could have moved the cursor backwards on the command-line. + # We need to trigger completion from the $cword location, so we need + # to truncate the command-line ($words) up to the $cword location. + words=("${words[@]:0:$cword+1}") + __podman_debug "Truncated words[*]: ${words[*]}," + + local shellCompDirectiveError=1 + local shellCompDirectiveNoSpace=2 + local shellCompDirectiveNoFileComp=4 + local shellCompDirectiveFilterFileExt=8 + local shellCompDirectiveFilterDirs=16 + local shellCompDirectiveLegacyCustomComp=32 + local shellCompDirectiveLegacyCustomArgsComp=64 + + local out requestComp lastParam lastChar comp directive args flagPrefix + + # Prepare the command to request completions for the program. + # Calling ${words[0]} instead of directly podman allows to handle aliases + args=("${words[@]:1}") + requestComp="${words[0]} __completeNoDesc ${args[*]}" + + lastParam=${words[$((${#words[@]}-1))]} + lastChar=${lastParam:$((${#lastParam}-1)):1} + __podman_debug "lastParam ${lastParam}, lastChar ${lastChar}" + + if [ -z "${cur}" ] && [ "${lastChar}" != "=" ]; then + # If the last parameter is complete (there is a space following it) + # We add an extra empty parameter so we can indicate this to the go method. + __podman_debug "Adding extra empty parameter" + requestComp="${requestComp} \"\"" + fi - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_volume_names - ;; - esac -} + # When completing a flag with an = (e.g., podman -n=<TAB>) + # bash focuses on the part after the =, so we need to remove + # the flag part from $cur + if [[ "${cur}" == -*=* ]]; then + flagPrefix="${cur%%=*}=" + cur="${cur#*=}" + fi -_podman_volume_rm() { - local options_with_args="" + __podman_debug "Calling ${requestComp}" + # Use eval to handle any environment variables and such + out=$(eval "${requestComp}" 2>/dev/null) + + # Extract the directive integer at the very end of the output following a colon (:) + directive=${out##*:} + # Remove the directive + out=${out%:*} + if [ "${directive}" = "${out}" ]; then + # There is not directive specified + directive=0 + fi + __podman_debug "The completion directive is: ${directive}" + __podman_debug "The completions are: ${out[*]}" + + if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then + # Error code. No completion. + __podman_debug "Received error from custom completion go code" + return + else + if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then + if [[ $(type -t compopt) = "builtin" ]]; then + __podman_debug "Activating no space" + compopt -o nospace + fi + fi + if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then + if [[ $(type -t compopt) = "builtin" ]]; then + __podman_debug "Activating no file completion" + compopt +o default + fi + fi + fi - local boolean_options=" - --all -a - --force -f - --help -h - " + if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then + # File extension filtering + local fullFilter filter filteringCmd + + # Do not use quotes around the $out variable or else newline + # characters will be kept. + for filter in ${out[*]}; do + fullFilter+="$filter|" + done + + filteringCmd="_filedir $fullFilter" + __podman_debug "File filtering command: $filteringCmd" + $filteringCmd + elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then + # File completion for directories only + + # Use printf to strip any trailing newline + local subdir + subdir=$(printf "%s" "${out[0]}") + if [ -n "$subdir" ]; then + __podman_debug "Listing directories in $subdir" + pushd "$subdir" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return + else + __podman_debug "Listing directories in ." + _filedir -d + fi + elif [ $((directive & shellCompDirectiveLegacyCustomComp)) -ne 0 ]; then + local cmd + __podman_debug "Legacy custom completion. Directive: $directive, cmds: ${out[*]}" + + # The following variables should get their value through the commands + # we have received as completions and are parsing below. + local last_command + local nouns + + # Execute every command received + while IFS='' read -r cmd; do + __podman_debug "About to execute: $cmd" + eval "$cmd" + done < <(printf "%s\n" "${out[@]}") + + __podman_debug "last_command: $last_command" + __podman_debug "nouns[0]: ${nouns[0]}, nouns[1]: ${nouns[1]}" + + if [ $((directive & shellCompDirectiveLegacyCustomArgsComp)) -ne 0 ]; then + # We should call the global legacy custom completion function, if it is defined + if declare -F __podman_custom_func >/dev/null; then + # Use command name qualified legacy custom func + __podman_debug "About to call: __podman_custom_func" + __podman_custom_func + elif declare -F __custom_func >/dev/null; then + # Otherwise fall back to unqualified legacy custom func for compatibility + __podman_debug "About to call: __custom_func" + __custom_func + fi + fi + else + local tab + tab=$(printf '\t') + local longest=0 + # Look for the longest completion so that we can format things nicely + while IFS='' read -r comp; do + comp=${comp%%$tab*} + if ((${#comp}>longest)); then + longest=${#comp} + fi + done < <(printf "%s\n" "${out[@]}") + + local completions=() + while IFS='' read -r comp; do + if [ -z "$comp" ]; then + continue + fi + + __podman_debug "Original comp: $comp" + comp="$(__podman_format_comp_descriptions "$comp" "$longest")" + __podman_debug "Final comp: $comp" + completions+=("$comp") + done < <(printf "%s\n" "${out[@]}") + + while IFS='' read -r comp; do + # Although this script should only be used for bash + # there may be programs that still convert the bash + # script into a zsh one. To continue supporting those + # programs, we do this single adaptation for zsh + if [ -n "${ZSH_VERSION}" ]; then + # zsh completion needs --flag= prefix + COMPREPLY+=("$flagPrefix$comp") + else + COMPREPLY+=("$comp") + fi + done < <(compgen -W "${completions[*]}" -- "$cur") + + # If there is a single completion left, remove the description text + if [ ${#COMPREPLY[*]} -eq 1 ]; then + __podman_debug "COMPREPLY[0]: ${COMPREPLY[0]}" + comp="${COMPREPLY[0]%% *}" + __podman_debug "Removed description from single completion, which is now: ${comp}" + COMPREPLY=() + COMPREPLY+=("$comp") + fi + fi - _complete_ "$options_with_args" "$boolean_options" - case "$cur" in - -*) - COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur")) - ;; - *) - __podman_complete_volume_names - ;; - esac + __podman_handle_special_char "$cur" : + __podman_handle_special_char "$cur" = } -_podman_volume_prune() { - local options_with_args="" - - local boolean_options=" - --force -f - --help -h - " - - _complete_ "$options_with_args" "$boolean_options" +__podman_handle_special_char() +{ + local comp="$1" + local char=$2 + if [[ "$comp" == *${char}* && "$COMP_WORDBREAKS" == *${char}* ]]; then + local word=${comp%"${comp##*${char}}"} + local idx=${#COMPREPLY[*]} + while [[ $((--idx)) -ge 0 ]]; do + COMPREPLY[$idx]=${COMPREPLY[$idx]#"$word"} + done + fi } -_podman_volume() { - local boolean_options=" - --help -h - " - subcommands=" - create - inspect - ls - prune - rm - " - local aliases=" - list - remove - " - __podman_subcommands "$subcommands $aliases" && return +__podman_format_comp_descriptions() +{ + local tab + tab=$(printf '\t') + local comp="$1" + local longest=$2 + + # Properly format the description string which follows a tab character if there is one + if [[ "$comp" == *$tab* ]]; then + desc=${comp#*$tab} + comp=${comp%%$tab*} + + # $COLUMNS stores the current shell width. + # Remove an extra 4 because we add 2 spaces and 2 parentheses. + maxdesclength=$(( COLUMNS - longest - 4 )) + + # Make sure we can fit a description of at least 8 characters + # if we are to align the descriptions. + if [[ $maxdesclength -gt 8 ]]; then + # Add the proper number of spaces to align the descriptions + for ((i = ${#comp} ; i < longest ; i++)); do + comp+=" " + done + else + # Don't pad the descriptions so we can fit more text after the completion + maxdesclength=$(( COLUMNS - ${#comp} - 4 )) + fi + + # If there is enough space for any description text, + # truncate the descriptions that are too long for the shell width + if [ $maxdesclength -gt 0 ]; then + if [ ${#desc} -gt $maxdesclength ]; then + desc=${desc:0:$(( maxdesclength - 1 ))} + desc+="…" + fi + comp+=" ($desc)" + fi + fi - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "--help" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) ) - ;; - esac + # Must use printf to escape all special characters + printf "%q" "${comp}" } -_podman_podman() { - local options_with_args=" - --cni-config-dir - --conmon - --connection -c - --events-backend - --hooks-dir - --identity - --log-level - --namespace - --network-cmd-path - --root - --runroot - --runtime - --storage-driver - --storage-opt - --tmpdir - --url - " - local boolean_options=" - --help -h - --remote -r - --syslog - --version -v - " - commands=" - attach - auto-update - build - commit - container - cp - create - diff - events - exec - export - generate - healthcheck - history - image - images - import - info - inspect - kill - load - login - logout - logs - manifest - mount - network - pause - play - pod - port - ps - pull - push - restart - rm - rmi - run - save - search - start - stats - stop - system - tag - top - umount - unmount - unpause - untag - varlink - version - volume - wait - " +__start_podman() +{ + local cur prev words cword - case "$prev" in - $main_options_with_args_glob ) - return - ;; - esac + COMPREPLY=() + _get_comp_words_by_ref -n "=:" cur prev words cword - case "$cur" in - -*) - COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) ) - ;; - *) - COMPREPLY=( $( compgen -W "${commands[*]} help" -- "$cur" ) ) - ;; - esac + __podman_perform_completion } -_cli_bash_autocomplete() { - local cur opts base - - COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - COMPREPLY=() - local cur prev words cword +if [[ $(type -t compopt) = "builtin" ]]; then + complete -o default -F __start_podman podman +else + complete -o default -o nospace -F __start_podman podman +fi - _get_comp_words_by_ref -n : cur prev words cword - - local command=${PROG} cpos=0 - local counter=1 - counter=1 - while [ $counter -lt $cword ]; do - case "!${words[$counter]}" in - *) - command=$(echo "${words[$counter]}" | sed 's/-/_/g') - cpos=$counter - (( cpos++ )) - break - ;; - esac - (( counter++ )) - done - - local completions_func=_podman_${command} - declare -F $completions_func >/dev/null && $completions_func - - eval "$previous_extglob_setting" - return 0 -} +# ex: ts=4 sw=4 et filetype=sh -complete -F _cli_bash_autocomplete podman +# This file is generated with "podman completion"; see: podman-completion(1) diff --git a/completions/bash/podman-remote b/completions/bash/podman-remote new file mode 100644 index 000000000..43a5ce959 --- /dev/null +++ b/completions/bash/podman-remote @@ -0,0 +1,271 @@ +# bash completion for podman-remote -*- shell-script -*- + +__podman-remote_debug() +{ + if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then + echo "$*" >> "${BASH_COMP_DEBUG_FILE}" + fi +} + +__podman-remote_perform_completion() +{ + __podman-remote_debug + __podman-remote_debug "========= starting completion logic ==========" + __podman-remote_debug "cur is ${cur}, words[*] is ${words[*]}, #words[@] is ${#words[@]}, cword is $cword" + + # The user could have moved the cursor backwards on the command-line. + # We need to trigger completion from the $cword location, so we need + # to truncate the command-line ($words) up to the $cword location. + words=("${words[@]:0:$cword+1}") + __podman-remote_debug "Truncated words[*]: ${words[*]}," + + local shellCompDirectiveError=1 + local shellCompDirectiveNoSpace=2 + local shellCompDirectiveNoFileComp=4 + local shellCompDirectiveFilterFileExt=8 + local shellCompDirectiveFilterDirs=16 + local shellCompDirectiveLegacyCustomComp=32 + local shellCompDirectiveLegacyCustomArgsComp=64 + + local out requestComp lastParam lastChar comp directive args flagPrefix + + # Prepare the command to request completions for the program. + # Calling ${words[0]} instead of directly podman-remote allows to handle aliases + args=("${words[@]:1}") + requestComp="${words[0]} __completeNoDesc ${args[*]}" + + lastParam=${words[$((${#words[@]}-1))]} + lastChar=${lastParam:$((${#lastParam}-1)):1} + __podman-remote_debug "lastParam ${lastParam}, lastChar ${lastChar}" + + if [ -z "${cur}" ] && [ "${lastChar}" != "=" ]; then + # If the last parameter is complete (there is a space following it) + # We add an extra empty parameter so we can indicate this to the go method. + __podman-remote_debug "Adding extra empty parameter" + requestComp="${requestComp} \"\"" + fi + + # When completing a flag with an = (e.g., podman-remote -n=<TAB>) + # bash focuses on the part after the =, so we need to remove + # the flag part from $cur + if [[ "${cur}" == -*=* ]]; then + flagPrefix="${cur%%=*}=" + cur="${cur#*=}" + fi + + __podman-remote_debug "Calling ${requestComp}" + # Use eval to handle any environment variables and such + out=$(eval "${requestComp}" 2>/dev/null) + + # Extract the directive integer at the very end of the output following a colon (:) + directive=${out##*:} + # Remove the directive + out=${out%:*} + if [ "${directive}" = "${out}" ]; then + # There is not directive specified + directive=0 + fi + __podman-remote_debug "The completion directive is: ${directive}" + __podman-remote_debug "The completions are: ${out[*]}" + + if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then + # Error code. No completion. + __podman-remote_debug "Received error from custom completion go code" + return + else + if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then + if [[ $(type -t compopt) = "builtin" ]]; then + __podman-remote_debug "Activating no space" + compopt -o nospace + fi + fi + if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then + if [[ $(type -t compopt) = "builtin" ]]; then + __podman-remote_debug "Activating no file completion" + compopt +o default + fi + fi + fi + + if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then + # File extension filtering + local fullFilter filter filteringCmd + + # Do not use quotes around the $out variable or else newline + # characters will be kept. + for filter in ${out[*]}; do + fullFilter+="$filter|" + done + + filteringCmd="_filedir $fullFilter" + __podman-remote_debug "File filtering command: $filteringCmd" + $filteringCmd + elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then + # File completion for directories only + + # Use printf to strip any trailing newline + local subdir + subdir=$(printf "%s" "${out[0]}") + if [ -n "$subdir" ]; then + __podman-remote_debug "Listing directories in $subdir" + pushd "$subdir" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return + else + __podman-remote_debug "Listing directories in ." + _filedir -d + fi + elif [ $((directive & shellCompDirectiveLegacyCustomComp)) -ne 0 ]; then + local cmd + __podman-remote_debug "Legacy custom completion. Directive: $directive, cmds: ${out[*]}" + + # The following variables should get their value through the commands + # we have received as completions and are parsing below. + local last_command + local nouns + + # Execute every command received + while IFS='' read -r cmd; do + __podman-remote_debug "About to execute: $cmd" + eval "$cmd" + done < <(printf "%s\n" "${out[@]}") + + __podman-remote_debug "last_command: $last_command" + __podman-remote_debug "nouns[0]: ${nouns[0]}, nouns[1]: ${nouns[1]}" + + if [ $((directive & shellCompDirectiveLegacyCustomArgsComp)) -ne 0 ]; then + # We should call the global legacy custom completion function, if it is defined + if declare -F __podman-remote_custom_func >/dev/null; then + # Use command name qualified legacy custom func + __podman-remote_debug "About to call: __podman-remote_custom_func" + __podman-remote_custom_func + elif declare -F __custom_func >/dev/null; then + # Otherwise fall back to unqualified legacy custom func for compatibility + __podman-remote_debug "About to call: __custom_func" + __custom_func + fi + fi + else + local tab + tab=$(printf '\t') + local longest=0 + # Look for the longest completion so that we can format things nicely + while IFS='' read -r comp; do + comp=${comp%%$tab*} + if ((${#comp}>longest)); then + longest=${#comp} + fi + done < <(printf "%s\n" "${out[@]}") + + local completions=() + while IFS='' read -r comp; do + if [ -z "$comp" ]; then + continue + fi + + __podman-remote_debug "Original comp: $comp" + comp="$(__podman-remote_format_comp_descriptions "$comp" "$longest")" + __podman-remote_debug "Final comp: $comp" + completions+=("$comp") + done < <(printf "%s\n" "${out[@]}") + + while IFS='' read -r comp; do + # Although this script should only be used for bash + # there may be programs that still convert the bash + # script into a zsh one. To continue supporting those + # programs, we do this single adaptation for zsh + if [ -n "${ZSH_VERSION}" ]; then + # zsh completion needs --flag= prefix + COMPREPLY+=("$flagPrefix$comp") + else + COMPREPLY+=("$comp") + fi + done < <(compgen -W "${completions[*]}" -- "$cur") + + # If there is a single completion left, remove the description text + if [ ${#COMPREPLY[*]} -eq 1 ]; then + __podman-remote_debug "COMPREPLY[0]: ${COMPREPLY[0]}" + comp="${COMPREPLY[0]%% *}" + __podman-remote_debug "Removed description from single completion, which is now: ${comp}" + COMPREPLY=() + COMPREPLY+=("$comp") + fi + fi + + __podman-remote_handle_special_char "$cur" : + __podman-remote_handle_special_char "$cur" = +} + +__podman-remote_handle_special_char() +{ + local comp="$1" + local char=$2 + if [[ "$comp" == *${char}* && "$COMP_WORDBREAKS" == *${char}* ]]; then + local word=${comp%"${comp##*${char}}"} + local idx=${#COMPREPLY[*]} + while [[ $((--idx)) -ge 0 ]]; do + COMPREPLY[$idx]=${COMPREPLY[$idx]#"$word"} + done + fi +} + +__podman-remote_format_comp_descriptions() +{ + local tab + tab=$(printf '\t') + local comp="$1" + local longest=$2 + + # Properly format the description string which follows a tab character if there is one + if [[ "$comp" == *$tab* ]]; then + desc=${comp#*$tab} + comp=${comp%%$tab*} + + # $COLUMNS stores the current shell width. + # Remove an extra 4 because we add 2 spaces and 2 parentheses. + maxdesclength=$(( COLUMNS - longest - 4 )) + + # Make sure we can fit a description of at least 8 characters + # if we are to align the descriptions. + if [[ $maxdesclength -gt 8 ]]; then + # Add the proper number of spaces to align the descriptions + for ((i = ${#comp} ; i < longest ; i++)); do + comp+=" " + done + else + # Don't pad the descriptions so we can fit more text after the completion + maxdesclength=$(( COLUMNS - ${#comp} - 4 )) + fi + + # If there is enough space for any description text, + # truncate the descriptions that are too long for the shell width + if [ $maxdesclength -gt 0 ]; then + if [ ${#desc} -gt $maxdesclength ]; then + desc=${desc:0:$(( maxdesclength - 1 ))} + desc+="…" + fi + comp+=" ($desc)" + fi + fi + + # Must use printf to escape all special characters + printf "%q" "${comp}" +} + +__start_podman-remote() +{ + local cur prev words cword + + COMPREPLY=() + _get_comp_words_by_ref -n "=:" cur prev words cword + + __podman-remote_perform_completion +} + +if [[ $(type -t compopt) = "builtin" ]]; then + complete -o default -F __start_podman-remote podman-remote +else + complete -o default -o nospace -F __start_podman-remote podman-remote +fi + +# ex: ts=4 sw=4 et filetype=sh + +# This file is generated with "podman-remote completion"; see: podman-completion(1) diff --git a/completions/fish/podman-remote.fish b/completions/fish/podman-remote.fish new file mode 100644 index 000000000..e0216844d --- /dev/null +++ b/completions/fish/podman-remote.fish @@ -0,0 +1,182 @@ +# fish completion for podman-remote -*- shell-script -*- + +function __podman_remote_debug + set file "$BASH_COMP_DEBUG_FILE" + if test -n "$file" + echo "$argv" >> $file + end +end + +function __podman_remote_perform_completion + __podman_remote_debug "Starting __podman_remote_perform_completion" + + set args (string split -- " " (commandline -c)) + set lastArg "$args[-1]" + + __podman_remote_debug "args: $args" + __podman_remote_debug "last arg: $lastArg" + + set emptyArg "" + if test -z "$lastArg" + __podman_remote_debug "Setting emptyArg" + set emptyArg \"\" + end + __podman_remote_debug "emptyArg: $emptyArg" + + if not type -q "$args[1]" + # This can happen when "complete --do-complete podman-remote" is called when running this script. + __podman_remote_debug "Cannot find $args[1]. No completions." + return + end + + set requestComp "$args[1] __complete $args[2..-1] $emptyArg" + __podman_remote_debug "Calling $requestComp" + + set results (eval $requestComp 2> /dev/null) + set comps $results[1..-2] + set directiveLine $results[-1] + + # For Fish, when completing a flag with an = (e.g., <program> -n=<TAB>) + # completions must be prefixed with the flag + set flagPrefix (string match -r -- '-.*=' "$lastArg") + + __podman_remote_debug "Comps: $comps" + __podman_remote_debug "DirectiveLine: $directiveLine" + __podman_remote_debug "flagPrefix: $flagPrefix" + + for comp in $comps + printf "%s%s\n" "$flagPrefix" "$comp" + end + + printf "%s\n" "$directiveLine" +end + +# This function does two things: +# - Obtain the completions and store them in the global __podman_remote_comp_results +# - Return false if file completion should be performed +function __podman_remote_prepare_completions + __podman_remote_debug "" + __podman_remote_debug "========= starting completion logic ==========" + + # Start fresh + set --erase __podman_remote_comp_results + + set results (__podman_remote_perform_completion) + __podman_remote_debug "Completion results: $results" + + if test -z "$results" + __podman_remote_debug "No completion, probably due to a failure" + # Might as well do file completion, in case it helps + return 1 + end + + set directive (string sub --start 2 $results[-1]) + set --global __podman_remote_comp_results $results[1..-2] + + __podman_remote_debug "Completions are: $__podman_remote_comp_results" + __podman_remote_debug "Directive is: $directive" + + set shellCompDirectiveError 1 + set shellCompDirectiveNoSpace 2 + set shellCompDirectiveNoFileComp 4 + set shellCompDirectiveFilterFileExt 8 + set shellCompDirectiveFilterDirs 16 + set shellCompDirectiveLegacyCustomComp 32 + set shellCompDirectiveLegacyCustomArgsComp 64 + + if test -z "$directive" + set directive 0 + end + + set compErr (math (math --scale 0 $directive / $shellCompDirectiveError) % 2) + if test $compErr -eq 1 + __podman_remote_debug "Received error directive: aborting." + # Might as well do file completion, in case it helps + return 1 + end + + set legacyCustom (math (math --scale 0 $directive / $shellCompDirectiveLegacyCustomComp) % 2) + set legacyCustomArgs (math (math --scale 0 $directive / $shellCompDirectiveLegacyCustomArgsComp) % 2) + if test $legacyCustom -eq 1; or test $legacyCustomArgs -eq 1 + __podman_remote_debug "Legacy bash custom completion not applicable to fish" + # Do full file completion instead + set --global __podman_remote_comp_do_file_comp 1 + return 1 + end + + set filefilter (math (math --scale 0 $directive / $shellCompDirectiveFilterFileExt) % 2) + set dirfilter (math (math --scale 0 $directive / $shellCompDirectiveFilterDirs) % 2) + if test $filefilter -eq 1; or test $dirfilter -eq 1 + __podman_remote_debug "File extension filtering or directory filtering not supported" + # Do full file completion instead + return 1 + end + + set nospace (math (math --scale 0 $directive / $shellCompDirectiveNoSpace) % 2) + set nofiles (math (math --scale 0 $directive / $shellCompDirectiveNoFileComp) % 2) + + __podman_remote_debug "nospace: $nospace, nofiles: $nofiles" + + # If we want to prevent a space, or if file completion is NOT disabled, + # we need to count the number of valid completions. + # To do so, we will filter on prefix as the completions we have received + # may not already be filtered so as to allow fish to match on different + # criteria than prefix. + if test $nospace -ne 0; or test $nofiles -eq 0 + set prefix (commandline -t) + __podman_remote_debug "prefix: $prefix" + + set completions + for comp in $__podman_remote_comp_results + if test (string match -e -r "^$prefix" "$comp") + set -a completions $comp + end + end + set --global __podman_remote_comp_results $completions + __podman_remote_debug "Filtered completions are: $__podman_remote_comp_results" + + # Important not to quote the variable for count to work + set numComps (count $__podman_remote_comp_results) + __podman_remote_debug "numComps: $numComps" + + if test $numComps -eq 1; and test $nospace -ne 0 + # To support the "nospace" directive we trick the shell + # by outputting an extra, longer completion. + # We must first split on \t to get rid of the descriptions because + # the extra character we add to the fake second completion must be + # before the description. We don't need descriptions anyway since + # there is only a single real completion which the shell will expand + # immediately. + __podman_remote_debug "Adding second completion to perform nospace directive" + set split (string split --max 1 \t $__podman_remote_comp_results[1]) + set --global __podman_remote_comp_results $split[1] $split[1]. + __podman_remote_debug "Completions are now: $__podman_remote_comp_results" + end + + if test $numComps -eq 0; and test $nofiles -eq 0 + # To be consistent with bash and zsh, we only trigger file + # completion when there are no other completions + __podman_remote_debug "Requesting file completion" + return 1 + end + end + + return 0 +end + +# Since Fish completions are only loaded once the user triggers them, we trigger them ourselves +# so we can properly delete any completions provided by another script. +# The space after the the program name is essential to trigger completion for the program +# and not completion of the program name itself. +complete --do-complete "podman-remote " > /dev/null 2>&1 +# Using '> /dev/null 2>&1' since '&>' is not supported in older versions of fish. + +# Remove any pre-existing completions for the program since we will be handling all of them. +complete -c podman-remote -e + +# The call to __podman_remote_prepare_completions will setup __podman_remote_comp_results +# which provides the program's completion choices. +complete -c podman-remote -n '__podman_remote_prepare_completions' -f -a '$__podman_remote_comp_results' + + +# This file is generated with "podman-remote completion"; see: podman-completion(1) diff --git a/completions/fish/podman.fish b/completions/fish/podman.fish new file mode 100644 index 000000000..2a89e7118 --- /dev/null +++ b/completions/fish/podman.fish @@ -0,0 +1,182 @@ +# fish completion for podman -*- shell-script -*- + +function __podman_debug + set file "$BASH_COMP_DEBUG_FILE" + if test -n "$file" + echo "$argv" >> $file + end +end + +function __podman_perform_completion + __podman_debug "Starting __podman_perform_completion" + + set args (string split -- " " (commandline -c)) + set lastArg "$args[-1]" + + __podman_debug "args: $args" + __podman_debug "last arg: $lastArg" + + set emptyArg "" + if test -z "$lastArg" + __podman_debug "Setting emptyArg" + set emptyArg \"\" + end + __podman_debug "emptyArg: $emptyArg" + + if not type -q "$args[1]" + # This can happen when "complete --do-complete podman" is called when running this script. + __podman_debug "Cannot find $args[1]. No completions." + return + end + + set requestComp "$args[1] __complete $args[2..-1] $emptyArg" + __podman_debug "Calling $requestComp" + + set results (eval $requestComp 2> /dev/null) + set comps $results[1..-2] + set directiveLine $results[-1] + + # For Fish, when completing a flag with an = (e.g., <program> -n=<TAB>) + # completions must be prefixed with the flag + set flagPrefix (string match -r -- '-.*=' "$lastArg") + + __podman_debug "Comps: $comps" + __podman_debug "DirectiveLine: $directiveLine" + __podman_debug "flagPrefix: $flagPrefix" + + for comp in $comps + printf "%s%s\n" "$flagPrefix" "$comp" + end + + printf "%s\n" "$directiveLine" +end + +# This function does two things: +# - Obtain the completions and store them in the global __podman_comp_results +# - Return false if file completion should be performed +function __podman_prepare_completions + __podman_debug "" + __podman_debug "========= starting completion logic ==========" + + # Start fresh + set --erase __podman_comp_results + + set results (__podman_perform_completion) + __podman_debug "Completion results: $results" + + if test -z "$results" + __podman_debug "No completion, probably due to a failure" + # Might as well do file completion, in case it helps + return 1 + end + + set directive (string sub --start 2 $results[-1]) + set --global __podman_comp_results $results[1..-2] + + __podman_debug "Completions are: $__podman_comp_results" + __podman_debug "Directive is: $directive" + + set shellCompDirectiveError 1 + set shellCompDirectiveNoSpace 2 + set shellCompDirectiveNoFileComp 4 + set shellCompDirectiveFilterFileExt 8 + set shellCompDirectiveFilterDirs 16 + set shellCompDirectiveLegacyCustomComp 32 + set shellCompDirectiveLegacyCustomArgsComp 64 + + if test -z "$directive" + set directive 0 + end + + set compErr (math (math --scale 0 $directive / $shellCompDirectiveError) % 2) + if test $compErr -eq 1 + __podman_debug "Received error directive: aborting." + # Might as well do file completion, in case it helps + return 1 + end + + set legacyCustom (math (math --scale 0 $directive / $shellCompDirectiveLegacyCustomComp) % 2) + set legacyCustomArgs (math (math --scale 0 $directive / $shellCompDirectiveLegacyCustomArgsComp) % 2) + if test $legacyCustom -eq 1; or test $legacyCustomArgs -eq 1 + __podman_debug "Legacy bash custom completion not applicable to fish" + # Do full file completion instead + set --global __podman_comp_do_file_comp 1 + return 1 + end + + set filefilter (math (math --scale 0 $directive / $shellCompDirectiveFilterFileExt) % 2) + set dirfilter (math (math --scale 0 $directive / $shellCompDirectiveFilterDirs) % 2) + if test $filefilter -eq 1; or test $dirfilter -eq 1 + __podman_debug "File extension filtering or directory filtering not supported" + # Do full file completion instead + return 1 + end + + set nospace (math (math --scale 0 $directive / $shellCompDirectiveNoSpace) % 2) + set nofiles (math (math --scale 0 $directive / $shellCompDirectiveNoFileComp) % 2) + + __podman_debug "nospace: $nospace, nofiles: $nofiles" + + # If we want to prevent a space, or if file completion is NOT disabled, + # we need to count the number of valid completions. + # To do so, we will filter on prefix as the completions we have received + # may not already be filtered so as to allow fish to match on different + # criteria than prefix. + if test $nospace -ne 0; or test $nofiles -eq 0 + set prefix (commandline -t) + __podman_debug "prefix: $prefix" + + set completions + for comp in $__podman_comp_results + if test (string match -e -r "^$prefix" "$comp") + set -a completions $comp + end + end + set --global __podman_comp_results $completions + __podman_debug "Filtered completions are: $__podman_comp_results" + + # Important not to quote the variable for count to work + set numComps (count $__podman_comp_results) + __podman_debug "numComps: $numComps" + + if test $numComps -eq 1; and test $nospace -ne 0 + # To support the "nospace" directive we trick the shell + # by outputting an extra, longer completion. + # We must first split on \t to get rid of the descriptions because + # the extra character we add to the fake second completion must be + # before the description. We don't need descriptions anyway since + # there is only a single real completion which the shell will expand + # immediately. + __podman_debug "Adding second completion to perform nospace directive" + set split (string split --max 1 \t $__podman_comp_results[1]) + set --global __podman_comp_results $split[1] $split[1]. + __podman_debug "Completions are now: $__podman_comp_results" + end + + if test $numComps -eq 0; and test $nofiles -eq 0 + # To be consistent with bash and zsh, we only trigger file + # completion when there are no other completions + __podman_debug "Requesting file completion" + return 1 + end + end + + return 0 +end + +# Since Fish completions are only loaded once the user triggers them, we trigger them ourselves +# so we can properly delete any completions provided by another script. +# The space after the the program name is essential to trigger completion for the program +# and not completion of the program name itself. +complete --do-complete "podman " > /dev/null 2>&1 +# Using '> /dev/null 2>&1' since '&>' is not supported in older versions of fish. + +# Remove any pre-existing completions for the program since we will be handling all of them. +complete -c podman -e + +# The call to __podman_prepare_completions will setup __podman_comp_results +# which provides the program's completion choices. +complete -c podman -n '__podman_prepare_completions' -f -a '$__podman_comp_results' + + +# This file is generated with "podman completion"; see: podman-completion(1) diff --git a/completions/zsh/_podman b/completions/zsh/_podman index b65c3dbb8..b25e9cb08 100644 --- a/completions/zsh/_podman +++ b/completions/zsh/_podman @@ -1,379 +1,181 @@ -#compdef podman +#compdef _podman podman -# To get zsh to reread this file: unset -f _podman;rm -f ~/.zcompdump;compinit +# zsh completion for podman -*- shell-script -*- -# On rereads, reset cache. (Not that the caching works, but some day it might) -unset -m '_podman_*' - -############################################################################### -# BEGIN 'podman help' parsers -- for options, subcommands, and usage - -# Run 'podman XX --help', set _podman_commands to a formatted list of cmds -_read_podman_commands() { - local line - - # Cache: the intention here is to run each 'podman help' only once. - # Unfortunately it doesn't seem to actually be working: even though - # I can see the var_ref in my shell, it's not visible here. - local _var_ref=_podman_commands_"${*// /_}" - typeset -ga _podman_commands - _podman_commands=(${(P)_var_ref}) - (( $#_podman_commands )) && return - - _call_program podman podman "$@" --help |\ - sed -n -e '0,/^Available Commands/d' -e '/^[A-Z]/q;p' |\ - sed -e 's/^ \+\([^ ]\+\) \+/\1:/' |\ - egrep . | while read line; do - _podman_commands+=($line) - done - - eval "typeset -ga $_var_ref" - eval "$_var_ref=(\$_podman_commands)" -} - -# Run 'podman XX --help', set _podman_option_list to a formatted list -# of option options for XX -_read_podman_options() { - local line - - local _var_ref=_podman_options_"${*// /_}" - eval "typeset -ga ${_var_ref}" - typeset -ga _podman_option_list - _podman_option_list=(${(P)_var_ref}) - (( $#_podman_option_list )) && return - - # Extract the Options; strip leading whitespace; pack '-f, --foo' - # as '-f,--foo' (no space); then add '=' to '--foo string'. - # The result will be, e.g. '-f,--foo=string Description of Option' - _call_program podman podman "$@" --help |\ - sed -n -e '0,/^Options:/d' -e '/^$/q;p' |\ - grep '^ \+-' |\ - sed -e 's/^ *//' -e 's/^\(-.,\) --/\1--/' |\ - sed -e 's/^\(-[^ ]\+\) \([^ ]\+\) /\1=\2 /' |\ - while read options desc;do - # options like --foo=string: split into --foo & string - local -a tmpa - local optval= - tmpa=(${(s.=.)options}) - if [ -n "$tmpa[2]" ]; then - options=$tmpa[1] - optval=$tmpa[2] - fi - - # 'podman attach --detach-keys' includes ']' in help msg - desc=${desc//\]/\\]} - - for option in ${(s:,:)options}; do - if [ -n "$optval" ]; then - _podman_option_list+=("${option}[$desc]:$(_podman_find_helper ${options} ${optval} ${desc})") - else - _podman_option_list+=("${option}[$desc]") - fi - done - done - - eval "typeset -ga $_var_ref=(\$_podman_option_list)" -} - -# Run 'podman XXX --help', set _podman_usage to the line after "Usage:" -_read_podman_usage() { - local _var_ref=_podman_usage_"${*// /_}" - typeset -ga _podman_usage - _podman_usage=${(P)_var_ref} - (( $#_podman_usage )) && return - - _podman_usage=$(_call_program podman podman "$@" --help |\ - grep -A1 'Usage:'|\ - tail -1 |\ - sed -e 's/^ *//') - - eval "typeset -ga $_var_ref" - eval "$_var_ref=\$_podman_usage" -} - -# END 'podman help' parsers -############################################################################### -# BEGIN custom helpers for individual option arguments - -# Find a zsh helper for a given option or command-line option -_podman_find_helper() { - local options=$1 - local optval=$2 - local desc=$3 - local helper= - - # Yes, this is a lot of hardcoding. IMHO it's still better than - # hardcoding every possible podman option. - # FIXME: there are many more options that could use helpers. - if expr "$desc" : ".*[Dd]irectory" >/dev/null; then - optval="directory" - helper="_files -/" - elif expr "$desc" : ".*[Pp]ath" >/dev/null; then - optval="path" - helper=_files - # For messages like 'restart policy ("always"|"no"|"on-failure") - elif optlist=$(expr "$desc" : '.*(\(\"[^\\)]\+|[^\\)]\+\"\))' 2>/dev/null); then - optval=${${options##--}//-/ } # "--log-level" => "log level" - optlist=${optlist//\"/} # "a"|"b"|"c" => a|b|c - optlist=${optlist//\|/ } # a|b|c => a b c - # FIXME: how to present values _in order_, not sorted alphabetically? - helper="($optlist)" +__podman_debug() +{ + local file="$BASH_COMP_DEBUG_FILE" + if [[ -n ${file} ]]; then + echo "$*" >> "${file}" fi - echo "$optval:$helper" -} - -# END custom helpers for individual option arguments -############################################################################### -# BEGIN helpers for command-line args (containers, images) - -__podman_helper_generic() { - local expl line - local -a results - - local foo1=$1; shift - local name=$2; shift - - _call_program $foo1 podman "$@" |\ - while read line; do - results+=(${=line}) - done - - _wanted $foo1 expl $name compadd ${(u)results} -} - -_podman_helper_image() { - __podman_helper_generic podman-images 'images' \ - images --format '{{.ID}}\ {{.Repository}}:{{.Tag}}' -} - -# FIXME: at some point, distinguish between running & stopped containers -_podman_helper_container() { - __podman_helper_generic podman-containers 'containers' \ - ps -a --format '{{.Names}}\ {{.ID}}' -} - -_podman_helper_pod() { - __podman_helper_generic podman-pods 'pods' pod list --format '{{.Name}}' } -_podman_helper_volume() { - __podman_helper_generic podman-volumes 'volumes' volume ls --format '{{.Name}}' -} - -# Combinations. This one seen in diff & inspect -_podman_helper_container-or-image() { - _podman_helper_image - _podman_helper_container -} - -# Seen in generate-kube -_podman_helper_container-or-pod() { - _podman_helper_container - _podman_helper_pod -} - -# For top and pod-top -_podman_helper_format-descriptors() { - __podman_helper_generic top-format-descriptors 'format descriptors' \ - top --list-descriptors -} - -# for push, login/logout, and trust -# FIXME: some day, use this to define a helper for IMAGE-PATH (in 'pull') -_podman_helper_registry() { - local expl - local -a registries +_podman() +{ + local shellCompDirectiveError=1 + local shellCompDirectiveNoSpace=2 + local shellCompDirectiveNoFileComp=4 + local shellCompDirectiveFilterFileExt=8 + local shellCompDirectiveFilterDirs=16 + local shellCompDirectiveLegacyCustomComp=32 + local shellCompDirectiveLegacyCustomArgsComp=64 + + local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace + local -a completions + + __podman_debug "\n========= starting completion logic ==========" + __podman_debug "CURRENT: ${CURRENT}, words[*]: ${words[*]}" + + # The user could have moved the cursor backwards on the command-line. + # We need to trigger completion from the $CURRENT location, so we need + # to truncate the command-line ($words) up to the $CURRENT location. + # (We cannot use $CURSOR as its value does not work when a command is an alias.) + words=("${=words[1,CURRENT]}") + __podman_debug "Truncated words[*]: ${words[*]}," + + lastParam=${words[-1]} + lastChar=${lastParam[-1]} + __podman_debug "lastParam: ${lastParam}, lastChar: ${lastChar}" + + # For zsh, when completing a flag with an = (e.g., podman -n=<TAB>) + # completions must be prefixed with the flag + setopt local_options BASH_REMATCH + if [[ "${lastParam}" =~ '-.*=' ]]; then + # We are dealing with a flag with an = + flagPrefix="-P ${BASH_REMATCH}" + fi - # Suggestions for improvement more than welcome. - python3 -c 'from configparser import ConfigParser;cp=ConfigParser();cp.read("/etc/containers/registries.conf");registries=eval(cp.get("registries.search","registries"));[print(r) for r in registries]' 2>/dev/null | while read line; do - registries+=($line) - done + # Prepare the command to obtain completions + requestComp="${words[1]} __complete ${words[2,-1]}" + if [ "${lastChar}" = "" ]; then + # If the last parameter is complete (there is a space following it) + # We add an extra empty parameter so we can indicate this to the go completion code. + __podman_debug "Adding extra empty parameter" + requestComp="${requestComp} \"\"" + fi - if (( $#registries )); then - _wanted podman-registry expl "registry" compadd ${(u)registries} + __podman_debug "About to call: eval ${requestComp}" + + # Use eval to handle any environment variables and such + out=$(eval ${requestComp} 2>/dev/null) + __podman_debug "completion output: ${out}" + + # Extract the directive integer following a : from the last line + local lastLine + while IFS='\n' read -r line; do + lastLine=${line} + done < <(printf "%s\n" "${out[@]}") + __podman_debug "last line: ${lastLine}" + + if [ "${lastLine[1]}" = : ]; then + directive=${lastLine[2,-1]} + # Remove the directive including the : and the newline + local suffix + (( suffix=${#lastLine}+2)) + out=${out[1,-$suffix]} else - _hosts + # There is no directive specified. Leave $out as is. + __podman_debug "No directive found. Setting do default" + directive=0 fi -} - -# END helpers for command-line args -############################################################################### -# BEGIN figure out completion helpers for a given (sub)command -# Read Usage string for this subcommand, set up helpers for its subargs -_set_up_podman_args() { - _read_podman_usage "$@" + __podman_debug "directive: ${directive}" + __podman_debug "completions: ${out}" + __podman_debug "flagPrefix: ${flagPrefix}" - typeset -ga _podman_args=() - # E.g. 'podman exec [options] CONTAINER [...' -> 'CONTAINER [....' - local usage_rhs=$(expr "$_podman_usage" : ".*\[options\] \+\(.*\)") - - # e.g. podman pod ps which takes no further args - if [ -z "$usage_rhs" ]; then + if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then + __podman_debug "Completion received error. Ignoring completions." return fi - # podman diff & inspect accept 'CONTAINER | IMAGE'; make into one keyword. - usage_rhs=${usage_rhs// | /-OR-} + while IFS='\n' read -r comp; do + if [ -n "$comp" ]; then + # If requested, completions are returned with a description. + # The description is preceded by a TAB character. + # For zsh's _describe, we need to use a : instead of a TAB. + # We first need to escape any : as part of the completion itself. + comp=${comp//:/\\:} - # Arg parsing. There are three possibilities in Usage messages: - # - # [IMAGE] - optional image arg (zero or one) - # IMAGE - exactly one image arg - # IMAGE [IMAGE...] - one or more image args - # and, theoretically: - # [IMAGE...] - zero or more? Haven't seen it in practice. Defer. - # - # For completion purposes, we only need to provide two options: - # one, or more than one? That is: continue offering completion - # suggestions after the first one? For that, we make two passes; - # in the first, mark an option as either '' (only one) or + local tab=$(printf '\t') + comp=${comp//$tab/:} - # Parse each command-line arg seen in usage message - local word - local -A _seen=() - for word in ${=usage_rhs}; do - local unbracketed=$(expr "$word" : "\[\(.*\)\]") + __podman_debug "Adding completion: ${comp}" + completions+=${comp} + lastComp=$comp + fi + done < <(printf "%s\n" "${out[@]}") - if [ -n "$unbracketed" ]; then - # Remove all dots; assume(!?) that they'll all be at the end - unbracketed=${unbracketed//./} + if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then + __podman_debug "Activating nospace." + noSpace="-S ''" + fi - if (( $_seen[$unbracketed] )); then - # Is this the same word as the previous arg? - if expr "$_podman_args[-1]" : ":$unbracketed:" >/dev/null; then - # Yes. Make it '*:...' instead of ':...', indicating >1 - _podman_args[-1]="*$_podman_args[-1]" - fi - continue + if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then + # File extension filtering + local filteringCmd + filteringCmd='_files' + for filter in ${completions[@]}; do + if [ ${filter[1]} != '*' ]; then + # zsh requires a glob pattern to do file filtering + filter="\*.$filter" fi - - word=$unbracketed + filteringCmd+=" -g $filter" + done + filteringCmd+=" ${flagPrefix}" + + __podman_debug "File filtering command: $filteringCmd" + _arguments '*:filename:'"$filteringCmd" + elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then + # File completion for directories only + local subDir + subdir="${completions[1]}" + if [ -n "$subdir" ]; then + __podman_debug "Listing directories in $subdir" + pushd "${subdir}" >/dev/null 2>&1 + else + __podman_debug "Listing directories in ." fi - # As of 2019-03 all such instances are '[COMMAND [ARG...]]' and are, - # of course, at the end of the line. We can't offer completion for - # these, because the container will have different commands than - # the host system... but try anyway. - if [ "$word" = '[COMMAND' ]; then - # e.g. podman create, exec, run - _podman_args+=( - ":command: _command_names -e" - "*::arguments: _normal" - ) - return + local result + _arguments '*:dirname:_files -/'" ${flagPrefix}" + result=$? + if [ -n "$subdir" ]; then + popd >/dev/null 2>&1 fi + return $result + else + __podman_debug "Calling _describe" + if eval _describe "completions" completions $flagPrefix $noSpace; then + __podman_debug "_describe found some completions" - # Look for an existing helper, e.g. IMAGE -> _podman_helper_image - local helper="_podman_helper_${(L)word}" - if (( $+functions[$helper] )); then - : + # Return the success of having called _describe + return 0 else - # No defined helper. Reset, but check for known expressions. - helper= - case "$word" in - KUBEFILE) helper='_files -g "*.y(|a)ml(-.)"' ;; - PATH) helper='_files' ;; - esac - fi - - # Another special case: 'top' actually takes multiple options - local multi= - if [ "$word" = "FORMAT-DESCRIPTORS" ]; then - multi='*' + __podman_debug "_describe did not find completions." + __podman_debug "Checking if we should do file completion." + if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then + __podman_debug "deactivating file completion" + + # We must return an error code here to let zsh know that there were no + # completions found by _describe; this is what will trigger other + # matching algorithms to attempt to find completions. + # For example zsh can match letters in the middle of words. + return 1 + else + # Perform file completion + __podman_debug "Activating file completion" + + # We must return the result of this command, so it must be the + # last command, or else we must store its result to return it. + _arguments '*:filename:_files'" ${flagPrefix}" + fi fi - _podman_args+=("$multi:${(L)word}:$helper") - _seen[$word]=1 - done -} - -# For an endpoint command, i.e. not a subcommand. -_podman_terminus() { - typeset -A opt_args - typeset -ga _podman_option_list - typeset -ga _podman_args - integer ret=1 - - # Find out what args it takes (e.g. image(s), container(s)) and see - # if we have helpers for them. - _set_up_podman_args "$@" - _arguments -C $_podman_option_list $_podman_args && ret=0 - - return ret -} - -# END figure out completion helpers for a given (sub)command -################################################################################ -# BEGIN actual entry point - -# This is the main entry point; it's also where we (recursively) come in -# to handle nested subcommands such as 'podman container' or even 3-level -# ones like 'podman generate kube'. Nesting is complicated, so here's -# my best understanding as of 2019-03-12: -# -# Easy first: when you do "podman <TAB>" zsh calls us, we run 'podman --help', -# figure out the global options and subcommands, and run the magic _arguments -# command. That will offer those options/subcommands, and complete, etc. -# -# Where it gets harder is when you do "podman container mount <TAB>". -# zsh first calls us with words=(podman container mount) but we don't -# want all that full context yet! We want to go a piece at a time, -# handling 'container' first, then 'mount'; ending up with our -# final 'podman container mount --help' giving us suitable options -# and no subcommands; from which we determine that it's a terminus -# and jump to a function that handles non-subcommand arguments. -# -# This is the closest I've yet come to understanding zsh completion; -# it is still incomplete and may in fact be incorrect. But it works -# better than anything I've played with so far. -_podman_subcommand() { - local curcontext="$curcontext" state line - typeset -A opt_args - integer ret=1 - - # Run 'podman --help' / 'podman system --help' for our context (initially - # empty, then possibly under subcommands); from those, get a list of - # options appropriate for this context and, if applicable, subcommands. - _read_podman_options "$@" - _read_podman_commands "$@" - - # Now, is this a sub-subcommand, or does it have args? - if (( $#_podman_commands )); then - # Subcommands required (podman, podman system, etc) - local cmd=${words// /_} - _arguments -C $_podman_option_list \ - "(-): :->command" \ - "(-)*:: :->option-or-argument" \ - && ret=0 - - case $state in - (command) - _describe -t command "podman $* command" _podman_commands && ret=0 - ;; - (option-or-argument) - # I think this is when we have a _completed_ subcommand. - # Recurse back into here, offering options for that subcommand. - curcontext=${curcontext%:*:*}:podman-${words[1]}: - _podman_subcommand "$@" ${words[1]} && ret=0 - ;; - esac - else - # At a terminus, i.e. podman info, podman history; find out - # what args it takes. - _podman_terminus "$@" && ret=0 fi - - return ret } -_podman() { - _podman_subcommand -} +# don't run the completion function when being source-ed or eval-ed +if [ "$funcstack[1]" = "_podman" ]; then + _podman +fi -# Local Variables: -# mode: shell-script -# sh-indentation: 4 -# indent-tabs-mode: nil -# sh-basic-offset: 4 -# End: -# vim: ft=zsh sw=4 ts=4 et +# This file is generated with "podman completion"; see: podman-completion(1) diff --git a/completions/zsh/_podman-remote b/completions/zsh/_podman-remote new file mode 100644 index 000000000..fc2984cfd --- /dev/null +++ b/completions/zsh/_podman-remote @@ -0,0 +1,181 @@ +#compdef _podman-remote podman-remote + +# zsh completion for podman-remote -*- shell-script -*- + +__podman-remote_debug() +{ + local file="$BASH_COMP_DEBUG_FILE" + if [[ -n ${file} ]]; then + echo "$*" >> "${file}" + fi +} + +_podman-remote() +{ + local shellCompDirectiveError=1 + local shellCompDirectiveNoSpace=2 + local shellCompDirectiveNoFileComp=4 + local shellCompDirectiveFilterFileExt=8 + local shellCompDirectiveFilterDirs=16 + local shellCompDirectiveLegacyCustomComp=32 + local shellCompDirectiveLegacyCustomArgsComp=64 + + local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace + local -a completions + + __podman-remote_debug "\n========= starting completion logic ==========" + __podman-remote_debug "CURRENT: ${CURRENT}, words[*]: ${words[*]}" + + # The user could have moved the cursor backwards on the command-line. + # We need to trigger completion from the $CURRENT location, so we need + # to truncate the command-line ($words) up to the $CURRENT location. + # (We cannot use $CURSOR as its value does not work when a command is an alias.) + words=("${=words[1,CURRENT]}") + __podman-remote_debug "Truncated words[*]: ${words[*]}," + + lastParam=${words[-1]} + lastChar=${lastParam[-1]} + __podman-remote_debug "lastParam: ${lastParam}, lastChar: ${lastChar}" + + # For zsh, when completing a flag with an = (e.g., podman-remote -n=<TAB>) + # completions must be prefixed with the flag + setopt local_options BASH_REMATCH + if [[ "${lastParam}" =~ '-.*=' ]]; then + # We are dealing with a flag with an = + flagPrefix="-P ${BASH_REMATCH}" + fi + + # Prepare the command to obtain completions + requestComp="${words[1]} __complete ${words[2,-1]}" + if [ "${lastChar}" = "" ]; then + # If the last parameter is complete (there is a space following it) + # We add an extra empty parameter so we can indicate this to the go completion code. + __podman-remote_debug "Adding extra empty parameter" + requestComp="${requestComp} \"\"" + fi + + __podman-remote_debug "About to call: eval ${requestComp}" + + # Use eval to handle any environment variables and such + out=$(eval ${requestComp} 2>/dev/null) + __podman-remote_debug "completion output: ${out}" + + # Extract the directive integer following a : from the last line + local lastLine + while IFS='\n' read -r line; do + lastLine=${line} + done < <(printf "%s\n" "${out[@]}") + __podman-remote_debug "last line: ${lastLine}" + + if [ "${lastLine[1]}" = : ]; then + directive=${lastLine[2,-1]} + # Remove the directive including the : and the newline + local suffix + (( suffix=${#lastLine}+2)) + out=${out[1,-$suffix]} + else + # There is no directive specified. Leave $out as is. + __podman-remote_debug "No directive found. Setting do default" + directive=0 + fi + + __podman-remote_debug "directive: ${directive}" + __podman-remote_debug "completions: ${out}" + __podman-remote_debug "flagPrefix: ${flagPrefix}" + + if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then + __podman-remote_debug "Completion received error. Ignoring completions." + return + fi + + while IFS='\n' read -r comp; do + if [ -n "$comp" ]; then + # If requested, completions are returned with a description. + # The description is preceded by a TAB character. + # For zsh's _describe, we need to use a : instead of a TAB. + # We first need to escape any : as part of the completion itself. + comp=${comp//:/\\:} + + local tab=$(printf '\t') + comp=${comp//$tab/:} + + __podman-remote_debug "Adding completion: ${comp}" + completions+=${comp} + lastComp=$comp + fi + done < <(printf "%s\n" "${out[@]}") + + if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then + __podman-remote_debug "Activating nospace." + noSpace="-S ''" + fi + + if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then + # File extension filtering + local filteringCmd + filteringCmd='_files' + for filter in ${completions[@]}; do + if [ ${filter[1]} != '*' ]; then + # zsh requires a glob pattern to do file filtering + filter="\*.$filter" + fi + filteringCmd+=" -g $filter" + done + filteringCmd+=" ${flagPrefix}" + + __podman-remote_debug "File filtering command: $filteringCmd" + _arguments '*:filename:'"$filteringCmd" + elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then + # File completion for directories only + local subDir + subdir="${completions[1]}" + if [ -n "$subdir" ]; then + __podman-remote_debug "Listing directories in $subdir" + pushd "${subdir}" >/dev/null 2>&1 + else + __podman-remote_debug "Listing directories in ." + fi + + local result + _arguments '*:dirname:_files -/'" ${flagPrefix}" + result=$? + if [ -n "$subdir" ]; then + popd >/dev/null 2>&1 + fi + return $result + else + __podman-remote_debug "Calling _describe" + if eval _describe "completions" completions $flagPrefix $noSpace; then + __podman-remote_debug "_describe found some completions" + + # Return the success of having called _describe + return 0 + else + __podman-remote_debug "_describe did not find completions." + __podman-remote_debug "Checking if we should do file completion." + if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then + __podman-remote_debug "deactivating file completion" + + # We must return an error code here to let zsh know that there were no + # completions found by _describe; this is what will trigger other + # matching algorithms to attempt to find completions. + # For example zsh can match letters in the middle of words. + return 1 + else + # Perform file completion + __podman-remote_debug "Activating file completion" + + # We must return the result of this command, so it must be the + # last command, or else we must store its result to return it. + _arguments '*:filename:_files'" ${flagPrefix}" + fi + fi + fi +} + +# don't run the completion function when being source-ed or eval-ed +if [ "$funcstack[1]" = "_podman-remote" ]; then + _podman-remote +fi + +# This file is generated with "podman-remote completion"; see: podman-completion(1) |