Browse code

Merge pull request #21546 from sdurrheimer/zsh-completion-ps-filters

Add zsh completion for 'docker ps --filter' values

Vincent Demeester authored on 2016/03/27 17:22:50
Showing 1 changed files
... ...
@@ -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) \