Add zsh completion for 'docker ps --filter' values
| ... | ... |
@@ -50,11 +50,11 @@ __docker_arguments() {
|
| 50 | 50 |
__docker_get_containers() {
|
| 51 | 51 |
[[ $PREFIX = -* ]] && return 1 |
| 52 | 52 |
integer ret=1 |
| 53 |
- local kind |
|
| 54 |
- declare -a running stopped lines args |
|
| 53 |
+ local kind type line s |
|
| 54 |
+ declare -a running stopped lines args names |
|
| 55 | 55 |
|
| 56 |
- kind=$1 |
|
| 57 |
- shift |
|
| 56 |
+ kind=$1; shift |
|
| 57 |
+ type=$1; shift |
|
| 58 | 58 |
[[ $kind = (stopped|all) ]] && args=($args -a) |
| 59 | 59 |
|
| 60 | 60 |
lines=(${(f)"$(_call_program commands docker $docker_options ps --no-trunc $args)"})
|
| ... | ... |
@@ -73,39 +73,40 @@ __docker_get_containers() {
|
| 73 | 73 |
lines=(${lines[2,-1]})
|
| 74 | 74 |
|
| 75 | 75 |
# Container ID |
| 76 |
- local line |
|
| 77 |
- local s |
|
| 78 |
- for line in $lines; do |
|
| 79 |
- s="${${line[${begin[CONTAINER ID]},${end[CONTAINER ID]}]%% ##}[0,12]}"
|
|
| 80 |
- s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
|
|
| 81 |
- s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}"
|
|
| 82 |
- if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then
|
|
| 83 |
- stopped=($stopped $s) |
|
| 84 |
- else |
|
| 85 |
- running=($running $s) |
|
| 86 |
- fi |
|
| 87 |
- done |
|
| 76 |
+ if [[ $type = (ids|all) ]]; then |
|
| 77 |
+ for line in $lines; do |
|
| 78 |
+ s="${${line[${begin[CONTAINER ID]},${end[CONTAINER ID]}]%% ##}[0,12]}"
|
|
| 79 |
+ s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
|
|
| 80 |
+ s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}"
|
|
| 81 |
+ if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then
|
|
| 82 |
+ stopped=($stopped $s) |
|
| 83 |
+ else |
|
| 84 |
+ running=($running $s) |
|
| 85 |
+ fi |
|
| 86 |
+ done |
|
| 87 |
+ fi |
|
| 88 | 88 |
|
| 89 | 89 |
# Names: we only display the one without slash. All other names |
| 90 | 90 |
# are generated and may clutter the completion. However, with |
| 91 | 91 |
# Swarm, all names may be prefixed by the swarm node name. |
| 92 |
- local -a names |
|
| 93 |
- for line in $lines; do |
|
| 94 |
- names=(${(ps:,:)${${line[${begin[NAMES]},${end[NAMES]}]}%% *}})
|
|
| 95 |
- # First step: find a common prefix and strip it (swarm node case) |
|
| 96 |
- (( ${#${(u)names%%/*}} == 1 )) && names=${names#${names[1]%%/*}/}
|
|
| 97 |
- # Second step: only keep the first name without a / |
|
| 98 |
- s=${${names:#*/*}[1]}
|
|
| 99 |
- # If no name, well give up. |
|
| 100 |
- (( $#s != 0 )) || continue |
|
| 101 |
- s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
|
|
| 102 |
- s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}"
|
|
| 103 |
- if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then
|
|
| 104 |
- stopped=($stopped $s) |
|
| 105 |
- else |
|
| 106 |
- running=($running $s) |
|
| 107 |
- fi |
|
| 108 |
- done |
|
| 92 |
+ if [[ $type = (names|all) ]]; then |
|
| 93 |
+ for line in $lines; do |
|
| 94 |
+ names=(${(ps:,:)${${line[${begin[NAMES]},${end[NAMES]}]}%% *}})
|
|
| 95 |
+ # First step: find a common prefix and strip it (swarm node case) |
|
| 96 |
+ (( ${#${(u)names%%/*}} == 1 )) && names=${names#${names[1]%%/*}/}
|
|
| 97 |
+ # Second step: only keep the first name without a / |
|
| 98 |
+ s=${${names:#*/*}[1]}
|
|
| 99 |
+ # If no name, well give up. |
|
| 100 |
+ (( $#s != 0 )) || continue |
|
| 101 |
+ s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
|
|
| 102 |
+ s="$s, ${${${line[${begin[IMAGE]},${end[IMAGE]}]}/:/\\:}%% ##}"
|
|
| 103 |
+ if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then
|
|
| 104 |
+ stopped=($stopped $s) |
|
| 105 |
+ else |
|
| 106 |
+ running=($running $s) |
|
| 107 |
+ fi |
|
| 108 |
+ done |
|
| 109 |
+ fi |
|
| 109 | 110 |
|
| 110 | 111 |
[[ $kind = (running|all) ]] && _describe -t containers-running "running containers" running "$@" && ret=0 |
| 111 | 112 |
[[ $kind = (stopped|all) ]] && _describe -t containers-stopped "stopped containers" stopped "$@" && ret=0 |
| ... | ... |
@@ -114,17 +115,27 @@ __docker_get_containers() {
|
| 114 | 114 |
|
| 115 | 115 |
__docker_stoppedcontainers() {
|
| 116 | 116 |
[[ $PREFIX = -* ]] && return 1 |
| 117 |
- __docker_get_containers stopped "$@" |
|
| 117 |
+ __docker_get_containers stopped all "$@" |
|
| 118 | 118 |
} |
| 119 | 119 |
|
| 120 | 120 |
__docker_runningcontainers() {
|
| 121 | 121 |
[[ $PREFIX = -* ]] && return 1 |
| 122 |
- __docker_get_containers running "$@" |
|
| 122 |
+ __docker_get_containers running all "$@" |
|
| 123 | 123 |
} |
| 124 | 124 |
|
| 125 | 125 |
__docker_containers() {
|
| 126 | 126 |
[[ $PREFIX = -* ]] && return 1 |
| 127 |
- __docker_get_containers all "$@" |
|
| 127 |
+ __docker_get_containers all all "$@" |
|
| 128 |
+} |
|
| 129 |
+ |
|
| 130 |
+__docker_containers_ids() {
|
|
| 131 |
+ [[ $PREFIX = -* ]] && return 1 |
|
| 132 |
+ __docker_get_containers all ids "$@" |
|
| 133 |
+} |
|
| 134 |
+ |
|
| 135 |
+__docker_containers_names() {
|
|
| 136 |
+ [[ $PREFIX = -* ]] && return 1 |
|
| 137 |
+ __docker_get_containers all names "$@" |
|
| 128 | 138 |
} |
| 129 | 139 |
|
| 130 | 140 |
__docker_images() {
|
| ... | ... |
@@ -244,6 +255,43 @@ __docker_complete_detach_keys() {
|
| 244 | 244 |
_describe -t detach_keys-ctrl "'ctrl-' + 'a-z @ [ \\\\ ] ^ _'" ctrl_keys -qS "," && ret=0 |
| 245 | 245 |
} |
| 246 | 246 |
|
| 247 |
+__docker_complete_ps_filters() {
|
|
| 248 |
+ [[ $PREFIX = -* ]] && return 1 |
|
| 249 |
+ integer ret=1 |
|
| 250 |
+ |
|
| 251 |
+ if compset -P '*='; then |
|
| 252 |
+ case "${${words[-1]%=*}#*=}" in
|
|
| 253 |
+ (ancestor) |
|
| 254 |
+ __docker_images && ret=0 |
|
| 255 |
+ ;; |
|
| 256 |
+ (before|since) |
|
| 257 |
+ __docker_containers && ret=0 |
|
| 258 |
+ ;; |
|
| 259 |
+ (id) |
|
| 260 |
+ __docker_containers_ids && ret=0 |
|
| 261 |
+ ;; |
|
| 262 |
+ (name) |
|
| 263 |
+ __docker_containers_names && ret=0 |
|
| 264 |
+ ;; |
|
| 265 |
+ (status) |
|
| 266 |
+ status_opts=('created' 'dead' 'exited' 'paused' 'restarting' 'running')
|
|
| 267 |
+ _describe -t status-filter-opts "Status Filter Options" status_opts && ret=0 |
|
| 268 |
+ ;; |
|
| 269 |
+ (volume) |
|
| 270 |
+ __docker_volumes && ret=0 |
|
| 271 |
+ ;; |
|
| 272 |
+ *) |
|
| 273 |
+ _message 'value' && ret=0 |
|
| 274 |
+ ;; |
|
| 275 |
+ esac |
|
| 276 |
+ else |
|
| 277 |
+ opts=('ancestor' 'before' 'exited' 'id' 'label' 'name' 'since' 'status' 'volume')
|
|
| 278 |
+ _describe -t filter-opts "Filter Options" opts -qS "=" && ret=0 |
|
| 279 |
+ fi |
|
| 280 |
+ |
|
| 281 |
+ return ret |
|
| 282 |
+} |
|
| 283 |
+ |
|
| 247 | 284 |
__docker_networks() {
|
| 248 | 285 |
[[ $PREFIX = -* ]] && return 1 |
| 249 | 286 |
integer ret=1 |
| ... | ... |
@@ -870,7 +918,7 @@ __docker_subcommand() {
|
| 870 | 870 |
$opts_help \ |
| 871 | 871 |
"($help -a --all)"{-a,--all}"[Show all containers]" \
|
| 872 | 872 |
"($help)--before=[Show only container created before...]:containers:__docker_containers" \ |
| 873 |
- "($help)*"{-f=,--filter=}"[Filter values]:filter: " \
|
|
| 873 |
+ "($help)*"{-f=,--filter=}"[Filter values]:filter:->filter-options" \
|
|
| 874 | 874 |
"($help)--format[Pretty-print containers using a Go template]:format: " \ |
| 875 | 875 |
"($help -l --latest)"{-l,--latest}"[Show only the latest created container]" \
|
| 876 | 876 |
"($help)-n[Show n last created containers, include non-running one]:n:(1 5 10 25 50)" \ |
| ... | ... |
@@ -878,6 +926,12 @@ __docker_subcommand() {
|
| 878 | 878 |
"($help -q --quiet)"{-q,--quiet}"[Only show numeric IDs]" \
|
| 879 | 879 |
"($help -s --size)"{-s,--size}"[Display total file sizes]" \
|
| 880 | 880 |
"($help)--since=[Show only containers created since...]:containers:__docker_containers" && ret=0 |
| 881 |
+ |
|
| 882 |
+ case $state in |
|
| 883 |
+ (filter-options) |
|
| 884 |
+ __docker_complete_ps_filters && ret=0 |
|
| 885 |
+ ;; |
|
| 886 |
+ esac |
|
| 881 | 887 |
;; |
| 882 | 888 |
(pull) |
| 883 | 889 |
_arguments $(__docker_arguments) \ |