Browse code

Add powershell completion support

Initial version of powershell tab completion. It completes
commands and container names.

Signed-off-by: Sam Neirinck <sam@samneirinck.com>

Sam Neirinck authored on 2016/02/02 01:12:15
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,179 @@
0
+# Powershell completion for docker
1
+
2
+### Prerequisite
3
+# Docker.exe needs to be in your PATH.
4
+# If the command is not found, you will need to add a docker alias or add the docker installation folder (e.g. `%ProgramFiles%\Docker Toolbox`) to your PATH environment variable.
5
+
6
+### Installation (Latest stable)
7
+# Windows 10 / Windows Server 2016: 
8
+# 1. Open a powershell prompt
9
+# 2. Run `Install-Module -Scope CurrentUser posh-docker`
10
+#
11
+# Earlier Windows versions:
12
+# 1. Install [PackageManagement PowerShell Modules Preview](https://www.microsoft.com/en-us/download/details.aspx?id=49186)
13
+# 2. Open a powershell prompt
14
+# 3. Run `Install-Module -Scope CurrentUser posh-docker`
15
+
16
+### Installation (From source)
17
+# Copy this file to the %userprofile%\Documents\WindowsPowerShell\Modules\posh-docker directory (create directories as needed)
18
+
19
+### Usage
20
+# After installation, execute the following line to enable autocompletion for the current powershell session:
21
+#
22
+# Import-Module posh-docker
23
+#
24
+# To make it persistent, add the above line to your profile. For example, run `notepad $PROFILE` and insert the line above.
25
+
26
+$global:DockerCompletion = @{}
27
+
28
+$script:flagRegex = "^  (-[^, =]+),? ?(--[^= ]+)?"
29
+
30
+function script:Get-Containers($filter)
31
+{
32
+    if ($filter -eq $null)
33
+    {
34
+       docker ps -a --no-trunc --format "{{.Names}}"
35
+    } else {
36
+       docker ps -a --no-trunc --format "{{.Names}}" --filter $filter
37
+    }
38
+}
39
+
40
+function script:Get-AutoCompleteResult
41
+{
42
+    param([Parameter(ValueFromPipeline=$true)] $value)
43
+    
44
+    Process
45
+    {
46
+        New-Object System.Management.Automation.CompletionResult $value
47
+    }
48
+}
49
+
50
+filter script:MatchingCommand($commandName)
51
+{
52
+    if ($_.StartsWith($commandName))
53
+    {
54
+        $_
55
+    }
56
+}
57
+
58
+$completion_Docker = {
59
+    param($commandName, $commandAst, $cursorPosition)
60
+
61
+    $command = $null
62
+    $commandParameters = @{}
63
+    $state = "Unknown"
64
+    $wordToComplete = $commandAst.CommandElements | Where-Object { $_.ToString() -eq $commandName } | Foreach-Object { $commandAst.CommandElements.IndexOf($_) }
65
+
66
+    for ($i=1; $i -lt $commandAst.CommandElements.Count; $i++)
67
+    {
68
+        $p = $commandAst.CommandElements[$i].ToString()
69
+
70
+        if ($p.StartsWith("-"))
71
+        {
72
+            if ($state -eq "Unknown" -or $state -eq "Options")
73
+            {
74
+                $commandParameters[$i] = "Option"
75
+                $state = "Options"
76
+            }
77
+            else
78
+            {
79
+                $commandParameters[$i] = "CommandOption"
80
+                $state = "CommandOptions"
81
+            }
82
+        } 
83
+        else 
84
+        {
85
+            if ($state -ne "CommandOptions")
86
+            {
87
+                $commandParameters[$i] = "Command"
88
+                $command = $p
89
+                $state = "CommandOptions"
90
+            } 
91
+            else 
92
+            {
93
+                $commandParameters[$i] = "CommandOther"
94
+            }
95
+        }
96
+    }
97
+
98
+    if ($global:DockerCompletion.Count -eq 0)
99
+    {
100
+        $global:DockerCompletion["commands"] = @{}
101
+        $global:DockerCompletion["options"] = @()
102
+        
103
+        docker --help | ForEach-Object {
104
+            Write-Output $_
105
+            if ($_ -match "^    (\w+)\s+(.+)")
106
+            {
107
+                $global:DockerCompletion["commands"][$Matches[1]] = @{}
108
+                
109
+                $currentCommand = $global:DockerCompletion["commands"][$Matches[1]]
110
+                $currentCommand["options"] = @()
111
+            }
112
+            elseif ($_ -match $flagRegex)
113
+            {
114
+                $global:DockerCompletion["options"] += $Matches[1]
115
+                if ($Matches[2] -ne $null)
116
+                {
117
+                    $global:DockerCompletion["options"] += $Matches[2]
118
+                 }
119
+            }
120
+        }
121
+
122
+    }
123
+    
124
+    if ($wordToComplete -eq $null)
125
+    {
126
+        $commandToComplete = "Command"
127
+        if ($commandParameters.Count -gt 0)
128
+        {
129
+            if ($commandParameters[$commandParameters.Count] -eq "Command")
130
+            {
131
+                $commandToComplete = "CommandOther"
132
+            }
133
+        } 
134
+    } else {
135
+        $commandToComplete = $commandParameters[$wordToComplete]
136
+    }
137
+
138
+    switch ($commandToComplete)
139
+    {
140
+        "Command" { $global:DockerCompletion["commands"].Keys | MatchingCommand -Command $commandName | Sort-Object | Get-AutoCompleteResult }
141
+        "Option" { $global:DockerCompletion["options"] | MatchingCommand -Command $commandName | Sort-Object | Get-AutoCompleteResult }
142
+        "CommandOption" { 
143
+            $options = $global:DockerCompletion["commands"][$command]["options"]
144
+            if ($options.Count -eq 0)
145
+            {
146
+                docker $command --help | % {
147
+                if ($_ -match $flagRegex)
148
+                    {
149
+                        $options += $Matches[1]
150
+                        if ($Matches[2] -ne $null)
151
+                        {
152
+                            $options += $Matches[2]
153
+                        }
154
+                    }
155
+                }
156
+            }
157
+
158
+            $global:DockerCompletion["commands"][$command]["options"] = $options
159
+            $options | MatchingCommand -Command $commandName | Sort-Object | Get-AutoCompleteResult
160
+        }
161
+        "CommandOther" {
162
+            $filter = $null 
163
+            switch ($command)
164
+            {
165
+                "start" { $filter = "status=exited" }
166
+                "stop" { $filter = "status=running" }
167
+            }
168
+            Get-Containers $filter | MatchingCommand -Command $commandName | Sort-Object | Get-AutoCompleteResult
169
+        }
170
+        default { $global:DockerCompletion["commands"].Keys | MatchingCommand -Command $commandName }
171
+    }
172
+}
173
+
174
+# Register the TabExpension2 function
175
+if (-not $global:options) { $global:options = @{CustomArgumentCompleters = @{};NativeArgumentCompleters = @{}}}
176
+$global:options['NativeArgumentCompleters']['docker'] = $Completion_Docker
177
+
178
+$function:tabexpansion2 = $function:tabexpansion2 -replace 'End\r\n{','End { if ($null -ne $options) { $options += $global:options} else {$options = $global:options}'
0 179
\ No newline at end of file