@@ -178,52 +178,78 @@ __docker_complete_container_ids() {
178178 COMPREPLY=( $( compgen -W " ${containers[*]} " -- " $cur " ) )
179179}
180180
181+ # __docker_images returns a list of images. For each image, up to three representations
182+ # can be generated: the repository (e.g. busybox), repository:tag (e.g. busybox:latest)
183+ # and the ID (e.g. sha256:ee22cbbd4ea3dff63c86ba60c7691287c321e93adfc1009604eb1dde7ec88645).
184+ #
185+ # The optional arguments `--repo`, `--tag` and `--id` select the representations that
186+ # may be returned. Whether or not a particular representation is actually returned
187+ # depends on the user's customization through several environment variables:
188+ # - image IDs are only shown if DOCKER_COMPLETION_SHOW_IMAGE_IDS=all|non-intermediate.
189+ # - tags can be excluded by setting DOCKER_COMPLETION_SHOW_TAGS=no.
190+ # - repositories are always shown.
191+ #
192+ # In cases where an exact image specification is needed, `--force-tag` can be used.
193+ # It ignores DOCKER_COMPLETION_SHOW_TAGS and only lists valid repository:tag combinations,
194+ # avoiding repository names that would default to a potentially missing default tag.
195+ #
196+ # Additional arguments to `docker image ls` may be specified in order to filter the list,
197+ # e.g. `__docker_images --filter dangling=true`.
198+ #
181199__docker_images () {
182- local images_args=" "
183-
184- case " $DOCKER_COMPLETION_SHOW_IMAGE_IDS " in
185- all)
186- images_args=" --no-trunc -a"
187- ;;
188- non-intermediate)
189- images_args=" --no-trunc"
190- ;;
191- esac
200+ local repo_format=' {{.Repository}}'
201+ local tag_format=' {{.Repository}}:{{.Tag}}'
202+ local id_format=' {{.ID}}'
203+ local all
204+ local format
192205
193- local repo_print_command
194- if [ " ${DOCKER_COMPLETION_SHOW_TAGS:- yes} " = " yes" ]; then
195- repo_print_command=' print $1; print $1":"$2'
196- else
197- repo_print_command=' print $1'
206+ if [ " $DOCKER_COMPLETION_SHOW_IMAGE_IDS " = " all" ] ; then
207+ all=' --all'
198208 fi
199209
200- local awk_script
201- case " $DOCKER_COMPLETION_SHOW_IMAGE_IDS " in
202- all|non-intermediate)
203- awk_script=' NR>1 { print $3; if ($1 != "<none>") { ' " $repo_print_command " ' } }'
204- ;;
205- none|* )
206- awk_script=' NR>1 && $1 != "<none>" { ' " $repo_print_command " ' }'
207- ;;
208- esac
210+ while true ; do
211+ case " $1 " in
212+ --repo)
213+ format+=" $repo_format \n"
214+ shift
215+ ;;
216+ --tag)
217+ if [ " ${DOCKER_COMPLETION_SHOW_TAGS:- yes} " = " yes" ]; then
218+ format+=" $tag_format \n"
219+ fi
220+ shift
221+ ;;
222+ --id)
223+ if [[ $DOCKER_COMPLETION_SHOW_IMAGE_IDS =~ ^(all| non-intermediate)$ ]] ; then
224+ format+=" $id_format \n"
225+ fi
226+ shift
227+ ;;
228+ --force-tag)
229+ # like `--tag` but ignores environment setting
230+ format+=" $tag_format \n"
231+ shift
232+ ;;
233+ * )
234+ break
235+ ;;
236+ esac
237+ done
209238
210- __docker_q images $images_args | awk " $awk_script " | grep -v ' <none>$'
239+ __docker_q image ls --no-trunc --format " ${format % \\ n} " $all " $@ " | grep -v ' <none>$'
211240}
212241
242+ # __docker_complete_images applies completion of images based on the current value of `$cur` or
243+ # the value of the optional first option `--cur`, if given.
244+ # See __docker_images for customization of the returned items.
213245__docker_complete_images () {
214- COMPREPLY=( $( compgen -W " $( __docker_images) " -- " $cur " ) )
215- __ltrim_colon_completions " $cur "
216- }
217-
218- __docker_complete_image_repos () {
219- local repos=" $( __docker_q images | awk ' NR>1 && $1 != "<none>" { print $1 }' ) "
220- COMPREPLY=( $( compgen -W " $repos " -- " $cur " ) )
221- }
222-
223- __docker_complete_image_repos_and_tags () {
224- local reposAndTags=" $( __docker_q images | awk ' NR>1 && $1 != "<none>" { print $1; print $1":"$2 }' ) "
225- COMPREPLY=( $( compgen -W " $reposAndTags " -- " $cur " ) )
226- __ltrim_colon_completions " $cur "
246+ local current=" $cur "
247+ if [ " $1 " = " --cur" ] ; then
248+ current=" $2 "
249+ shift 2
250+ fi
251+ COMPREPLY=( $( compgen -W " $( __docker_images " $@ " ) " -- " $current " ) )
252+ __ltrim_colon_completions " $current "
227253}
228254
229255# __docker_networks returns a list of all networks. Additional options to
@@ -1354,11 +1380,8 @@ _docker_container_commit() {
13541380 if [ " $cword " -eq " $counter " ]; then
13551381 __docker_complete_containers_all
13561382 return
1357- fi
1358- (( counter++ ))
1359-
1360- if [ " $cword " -eq " $counter " ]; then
1361- __docker_complete_image_repos_and_tags
1383+ elif [ " $cword " -eq " $(( counter + 1 )) " ]; then
1384+ __docker_complete_images --repo --tag
13621385 return
13631386 fi
13641387 ;;
@@ -1529,8 +1552,7 @@ _docker_container_ls() {
15291552 local key=$( __docker_map_key_of_current_option ' --filter|-f' )
15301553 case " $key " in
15311554 ancestor)
1532- cur=" ${cur##* =} "
1533- __docker_complete_images
1555+ __docker_complete_images --cur " ${cur##* =} " --repo --tag --id
15341556 return
15351557 ;;
15361558 before)
@@ -1998,7 +2020,7 @@ _docker_container_run_and_create() {
19982020 * )
19992021 local counter=$( __docker_pos_first_nonflag " $( __docker_to_alternatives " $options_with_args " ) " )
20002022 if [ " $cword " -eq " $counter " ]; then
2001- __docker_complete_images
2023+ __docker_complete_images --repo --tag --id
20022024 fi
20032025 ;;
20042026 esac
@@ -2513,7 +2535,7 @@ _docker_image_build() {
25132535 return
25142536 ;;
25152537 --cache-from)
2516- __docker_complete_image_repos_and_tags
2538+ __docker_complete_images --repo --tag --id
25172539 return
25182540 ;;
25192541 --file|-f|--iidfile)
@@ -2541,7 +2563,7 @@ _docker_image_build() {
25412563 return
25422564 ;;
25432565 --tag|-t)
2544- __docker_complete_image_repos_and_tags
2566+ __docker_complete_images --repo --tag
25452567 return
25462568 ;;
25472569 --target)
@@ -2587,9 +2609,9 @@ _docker_image_history() {
25872609 COMPREPLY=( $( compgen -W " --format --help --human=false -H=false --no-trunc --quiet -q" -- " $cur " ) )
25882610 ;;
25892611 * )
2590- local counter=$( __docker_pos_first_nonflag)
2612+ local counter=$( __docker_pos_first_nonflag ' --format ' )
25912613 if [ " $cword " -eq " $counter " ]; then
2592- __docker_complete_images
2614+ __docker_complete_images --force-tag --id
25932615 fi
25942616 ;;
25952617 esac
@@ -2613,12 +2635,10 @@ _docker_image_import() {
26132635 * )
26142636 local counter=$( __docker_pos_first_nonflag ' --change|-c|--message|-m' )
26152637 if [ " $cword " -eq " $counter " ]; then
2638+ _filedir
26162639 return
2617- fi
2618- (( counter++ ))
2619-
2620- if [ " $cword " -eq " $counter " ]; then
2621- __docker_complete_image_repos_and_tags
2640+ elif [ " $cword " -eq " $(( counter + 1 )) " ]; then
2641+ __docker_complete_images --repo --tag
26222642 return
26232643 fi
26242644 ;;
@@ -2651,9 +2671,8 @@ _docker_image_list() {
26512671_docker_image_ls () {
26522672 local key=$( __docker_map_key_of_current_option ' --filter|-f' )
26532673 case " $key " in
2654- before|since|reference)
2655- cur=" ${cur##* =} "
2656- __docker_complete_images
2674+ before|since)
2675+ __docker_complete_images --cur " ${cur##* =} " --force-tag --id
26572676 return
26582677 ;;
26592678 dangling)
@@ -2663,6 +2682,10 @@ _docker_image_ls() {
26632682 label)
26642683 return
26652684 ;;
2685+ reference)
2686+ __docker_complete_images --cur " ${cur##* =} " --repo --tag
2687+ return
2688+ ;;
26662689 esac
26672690
26682691 case " $prev " in
@@ -2684,7 +2707,7 @@ _docker_image_ls() {
26842707 return
26852708 ;;
26862709 * )
2687- __docker_complete_image_repos
2710+ __docker_complete_images --repo --tag
26882711 ;;
26892712 esac
26902713}
@@ -2725,12 +2748,12 @@ _docker_image_pull() {
27252748 for arg in " ${COMP_WORDS[@]} " ; do
27262749 case " $arg " in
27272750 --all-tags|-a)
2728- __docker_complete_image_repos
2751+ __docker_complete_images --repo
27292752 return
27302753 ;;
27312754 esac
27322755 done
2733- __docker_complete_image_repos_and_tags
2756+ __docker_complete_images --repo --tag
27342757 fi
27352758 ;;
27362759 esac
@@ -2744,7 +2767,7 @@ _docker_image_push() {
27442767 * )
27452768 local counter=$( __docker_pos_first_nonflag)
27462769 if [ " $cword " -eq " $counter " ]; then
2747- __docker_complete_image_repos_and_tags
2770+ __docker_complete_images --repo --tag
27482771 fi
27492772 ;;
27502773 esac
@@ -2760,7 +2783,7 @@ _docker_image_rm() {
27602783 COMPREPLY=( $( compgen -W " --force -f --help --no-prune" -- " $cur " ) )
27612784 ;;
27622785 * )
2763- __docker_complete_images
2786+ __docker_complete_images --force-tag --id
27642787 ;;
27652788 esac
27662789}
@@ -2782,7 +2805,7 @@ _docker_image_save() {
27822805 COMPREPLY=( $( compgen -W " --help --output -o" -- " $cur " ) )
27832806 ;;
27842807 * )
2785- __docker_complete_images
2808+ __docker_complete_images --repo --tag --id
27862809 ;;
27872810 esac
27882811}
@@ -2796,13 +2819,10 @@ _docker_image_tag() {
27962819 local counter=$( __docker_pos_first_nonflag)
27972820
27982821 if [ " $cword " -eq " $counter " ]; then
2799- __docker_complete_image_repos_and_tags
2822+ __docker_complete_images --force-tag --id
28002823 return
2801- fi
2802- (( counter++ ))
2803-
2804- if [ " $cword " -eq " $counter " ]; then
2805- __docker_complete_image_repos_and_tags
2824+ elif [ " $cword " -eq " $(( counter + 1 )) " ]; then
2825+ __docker_complete_images --repo --tag
28062826 return
28072827 fi
28082828 ;;
@@ -2858,7 +2878,7 @@ _docker_inspect() {
28582878 ' ' )
28592879 COMPREPLY=( $( compgen -W "
28602880 $( __docker_containers --all)
2861- $( __docker_images)
2881+ $( __docker_images --force-tag --id )
28622882 $( __docker_networks)
28632883 $( __docker_nodes)
28642884 $( __docker_plugins_installed)
@@ -2872,7 +2892,7 @@ _docker_inspect() {
28722892 __docker_complete_containers_all
28732893 ;;
28742894 image)
2875- __docker_complete_images
2895+ __docker_complete_images --force-tag --id
28762896 ;;
28772897 network)
28782898 __docker_complete_networks
@@ -3495,7 +3515,7 @@ _docker_service_update_and_create() {
34953515 esac
34963516 ;;
34973517 --image)
3498- __docker_complete_image_repos_and_tags
3518+ __docker_complete_images --repo --tag --id
34993519 return
35003520 ;;
35013521 --network-add|--network-rm)
@@ -3591,7 +3611,7 @@ _docker_service_update_and_create() {
35913611 fi
35923612 else
35933613 if [ " $cword " -eq " $counter " ]; then
3594- __docker_complete_images
3614+ __docker_complete_images --repo --tag --id
35953615 fi
35963616 fi
35973617 ;;
@@ -4639,8 +4659,7 @@ _docker_system_events() {
46394659 return
46404660 ;;
46414661 image)
4642- cur=" ${cur##* =} "
4643- __docker_complete_images
4662+ __docker_complete_images --cur " ${cur##* =} " --repo --tag
46444663 return
46454664 ;;
46464665 network)
@@ -4737,7 +4756,7 @@ _docker_trust_revoke() {
47374756 * )
47384757 local counter=$( __docker_pos_first_nonflag)
47394758 if [ " $cword " -eq " $counter " ]; then
4740- __docker_complete_images
4759+ __docker_complete_images --repo --tag
47414760 fi
47424761 ;;
47434762 esac
@@ -4751,7 +4770,7 @@ _docker_trust_sign() {
47514770 * )
47524771 local counter=$( __docker_pos_first_nonflag)
47534772 if [ " $cword " -eq " $counter " ]; then
4754- __docker_complete_images
4773+ __docker_complete_images --force-tag --id
47554774 fi
47564775 ;;
47574776 esac
@@ -4765,7 +4784,7 @@ _docker_trust_view() {
47654784 * )
47664785 local counter=$( __docker_pos_first_nonflag)
47674786 if [ " $cword " -eq " $counter " ]; then
4768- __docker_complete_images
4787+ __docker_complete_images --repo --tag
47694788 fi
47704789 ;;
47714790 esac
0 commit comments