Browse code

zsh: update zsh completion for docker command

zsh completion is updated with the content of
felixr/docker-zsh-completion.

The major change since the last merge is the removal of use of
sed/awk. This should help a lot OSX users who previously had to install
gawk and gsed.

Docker-DCO-1.1-Signed-off-by: Vincent Bernat <vincent@bernat.im> (github: vincentbernat)

Vincent Bernat authored on 2014/09/04 05:30:11
Showing 1 changed files
... ...
@@ -5,7 +5,7 @@
5 5
 # version:  0.3.0
6 6
 # github:   https://github.com/felixr/docker-zsh-completion
7 7
 #
8
-# contributers:
8
+# contributors:
9 9
 #   - Felix Riedel
10 10
 #   - Vincent Bernat
11 11
 #
... ...
@@ -37,65 +37,86 @@
37 37
 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 38
 #
39 39
 
40
-__parse_docker_list() {
41
-        awk '
42
-NR == 1 {
43
-    idx=1;i=0;f[i]=0
44
-    header=$0
45
-    while ( match(header, /  ([A-Z]+|[A-Z]+ [A-Z]+)/) ) {
46
-        idx += RSTART+1
47
-        f[++i]=idx
48
-        header = substr($0,idx)
49
-    }
50
-    f[++i]=999
51
-}
40
+__docker_get_containers() {
41
+    local kind expl
42
+    declare -a running stopped lines args
52 43
 
53
-NR > 1 '"$1"' {
54
-    for(j=0;j<i;j++) {
55
-        x[j] = substr($0, f[j], f[j+1]-f[j]-1)
56
-        gsub(/[ ]+$/, "", x[j])
57
-    }
58
-    printf("%s:%7s, %s\n", x[0], x[3], x[1])
59
-    if (x[6] != "") {
60
-       split(x[6], names, /,/)
61
-       for (name in names) printf("%s:%7s, %s\n", names[name], x[3], x[1])
44
+    kind=$1
45
+    shift
46
+    [[ $kind = (stopped|all) ]] && args=($args -a)
47
+
48
+    lines=(${(f)"$(_call_program commands docker ps ${args})"})
49
+
50
+    # Parse header line to find columns
51
+    local i=1 j=1 k header=${lines[1]}
52
+    declare -A begin end
53
+    while (( $j < ${#header} - 1 )) {
54
+        i=$(( $j + ${${header[$j,-1]}[(i)[^ ]]} - 1))
55
+        j=$(( $i + ${${header[$i,-1]}[(i)  ]} - 1))
56
+        k=$(( $j + ${${header[$j,-1]}[(i)[^ ]]} - 2))
57
+        begin[${header[$i,$(($j-1))]}]=$i
58
+        end[${header[$i,$(($j-1))]}]=$k
62 59
     }
63
-}
64
-'| sed -e 's/ \([hdwm]\)\(inutes\|ays\|ours\|eeks\)/\1/'
60
+    lines=(${lines[2,-1]})
61
+
62
+    # Container ID
63
+    local line
64
+    local s
65
+    for line in $lines; do
66
+        s="${line[${begin[CONTAINER ID]},${end[CONTAINER ID]}]%% ##}"
67
+        s="$s:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
68
+        s="$s, ${${${line[$begin[IMAGE],$end[IMAGE]]}/:/\\:}%% ##}"
69
+        if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then
70
+            stopped=($stopped $s)
71
+        else
72
+            running=($running $s)
73
+        fi
74
+    done
75
+
76
+    # Names
77
+    local name
78
+    local -a names
79
+    for line in $lines; do
80
+        names=(${(ps:,:)${${line[${begin[NAMES]},-1]}%% *}})
81
+        for name in $names; do
82
+            s="${name}:${(l:15:: :::)${${line[${begin[CREATED]},${end[CREATED]}]/ ago/}%% ##}}"
83
+            s="$s, ${${${line[$begin[IMAGE],$end[IMAGE]]}/:/\\:}%% ##}"
84
+            if [[ ${line[${begin[STATUS]},${end[STATUS]}]} = Exit* ]]; then
85
+                stopped=($stopped $s)
86
+            else
87
+                running=($running $s)
88
+            fi
89
+        done
90
+    done
91
+
92
+    [[ $kind = (running|all) ]] && _describe -t containers-running "running containers" running
93
+    [[ $kind = (stopped|all) ]] && _describe -t containers-stopped "stopped containers" stopped
65 94
 }
66 95
 
67 96
 __docker_stoppedcontainers() {
68
-    local expl
69
-    declare -a stoppedcontainers
70
-    stoppedcontainers=(${(f)"$(_call_program commands docker ps -a |  __parse_docker_list '&& / Exit/')"})
71
-    _describe -t containers-stopped "Stopped Containers" stoppedcontainers "$@"
97
+    __docker_get_containers stopped "$@"
72 98
 }
73 99
 
74 100
 __docker_runningcontainers() {
75
-    local expl
76
-    declare -a containers
77
-
78
-    containers=(${(f)"$(_call_program commands docker ps | __parse_docker_list)"})
79
-    _describe -t containers-active "Running Containers" containers "$@"
101
+    __docker_get_containers running "$@"
80 102
 }
81 103
 
82 104
 __docker_containers () {
83
-    __docker_stoppedcontainers "$@"
84
-    __docker_runningcontainers "$@"
105
+    __docker_get_containers all "$@"
85 106
 }
86 107
 
87 108
 __docker_images () {
88 109
     local expl
89 110
     declare -a images
90
-    images=(${(f)"$(_call_program commands docker images | awk '(NR > 1 && $1 != "<none>"){printf("%s", $1);if ($2 != "<none>") printf("\\:%s", $2); printf("\n")}')"})
91
-    images=($images ${(f)"$(_call_program commands docker images | awk '(NR > 1){printf("%s:%-15s in %s\n", $3,$2,$1)}')"})
92
-    _describe -t docker-images "Images" images
111
+    images=(${${${${(f)"$(_call_program commands docker images)"}[2,-1]}/ ##/\\:}%% *})
112
+    images=(${${images%\\:<none>}#<none>} ${${${(f)"$(_call_program commands docker images)"}[2,-1]}/(#b)([^ ]##) ##([^ ]##) ##([^ ]##)*/${match[3]}:${(r:15:: :::)match[2]} in ${match[1]}})
113
+    _describe -t docker-images "images" images
93 114
 }
94 115
 
95 116
 __docker_tags() {
96 117
     local expl
97 118
     declare -a tags
98
-    tags=(${(f)"$(_call_program commands docker images | awk '(NR>1){print $2}'| sort | uniq)"})
119
+    tags=(${${${${${(f)"$(_call_program commands docker images)"}#* }## #}%% *}[2,-1]})
99 120
     _describe -t docker-tags "tags" tags
100 121
 }
101 122
 
... ...
@@ -124,16 +145,15 @@ __docker_search() {
124 124
     if ( [[ ${(P)+cachename} -eq 0 ]] || _cache_invalid ${cachename#_} ) \
125 125
         && ! _retrieve_cache ${cachename#_}; then
126 126
         _message "Searching for ${searchterm}..."
127
-        result=(${(f)"$(_call_program commands docker search ${searchterm} | awk '(NR>2){print $1}')"})
127
+        result=(${${${(f)"$(_call_program commands docker search ${searchterm})"}%% *}[2,-1]})
128 128
         _store_cache ${cachename#_} result
129 129
     fi
130
-    _wanted dockersearch expl 'Available images' compadd -a result
130
+    _wanted dockersearch expl 'available images' compadd -a result
131 131
 }
132 132
 
133 133
 __docker_caching_policy()
134 134
 {
135
-  # oldp=( "$1"(Nmh+24) )     # 24 hour
136
-  oldp=( "$1"(Nmh+1) )     # 24 hour
135
+  oldp=( "$1"(Nmh+1) )     # 1 hour
137 136
   (( $#oldp ))
138 137
 }
139 138
 
... ...
@@ -141,8 +161,8 @@ __docker_caching_policy()
141 141
 __docker_repositories () {
142 142
     local expl
143 143
     declare -a repos
144
-    repos=(${(f)"$(_call_program commands docker images | sed -e '1d' -e 's/[ ].*//' | sort | uniq)"})
145
-    _describe -t docker-repos "Repositories" repos "$@"
144
+    repos=(${${${(f)"$(_call_program commands docker images)"}%% *}[2,-1]})
145
+    _describe -t docker-repos "repositories" repos "$@"
146 146
 }
147 147
 
148 148
 __docker_commands () {
... ...
@@ -157,8 +177,7 @@ __docker_commands () {
157 157
     if ( [[ ${+_docker_subcommands} -eq 0 ]] || _cache_invalid docker_subcommands) \
158 158
         && ! _retrieve_cache docker_subcommands;
159 159
     then
160
-        _docker_subcommands=(${${(f)"$(_call_program commands
161
-        docker 2>&1 | sed -e '1,6d' -e '/^[ ]*$/d' -e 's/[ ]*\([^ ]\+\)\s*\([^ ].*\)/\1:\2/' )"}})
160
+        _docker_subcommands=(${${${${(f)"$(_call_program commands docker 2>&1)"}[5,-1]}## #}/ ##/:})
162 161
         _docker_subcommands=($_docker_subcommands 'help:Show help for a command')
163 162
         _store_cache docker_subcommands _docker_subcommands
164 163
     fi
... ...
@@ -179,13 +198,13 @@ __docker_subcommand () {
179 179
                 '--no-cache[Do not use cache when building the image]' \
180 180
                 '-q[Suppress verbose build output]' \
181 181
                 '--rm[Remove intermediate containers after a successful build]' \
182
-                '-t=-:repository:__docker_repositories_with_tags' \
182
+                '-t:repository:__docker_repositories_with_tags' \
183 183
                 ':path or URL:_directories'
184 184
             ;;
185 185
         (commit)
186 186
             _arguments \
187 187
                 '--author=-[Author]:author: ' \
188
-                '-m=-[Commit message]:message: ' \
188
+                '-m[Commit message]:message: ' \
189 189
                 '--run=-[Configuration automatically applied when the image is run]:configuration: ' \
190 190
                 ':container:__docker_containers' \
191 191
                 ':repository:__docker_repositories_with_tags'
... ...
@@ -251,9 +270,9 @@ __docker_subcommand () {
251 251
             ;;
252 252
         (login)
253 253
             _arguments \
254
-                '-e=-[Email]:email: ' \
255
-                '-p=-[Password]:password: ' \
256
-                '-u=-[Username]:username: ' \
254
+                '-e[Email]:email: ' \
255
+                '-p[Password]:password: ' \
256
+                '-u[Username]:username: ' \
257 257
                 ':server: '
258 258
             ;;
259 259
         (logs)
... ...
@@ -283,7 +302,7 @@ __docker_subcommand () {
283 283
                 '*:images:__docker_images'
284 284
             ;;
285 285
         (restart|stop)
286
-            _arguments '-t=-[Number of seconds to try to stop for before killing the container]:seconds to before killing:(1 5 10 30 60)' \
286
+            _arguments '-t[Number of seconds to try to stop for before killing the container]:seconds to before killing:(1 5 10 30 60)' \
287 287
                 '*:containers:__docker_runningcontainers'
288 288
             ;;
289 289
         (top)
... ...
@@ -302,7 +321,7 @@ __docker_subcommand () {
302 302
                 '-a[Show all containers]' \
303 303
                 '--before=-[Show only container created before...]:containers:__docker_containers' \
304 304
                 '-l[Show only the latest created container]' \
305
-                '-n=-[Show n last created containers, include non-running one]:n:(1 5 10 25 50)' \
305
+                '-n[Show n last created containers, include non-running one]:n:(1 5 10 25 50)' \
306 306
                 '--no-trunc[Do not truncate output]' \
307 307
                 '-q[Only show numeric IDs]' \
308 308
                 '-s[Display sizes]' \
... ...
@@ -318,28 +337,28 @@ __docker_subcommand () {
318 318
             _arguments \
319 319
                 '-P[Publish all exposed ports to the host]' \
320 320
                 '-a[Attach to stdin, stdout or stderr]' \
321
-                '-c=-[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)' \
321
+                '-c[CPU shares (relative weight)]:CPU shares:(0 10 100 200 500 800 1000)' \
322 322
                 '--cidfile=-[Write the container ID to the file]:CID file:_files' \
323 323
                 '-d[Detached mode: leave the container running in the background]' \
324 324
                 '*--dns=-[Set custom dns servers]:dns server: ' \
325
-                '*-e=-[Set environment variables]:environment variable: ' \
325
+                '*-e[Set environment variables]:environment variable: ' \
326 326
                 '--entrypoint=-[Overwrite the default entrypoint of the image]:entry point: ' \
327 327
                 '*--expose=-[Expose a port from the container without publishing it]: ' \
328
-                '-h=-[Container host name]:hostname:_hosts' \
328
+                '-h[Container host name]:hostname:_hosts' \
329 329
                 '-i[Keep stdin open even if not attached]' \
330 330
                 '--link=-[Add link to another container]:link:->link' \
331 331
                 '--lxc-conf=-[Add custom lxc options]:lxc options: ' \
332
-                '-m=-[Memory limit (in bytes)]:limit: ' \
332
+                '-m[Memory limit (in bytes)]:limit: ' \
333 333
                 '--name=-[Container name]:name: ' \
334
-                '*-p=-[Expose a container'"'"'s port to the host]:port:_ports' \
334
+                '*-p[Expose a container'"'"'s port to the host]:port:_ports' \
335 335
                 '--privileged[Give extended privileges to this container]' \
336 336
                 '--rm[Remove intermediate containers when it exits]' \
337 337
                 '--sig-proxy[Proxify all received signal]' \
338 338
                 '-t[Allocate a pseudo-tty]' \
339
-                '-u=-[Username or UID]:user:_users' \
340
-                '*-v=-[Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)]:volume: '\
339
+                '-u[Username or UID]:user:_users' \
340
+                '*-v[Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)]:volume: '\
341 341
                 '--volumes-from=-[Mount volumes from the specified container]:volume: ' \
342
-                '-w=-[Working directory inside the container]:directory:_directories' \
342
+                '-w[Working directory inside the container]:directory:_directories' \
343 343
                 '(-):images:__docker_images' \
344 344
                 '(-):command: _command_names -e' \
345 345
                 '*::arguments: _normal'
... ...
@@ -359,7 +378,7 @@ __docker_subcommand () {
359 359
             _arguments ':name:__docker_search'
360 360
             ;;
361 361
         (push)
362
-            _arguments ':repository:__docker_repositories_with_tags'
362
+            _arguments ':images:__docker_images'
363 363
             ;;
364 364
         (save)
365 365
             _arguments \
... ...
@@ -389,7 +408,7 @@ _docker () {
389 389
     typeset -A opt_args
390 390
 
391 391
     _arguments -C \
392
-      '-H=-[tcp://host:port to bind/connect to]:socket: ' \
392
+      '-H[tcp://host:port to bind/connect to]:socket: ' \
393 393
          '(-): :->command' \
394 394
          '(-)*:: :->option-or-argument'
395 395
 
... ...
@@ -408,3 +427,11 @@ _docker () {
408 408
 }
409 409
 
410 410
 _docker "$@"
411
+
412
+# Local Variables:
413
+# mode: Shell-Script
414
+# sh-indentation: 4
415
+# indent-tabs-mode: nil
416
+# sh-basic-offset: 4
417
+# End:
418
+# vim: ft=zsh sw=4 ts=4 et