Skip to content

Commit 002492b

Browse files
🩹 [Patch]: Prevent ArgumentCompleters from falling back to the default file path completion (#515)
This PR addresses an issue where PowerShell argument completers would fall back to file path completion when no valid argument matches were found, leading to irrelevant file and folder suggestions. ## Problem When using argument completion with GitHub PowerShell module commands, if no matches were found for the typed input, PowerShell would default to showing file and folder completions from the current directory. This created a confusing user experience where typing something like: ```powershell Get-GitHubLicense -Name invalidlicense<TAB> ``` Would show local files and folders instead of no completions, suggesting invalid options to the user. ## Solution Updated all 34 argument completers across 14 files to explicitly return `$null` when no matches are found. The fix follows this pattern: **Before:** ```powershell Get-GitHubLicense @params | Where-Object { $_.Name -like $pattern } | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Name) } ``` **After:** ```powershell $filteredOptions = Get-GitHubLicense @params | Where-Object { $_.Name -like $pattern } if (-not $filteredOptions) { return $null } $filteredOptions | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Name) } ``` ## Result - ✅ When valid matches exist: Shows appropriate completions as before - ✅ When no matches exist: No completions shown (cursor stays in place) - ❌ Previously: Would show irrelevant file/folder completions when no matches found This provides a cleaner, more intuitive completion experience that doesn't suggest invalid options to users. ## Files Modified All completer files throughout the module structure: - Core completers in `/src/completers.ps1` - Function-specific completers in `/src/functions/public/*/completers.ps1` Fixes #514. <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: MariusStorhaug <17722253+MariusStorhaug@users.noreply.github.com>
1 parent 0294114 commit 002492b

File tree

14 files changed

+170
-34
lines changed

14 files changed

+170
-34
lines changed

src/completers.ps1

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
Verbose = $false
88
Debug = $false
99
}
10-
Get-GitHubAppInstallation @params | Where-Object { $_.Type -eq 'User' -and $_.Target.Name -like $pattern } | ForEach-Object {
10+
$filteredOptions = Get-GitHubAppInstallation @params | Where-Object { $_.Type -eq 'User' -and $_.Target.Name -like $pattern }
11+
if (-not $filteredOptions) {
12+
return $null
13+
}
14+
$filteredOptions | ForEach-Object {
1115
[System.Management.Automation.CompletionResult]::new($_.Target.Name, $_.Target.Name, 'ParameterValue', $_.Target.Name)
1216
}
1317
}
@@ -20,7 +24,11 @@ Register-ArgumentCompleter -CommandName Connect-GitHubApp -ParameterName Organiz
2024
Verbose = $false
2125
Debug = $false
2226
}
23-
Get-GitHubAppInstallation @params | Where-Object { $_.Type -eq 'Organization' -and $_.Target.Name -like $pattern } | ForEach-Object {
27+
$filteredOptions = Get-GitHubAppInstallation @params | Where-Object { $_.Type -eq 'Organization' -and $_.Target.Name -like $pattern }
28+
if (-not $filteredOptions) {
29+
return $null
30+
}
31+
$filteredOptions | ForEach-Object {
2432
[System.Management.Automation.CompletionResult]::new($_.Target.Name, $_.Target.Name, 'ParameterValue', $_.Target.Name)
2533
}
2634
}
@@ -33,7 +41,11 @@ Register-ArgumentCompleter -CommandName Connect-GitHubApp -ParameterName Enterpr
3341
Verbose = $false
3442
Debug = $false
3543
}
36-
Get-GitHubAppInstallation @params | Where-Object { $_.Type -eq 'Enterprise' -and $_.Target.Name -like $pattern } | ForEach-Object {
44+
$filteredOptions = Get-GitHubAppInstallation @params | Where-Object { $_.Type -eq 'Enterprise' -and $_.Target.Name -like $pattern }
45+
if (-not $filteredOptions) {
46+
return $null
47+
}
48+
$filteredOptions | ForEach-Object {
3749
[System.Management.Automation.CompletionResult]::new($_.Target.Name, $_.Target.Name, 'ParameterValue', $_.Target.Name)
3850
}
3951
}

src/functions/public/Auth/Context/completers.ps1

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414

1515
$contexts += Get-GitHubContext -ListAvailable -Verbose:$false -Debug:$false
1616
$contexts = $contexts | Sort-Object -Property Name
17-
$contexts | Where-Object { $_.Name -like $pattern } | ForEach-Object {
17+
$filteredOptions = $contexts | Where-Object { $_.Name -like $pattern }
18+
if (-not $filteredOptions) {
19+
return $null
20+
}
21+
$filteredOptions | ForEach-Object {
1822
[System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Name)
1923
}
2024
}

src/functions/public/Config/completers.ps1

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
33
$null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters
44
$pattern = switch (Get-GitHubConfig -Name CompletionMode) { 'Contains' { "*$wordToComplete*" } default { "$wordToComplete*" } }
5-
([GitHubConfig]).GetProperties().Name | Where-Object { $_ -like $pattern } | ForEach-Object {
5+
$filteredOptions = ([GitHubConfig]).GetProperties().Name | Where-Object { $_ -like $pattern }
6+
if (-not $filteredOptions) {
7+
return $null
8+
}
9+
$filteredOptions | ForEach-Object {
610
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_ )
711
}
812
}
@@ -13,17 +17,29 @@ Register-ArgumentCompleter -CommandName Set-GitHubConfig -ParameterName Value -S
1317
$pattern = switch (Get-GitHubConfig -Name CompletionMode) { 'Contains' { "*$wordToComplete*" } default { "$wordToComplete*" } }
1418
switch ($fakeBoundParameters.Name) {
1519
'CompletionMode' {
16-
@('StartsWith', 'Contains') | Where-Object { $_ -like $pattern } | ForEach-Object {
20+
$filteredOptions = @('StartsWith', 'Contains') | Where-Object { $_ -like $pattern }
21+
if (-not $filteredOptions) {
22+
return $null
23+
}
24+
$filteredOptions | ForEach-Object {
1725
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
1826
}
1927
}
2028
'HttpVersion' {
21-
@('1.0', '1.1', '2.0', '3.0') | Where-Object { $_ -like $pattern } | ForEach-Object {
29+
$filteredOptions = @('1.0', '1.1', '2.0', '3.0') | Where-Object { $_ -like $pattern }
30+
if (-not $filteredOptions) {
31+
return $null
32+
}
33+
$filteredOptions | ForEach-Object {
2234
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
2335
}
2436
}
2537
'EnvironmentType' {
26-
@('Local', 'GitHubActions', 'FunctionApp', 'Unknown') | Where-Object { $_ -like $pattern } | ForEach-Object {
38+
$filteredOptions = @('Local', 'GitHubActions', 'FunctionApp', 'Unknown') | Where-Object { $_ -like $pattern }
39+
if (-not $filteredOptions) {
40+
return $null
41+
}
42+
$filteredOptions | ForEach-Object {
2743
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
2844
}
2945
}
@@ -33,12 +49,20 @@ Register-ArgumentCompleter -CommandName Set-GitHubConfig -ParameterName Value -S
3349
Debug = $false
3450
Verbose = $false
3551
}
36-
Get-GitHubApiVersion @params | Where-Object { $_ -like $pattern } | ForEach-Object {
52+
$filteredOptions = Get-GitHubApiVersion @params | Where-Object { $_ -like $pattern }
53+
if (-not $filteredOptions) {
54+
return $null
55+
}
56+
$filteredOptions | ForEach-Object {
3757
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
3858
}
3959
}
4060
'DefaultContext' {
41-
Get-GitHubContext -ListAvailable | Where-Object { $_.Name -like $pattern } | ForEach-Object {
61+
$filteredOptions = Get-GitHubContext -ListAvailable | Where-Object { $_.Name -like $pattern }
62+
if (-not $filteredOptions) {
63+
return $null
64+
}
65+
$filteredOptions | ForEach-Object {
4266
[System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Name)
4367
}
4468
}

src/functions/public/Environments/completers.ps1

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111
Debug = $false
1212
}
1313
$params | Remove-HashtableEntry -NullOrEmptyValues
14-
Get-GitHubEnvironment @params | Where-Object { $_.Name -like $pattern } | ForEach-Object {
14+
$filteredOptions = Get-GitHubEnvironment @params | Where-Object { $_.Name -like $pattern }
15+
if (-not $filteredOptions) {
16+
return $null
17+
}
18+
$filteredOptions | ForEach-Object {
1519
[System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Name)
1620
}
1721
}
@@ -28,7 +32,11 @@ Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport)
2832
Debug = $false
2933
}
3034
$params | Remove-HashtableEntry -NullOrEmptyValues
31-
Get-GitHubEnvironment @params | Where-Object { $_.Name -like $pattern } | ForEach-Object {
35+
$filteredOptions = Get-GitHubEnvironment @params | Where-Object { $_.Name -like $pattern }
36+
if (-not $filteredOptions) {
37+
return $null
38+
}
39+
$filteredOptions | ForEach-Object {
3240
[System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Name)
3341
}
3442
}

src/functions/public/Gitignore/completers.ps1

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
Verbose = $false
88
Debug = $false
99
}
10-
Get-GitHubGitignore @params | Where-Object { $_ -like $pattern } | ForEach-Object {
10+
$filteredOptions = Get-GitHubGitignore @params | Where-Object { $_ -like $pattern }
11+
if (-not $filteredOptions) {
12+
return $null
13+
}
14+
$filteredOptions | ForEach-Object {
1115
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
1216
}
1317
}

src/functions/public/License/completers.ps1

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
Verbose = $false
88
Debug = $false
99
}
10-
Get-GitHubLicense @params | Where-Object { $_.Name -like $pattern } | ForEach-Object {
10+
$filteredOptions = Get-GitHubLicense @params | Where-Object { $_.Name -like $pattern }
11+
if (-not $filteredOptions) {
12+
return $null
13+
}
14+
$filteredOptions | ForEach-Object {
1115
[System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Name)
1216
}
1317
}

src/functions/public/Organization/completers.ps1

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
Verbose = $false
99
Debug = $false
1010
}
11-
Get-GitHubOrganization @params | Where-Object { $_.Name -like $pattern } | ForEach-Object {
11+
$filteredOptions = Get-GitHubOrganization @params | Where-Object { $_.Name -like $pattern }
12+
if (-not $filteredOptions) {
13+
return $null
14+
}
15+
$filteredOptions | ForEach-Object {
1216
[System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Name)
1317
}
1418
}
@@ -22,7 +26,11 @@ Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport)
2226
Verbose = $false
2327
Debug = $false
2428
}
25-
Get-GitHubOrganization @params | Where-Object { $_.Name -like $pattern } | ForEach-Object {
29+
$filteredOptions = Get-GitHubOrganization @params | Where-Object { $_.Name -like $pattern }
30+
if (-not $filteredOptions) {
31+
return $null
32+
}
33+
$filteredOptions | ForEach-Object {
2634
[System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Name)
2735
}
2836
}
@@ -36,7 +44,11 @@ Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport)
3644
Verbose = $false
3745
Debug = $false
3846
}
39-
Get-GitHubOrganization @params | Where-Object { $_.Name -like $pattern } | ForEach-Object {
47+
$filteredOptions = Get-GitHubOrganization @params | Where-Object { $_.Name -like $pattern }
48+
if (-not $filteredOptions) {
49+
return $null
50+
}
51+
$filteredOptions | ForEach-Object {
4052
[System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Name)
4153
}
4254
}

src/functions/public/Permission/completers.ps1

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
33
$null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters
44
$pattern = switch (Get-GitHubConfig -Name CompletionMode) { 'Contains' { "*$wordToComplete*" } default { "$wordToComplete*" } }
5-
[GitHubPermissionDefinition]::List.Name | Sort-Object -Unique | Where-Object { $_ -like $pattern } | ForEach-Object {
5+
$filteredOptions = [GitHubPermissionDefinition]::List.Name | Sort-Object -Unique | Where-Object { $_ -like $pattern }
6+
if (-not $filteredOptions) {
7+
return $null
8+
}
9+
$filteredOptions | ForEach-Object {
610
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
711
}
812
}
@@ -11,7 +15,11 @@ Register-ArgumentCompleter -CommandName Get-GitHubPermissionDefinition -Paramete
1115
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
1216
$null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters
1317
$pattern = switch (Get-GitHubConfig -Name CompletionMode) { 'Contains' { "*$wordToComplete*" } default { "$wordToComplete*" } }
14-
[GitHubPermissionDefinition]::List.DisplayName | Sort-Object -Unique | Where-Object { $_ -like $pattern } | ForEach-Object {
18+
$filteredOptions = [GitHubPermissionDefinition]::List.DisplayName | Sort-Object -Unique | Where-Object { $_ -like $pattern }
19+
if (-not $filteredOptions) {
20+
return $null
21+
}
22+
$filteredOptions | ForEach-Object {
1523
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
1624
}
1725
}
@@ -20,7 +28,11 @@ Register-ArgumentCompleter -CommandName Get-GitHubPermissionDefinition -Paramete
2028
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
2129
$null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters
2230
$pattern = switch (Get-GitHubConfig -Name CompletionMode) { 'Contains' { "*$wordToComplete*" } default { "$wordToComplete*" } }
23-
[GitHubPermissionDefinition]::List.Type | Sort-Object -Unique | Where-Object { $_ -like $pattern } | ForEach-Object {
31+
$filteredOptions = [GitHubPermissionDefinition]::List.Type | Sort-Object -Unique | Where-Object { $_ -like $pattern }
32+
if (-not $filteredOptions) {
33+
return $null
34+
}
35+
$filteredOptions | ForEach-Object {
2436
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
2537
}
2638
}
@@ -29,7 +41,11 @@ Register-ArgumentCompleter -CommandName Get-GitHubPermissionDefinition -Paramete
2941
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
3042
$null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters
3143
$pattern = switch (Get-GitHubConfig -Name CompletionMode) { 'Contains' { "*$wordToComplete*" } default { "$wordToComplete*" } }
32-
[GitHubPermissionDefinition]::List.Scope | Sort-Object -Unique | Where-Object { $_ -like $pattern } | ForEach-Object {
44+
$filteredOptions = [GitHubPermissionDefinition]::List.Scope | Sort-Object -Unique | Where-Object { $_ -like $pattern }
45+
if (-not $filteredOptions) {
46+
return $null
47+
}
48+
$filteredOptions | ForEach-Object {
3349
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
3450
}
3551
}

src/functions/public/Repositories/Permissions/completers.ps1

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
33
$null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters
44
$pattern = switch (Get-GitHubConfig -Name CompletionMode) { 'Contains' { "*$wordToComplete*" } default { "$wordToComplete*" } }
5-
@('None', 'Pull', 'Triage', 'Push', 'Maintain', 'Admin', 'Read', 'Write') | Where-Object { $_ -like $pattern } | ForEach-Object {
5+
$filteredOptions = @('None', 'Pull', 'Triage', 'Push', 'Maintain', 'Admin', 'Read', 'Write') | Where-Object { $_ -like $pattern }
6+
if (-not $filteredOptions) {
7+
return $null
8+
}
9+
$filteredOptions | ForEach-Object {
610
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
711
}
812
}

src/functions/public/Repositories/completers.ps1

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
Verbose = $false
88
Debug = $false
99
}
10-
Get-GitHubGitignore @params | Where-Object { $_ -like $pattern } | ForEach-Object {
10+
$filteredOptions = Get-GitHubGitignore @params | Where-Object { $_ -like $pattern }
11+
if (-not $filteredOptions) {
12+
return $null
13+
}
14+
$filteredOptions | ForEach-Object {
1115
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
1216
}
1317
}
@@ -21,7 +25,11 @@ Register-ArgumentCompleter -CommandName New-GitHubRepository -ParameterName Lice
2125
Verbose = $false
2226
Debug = $false
2327
}
24-
Get-GitHubLicense @params | Where-Object { $_.Name -like $pattern } | ForEach-Object {
28+
$filteredOptions = Get-GitHubLicense @params | Where-Object { $_.Name -like $pattern }
29+
if (-not $filteredOptions) {
30+
return $null
31+
}
32+
$filteredOptions | ForEach-Object {
2533
[System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Name)
2634
}
2735
}
@@ -30,7 +38,11 @@ Register-ArgumentCompleter -CommandName Get-GitHubRepository -ParameterName Addi
3038
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
3139
$null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters
3240
$pattern = switch (Get-GitHubConfig -Name CompletionMode) { 'Contains' { "*$wordToComplete*" } default { "$wordToComplete*" } }
33-
[GitHubRepository].GetProperties().Name | Where-Object { $_ -like $pattern } | ForEach-Object {
41+
$filteredOptions = [GitHubRepository].GetProperties().Name | Where-Object { $_ -like $pattern }
42+
if (-not $filteredOptions) {
43+
return $null
44+
}
45+
$filteredOptions | ForEach-Object {
3446
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
3547
}
3648
}
@@ -39,7 +51,11 @@ Register-ArgumentCompleter -CommandName Get-GitHubRepository -ParameterName Prop
3951
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
4052
$null = $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters
4153
$pattern = switch (Get-GitHubConfig -Name CompletionMode) { 'Contains' { "*$wordToComplete*" } default { "$wordToComplete*" } }
42-
[GitHubRepository].GetProperties().Name | Where-Object { $_ -like $pattern } | ForEach-Object {
54+
$filteredOptions = [GitHubRepository].GetProperties().Name | Where-Object { $_ -like $pattern }
55+
if (-not $filteredOptions) {
56+
return $null
57+
}
58+
$filteredOptions | ForEach-Object {
4359
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
4460
}
4561
}
@@ -54,7 +70,11 @@ Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport)
5470
Verbose = $false
5571
Debug = $false
5672
}
57-
Get-GitHubRepository @params | Where-Object { $_.Name -like $pattern } | ForEach-Object {
73+
$filteredOptions = Get-GitHubRepository @params | Where-Object { $_.Name -like $pattern }
74+
if (-not $filteredOptions) {
75+
return $null
76+
}
77+
$filteredOptions | ForEach-Object {
5878
[System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Name)
5979
}
6080
}
@@ -70,7 +90,11 @@ Register-ArgumentCompleter -CommandName ($script:PSModuleInfo.FunctionsToExport
7090
Verbose = $false
7191
Debug = $false
7292
}
73-
Get-GitHubRepository @params | Where-Object { $_.Name -like $pattern } | ForEach-Object {
93+
$filteredOptions = Get-GitHubRepository @params | Where-Object { $_.Name -like $pattern }
94+
if (-not $filteredOptions) {
95+
return $null
96+
}
97+
$filteredOptions | ForEach-Object {
7498
[System.Management.Automation.CompletionResult]::new($_.Name, $_.Name, 'ParameterValue', $_.Name)
7599
}
76100
}

0 commit comments

Comments
 (0)