Enable case-insensitive tab completion for files and folders on case-sensitive filesystem (#8128)
This commit is contained in:
parent
81618bc2c1
commit
b27380dc51
|
@ -4174,7 +4174,7 @@ namespace System.Management.Automation
|
|||
string[] entries = null;
|
||||
try
|
||||
{
|
||||
entries = Directory.GetFileSystemEntries(parentPath, leaf);
|
||||
entries = Directory.GetFileSystemEntries(parentPath, leaf, _enumerationOptions);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -4404,6 +4404,11 @@ namespace System.Management.Automation
|
|||
private const int ERROR_MORE_DATA = 234;
|
||||
private const int STYPE_DISKTREE = 0;
|
||||
private const int STYPE_MASK = 0x000000FF;
|
||||
private static System.IO.EnumerationOptions _enumerationOptions = new System.IO.EnumerationOptions
|
||||
{
|
||||
MatchCasing = MatchCasing.CaseInsensitive,
|
||||
AttributesToSkip = 0 // Default is to skip Hidden and System files, so we clear this to retain existing behavior
|
||||
};
|
||||
|
||||
[DllImport("Netapi32.dll", CharSet = CharSet.Unicode)]
|
||||
private static extern int NetShareEnum(string serverName, int level, out IntPtr bufptr, int prefMaxLen,
|
||||
|
|
|
@ -81,6 +81,11 @@ namespace Microsoft.PowerShell.Commands
|
|||
}
|
||||
|
||||
private Collection<WildcardPattern> _excludeMatcher = null;
|
||||
private static System.IO.EnumerationOptions _enumerationOptions = new System.IO.EnumerationOptions
|
||||
{
|
||||
MatchCasing = MatchCasing.CaseInsensitive,
|
||||
AttributesToSkip = 0 // Default is to skip Hidden and System files, so we clear this to retain existing behavior
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Converts all / in the path to \
|
||||
|
@ -1569,7 +1574,7 @@ namespace Microsoft.PowerShell.Commands
|
|||
else
|
||||
{
|
||||
// Filter the directories
|
||||
target.Add(directory.EnumerateDirectories(Filter));
|
||||
target.Add(directory.EnumerateDirectories(Filter, _enumerationOptions));
|
||||
}
|
||||
|
||||
// Making sure to obey the StopProcessing.
|
||||
|
@ -1580,7 +1585,7 @@ namespace Microsoft.PowerShell.Commands
|
|||
|
||||
// Use the specified filter when retrieving the
|
||||
// children
|
||||
target.Add(directory.EnumerateFiles(Filter));
|
||||
target.Add(directory.EnumerateFiles(Filter, _enumerationOptions));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -222,6 +222,7 @@ Describe "TabCompletion" -Tags CI {
|
|||
$oneSubDir = Join-Path -Path $tempDir -ChildPath "oneSubDir"
|
||||
$oneSubDirPrime = Join-Path -Path $tempDir -ChildPath "prime"
|
||||
$twoSubDir = Join-Path -Path $oneSubDir -ChildPath "twoSubDir"
|
||||
$caseTestPath = Join-Path $testdrive "CaseTest"
|
||||
|
||||
New-Item -Path $tempDir -ItemType Directory -Force > $null
|
||||
New-Item -Path $oneSubDir -ItemType Directory -Force > $null
|
||||
|
@ -254,12 +255,17 @@ Describe "TabCompletion" -Tags CI {
|
|||
}
|
||||
}
|
||||
|
||||
BeforeEach {
|
||||
New-Item -ItemType Directory -Path $caseTestPath > $null
|
||||
}
|
||||
|
||||
AfterAll {
|
||||
Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
AfterEach {
|
||||
Pop-Location
|
||||
Remove-Item -Path $caseTestPath -Recurse -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
It "Input '<inputStr>' should successfully complete" -TestCases $testCases {
|
||||
|
@ -318,6 +324,48 @@ Describe "TabCompletion" -Tags CI {
|
|||
$res.CompletionMatches | Should -HaveCount 1
|
||||
$res.CompletionMatches[0].CompletionText | Should -BeExactly $afterTab
|
||||
}
|
||||
|
||||
It "Test case insensitive <type> path" -Skip:(!$IsLinux) -TestCases @(
|
||||
@{ type = "File" ; beforeTab = "Get-Content f" },
|
||||
@{ type = "Directory"; beforeTab = "cd f" }
|
||||
) {
|
||||
param ($type, $beforeTab)
|
||||
|
||||
$testItems = "foo", "Foo", "fOO"
|
||||
$testItems | ForEach-Object {
|
||||
$itemPath = Join-Path $caseTestPath $_
|
||||
New-Item -ItemType $type -Path $itemPath
|
||||
}
|
||||
Push-Location $caseTestPath
|
||||
$res = TabExpansion2 -inputScript $beforeTab -cursorColumn $beforeTab.Length
|
||||
$res.CompletionMatches | Should -HaveCount $testItems.Count
|
||||
|
||||
# order isn't guaranteed so we'll sort them first
|
||||
$completions = ($res.CompletionMatches | Sort-Object CompletionText -CaseSensitive).CompletionText -join ":"
|
||||
$expected = ($testItems | Sort-Object -CaseSensitive | ForEach-Object { "./$_" }) -join ":"
|
||||
|
||||
$completions | Should -BeExactly $expected
|
||||
}
|
||||
|
||||
It "Test case insensitive file and folder path completing for <type>" -Skip:(!$IsLinux) -TestCases @(
|
||||
@{ type = "File" ; beforeTab = "Get-Content f"; expected = "foo","Foo" }, # Get-Content passes thru to provider
|
||||
@{ type = "Directory"; beforeTab = "cd f" ; expected = "Foo" } # Set-Location is aware of Files vs Folders
|
||||
) {
|
||||
param ($beforeTab, $expected)
|
||||
|
||||
$filePath = Join-Path $caseTestPath "foo"
|
||||
$folderPath = Join-Path $caseTestPath "Foo"
|
||||
New-Item -ItemType File -Path $filePath
|
||||
New-Item -ItemType Directory -Path $folderPath
|
||||
Push-Location $caseTestPath
|
||||
$res = TabExpansion2 -inputScript $beforeTab -cursorColumn $beforeTab.Length
|
||||
$res.CompletionMatches | Should -HaveCount $expected.Count
|
||||
|
||||
# order isn't guaranteed so we'll sort them first
|
||||
$completions = ($res.CompletionMatches | Sort-Object CompletionText -CaseSensitive).CompletionText -join ":"
|
||||
$expected = ($expected | Sort-Object -CaseSensitive | ForEach-Object { "./$_" }) -join ":"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Context "Cmdlet name completion" {
|
||||
|
|
Loading…
Reference in a new issue