1
+ if (Get-Command pnpm - ErrorAction SilentlyContinue) {
2
+ # ##-begin-pnpm-completion-###
3
+
4
+ Register-ArgumentCompleter - CommandName ' pnpm' - ScriptBlock {
5
+ param (
6
+ $WordToComplete ,
7
+ $CommandAst ,
8
+ $CursorPosition
9
+ )
10
+
11
+ function __pnpm_debug {
12
+ if ($env: BASH_COMP_DEBUG_FILE ) {
13
+ " $args " | Out-File - Append - FilePath " $env: BASH_COMP_DEBUG_FILE "
14
+ }
15
+ }
16
+
17
+ filter __pnpm_escapeStringWithSpecialChars {
18
+ $_ -replace ' \s|#|@|\$|;|,|'' |\{|\}|\(|\)|"|`|\||<|>|&' , ' `$&'
19
+ }
20
+
21
+ # Get the current command line and convert into a string
22
+ $Command = $CommandAst.CommandElements
23
+ $Command = " $Command "
24
+
25
+ __pnpm_debug " "
26
+ __pnpm_debug " ========= starting completion logic =========="
27
+ __pnpm_debug " WordToComplete: $WordToComplete Command: $Command CursorPosition: $CursorPosition "
28
+
29
+ # The user could have moved the cursor backwards on the command-line.
30
+ # We need to trigger completion from the $CursorPosition location, so we need
31
+ # to truncate the command-line ($Command) up to the $CursorPosition location.
32
+ # Make sure the $Command is longer then the $CursorPosition before we truncate.
33
+ # This happens because the $Command does not include the last space.
34
+ if ($Command.Length -gt $CursorPosition ) {
35
+ $Command = $Command.Substring (0 , $CursorPosition )
36
+ }
37
+ __pnpm_debug " Truncated command: $Command "
38
+
39
+ # Prepare the command to request completions for the program.
40
+ # Split the command at the first space to separate the program and arguments.
41
+ $Program , $Arguments = $Command.Split (" " , 2 )
42
+ $RequestComp = " $Program completion-server"
43
+ __pnpm_debug " RequestComp: $RequestComp "
44
+
45
+ # we cannot use $WordToComplete because it
46
+ # has the wrong values if the cursor was moved
47
+ # so use the last argument
48
+ if ($WordToComplete -ne " " ) {
49
+ $WordToComplete = $Arguments.Split (" " )[-1 ]
50
+ }
51
+ __pnpm_debug " New WordToComplete: $WordToComplete "
52
+
53
+
54
+ # Check for flag with equal sign
55
+ $IsEqualFlag = ($WordToComplete -Like " --*=*" )
56
+ if ( $IsEqualFlag ) {
57
+ __pnpm_debug " Completing equal sign flag"
58
+ # Remove the flag part
59
+ $Flag , $WordToComplete = $WordToComplete.Split (" =" , 2 )
60
+ }
61
+
62
+ if ( $WordToComplete -eq " " -And ( -Not $IsEqualFlag )) {
63
+ # If the last parameter is complete (there is a space following it)
64
+ # We add an extra empty parameter so we can indicate this to the go method.
65
+ __pnpm_debug " Adding extra empty parameter"
66
+ # We need to use `"`" to pass an empty argument a "" or '' does not work!!!
67
+ $Command = " $Command " + ' `"`"'
68
+ }
69
+
70
+ __pnpm_debug " Calling $RequestComp "
71
+
72
+ $oldenv = ($env: SHELL , $env: COMP_CWORD , $env: COMP_LINE , $env: COMP_POINT )
73
+ $env: SHELL = " pwsh"
74
+ $env: COMP_CWORD = $Command.Split (" " ).Count - 1
75
+ $env: COMP_POINT = $CursorPosition
76
+ $env: COMP_LINE = $Command
77
+
78
+ try {
79
+ # call the command store the output in $out and redirect stderr and stdout to null
80
+ # $Out is an array contains each line per element
81
+ Invoke-Expression - OutVariable out " $RequestComp " 2>&1 | Out-Null
82
+ }
83
+ finally {
84
+ ($env: SHELL , $env: COMP_CWORD , $env: COMP_LINE , $env: COMP_POINT ) = $oldenv
85
+ }
86
+
87
+ __pnpm_debug " The completions are: $Out "
88
+
89
+ $Longest = 0
90
+ $Values = $Out | ForEach-Object {
91
+ # Split the output in name and description
92
+ $Name , $Description = $_.Split (" `t " , 2 )
93
+ __pnpm_debug " Name: $Name Description: $Description "
94
+
95
+ # Look for the longest completion so that we can format things nicely
96
+ if ($Longest -lt $Name.Length ) {
97
+ $Longest = $Name.Length
98
+ }
99
+
100
+ # Set the description to a one space string if there is none set.
101
+ # This is needed because the CompletionResult does not accept an empty string as argument
102
+ if (-Not $Description ) {
103
+ $Description = " "
104
+ }
105
+ @ {Name = " $Name " ; Description = " $Description " }
106
+ }
107
+
108
+
109
+ $Space = " "
110
+ $Values = $Values | Where-Object {
111
+ # filter the result
112
+ if (-not $WordToComplete.StartsWith (" -" ) -and $_.Name.StartsWith (" -" )) {
113
+ # skip flag completions unless a dash is present
114
+ return
115
+ }
116
+ else {
117
+ $_.Name -like " $WordToComplete *"
118
+ }
119
+
120
+ # Join the flag back if we have an equal sign flag
121
+ if ( $IsEqualFlag ) {
122
+ __pnpm_debug " Join the equal sign flag back to the completion value"
123
+ $_.Name = $Flag + " =" + $_.Name
124
+ }
125
+ }
126
+
127
+ # Get the current mode
128
+ $Mode = (Get-PSReadLineKeyHandler | Where-Object { $_.Key -eq " Tab" }).Function
129
+ __pnpm_debug " Mode: $Mode "
130
+
131
+ $Values | ForEach-Object {
132
+
133
+ # store temporary because switch will overwrite $_
134
+ $comp = $_
135
+
136
+ # PowerShell supports three different completion modes
137
+ # - TabCompleteNext (default windows style - on each key press the next option is displayed)
138
+ # - Complete (works like bash)
139
+ # - MenuComplete (works like zsh)
140
+ # You set the mode with Set-PSReadLineKeyHandler -Key Tab -Function <mode>
141
+
142
+ # CompletionResult Arguments:
143
+ # 1) CompletionText text to be used as the auto completion result
144
+ # 2) ListItemText text to be displayed in the suggestion list
145
+ # 3) ResultType type of completion result
146
+ # 4) ToolTip text for the tooltip with details about the object
147
+
148
+ switch ($Mode ) {
149
+
150
+ # bash like
151
+ " Complete" {
152
+
153
+ if ($Values.Length -eq 1 ) {
154
+ __pnpm_debug " Only one completion left"
155
+
156
+ # insert space after value
157
+ [System.Management.Automation.CompletionResult ]::new($ ($comp.Name | __pnpm_escapeStringWithSpecialChars) + $Space , " $ ( $comp.Name ) " , ' ParameterValue' , " $ ( $comp.Description ) " )
158
+
159
+ }
160
+ else {
161
+ # Add the proper number of spaces to align the descriptions
162
+ while ($comp.Name.Length -lt $Longest ) {
163
+ $comp.Name = $comp.Name + " "
164
+ }
165
+
166
+ # Check for empty description and only add parentheses if needed
167
+ if ($ ($comp.Description ) -eq " " ) {
168
+ $Description = " "
169
+ }
170
+ else {
171
+ $Description = " ($ ( $comp.Description ) )"
172
+ }
173
+
174
+ [System.Management.Automation.CompletionResult ]::new(" $ ( $comp.Name ) $Description " , " $ ( $comp.Name ) $Description " , ' ParameterValue' , " $ ( $comp.Description ) " )
175
+ }
176
+ }
177
+
178
+ # zsh like
179
+ " MenuComplete" {
180
+ # insert space after value
181
+ # MenuComplete will automatically show the ToolTip of
182
+ # the highlighted value at the bottom of the suggestions.
183
+ [System.Management.Automation.CompletionResult ]::new($ ($comp.Name | __pnpm_escapeStringWithSpecialChars) + $Space , " $ ( $comp.Name ) " , ' ParameterValue' , " $ ( $comp.Description ) " )
184
+ }
185
+
186
+ # TabCompleteNext and in case we get something unknown
187
+ Default {
188
+ # Like MenuComplete but we don't want to add a space here because
189
+ # the user need to press space anyway to get the completion.
190
+ # Description will not be shown because that's not possible with TabCompleteNext
191
+ [System.Management.Automation.CompletionResult ]::new($ ($comp.Name | __pnpm_escapeStringWithSpecialChars), " $ ( $comp.Name ) " , ' ParameterValue' , " $ ( $comp.Description ) " )
192
+ }
193
+ }
194
+
195
+ }
196
+ }
197
+
198
+ # ##-end-pnpm-completion-###
199
+ }
0 commit comments