diff --git a/completions/powershell7plus/mutn.ps1 b/completions/powershell7plus/mutn.ps1 index 78f4c7c..a9395b0 100644 --- a/completions/powershell7plus/mutn.ps1 +++ b/completions/powershell7plus/mutn.ps1 @@ -1,9 +1,43 @@ +$global:cliMUTN_entriesToSpaceIndicesMap = @{} + if (!$IsWindows) { # since the executable has the same name as the completion function (on non-Windows platforms), its path must be stored before the function is registered $MUTNExecutablePath = (Get-Command mutn).Path } -function cliMUTNEntryCompleter { +function cliMUTN-getSpaceIndices { + param ([string]$inputString) + $indices = @() + + # loop through each character in the string + for ($i = 0; $i -lt $inputString.Length; $i++) { + if ($inputString[$i] -eq ' ') { + # if the character is a space, add the index to the array + $indices += $i + } + } + + return $indices +} + +function cliMUTN-getEscapedEntryName { + param ([int[]]$Indices, [string]$InputString) + $charArray = $InputString.ToCharArray() + + # loop through each index in the provided array, + # replacing the character at that index with a space + foreach ($index in $Indices) { + $charArray[$index] = ' ' + } + + # convert the character array back to a string + $outputString = -join $charArray + + # return the modified string with spaces escaped + return $outputString -replace ' ', '` ' +} + +function cliMUTN-entryCompleter { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) if ($IsWindows) { $entryRoot = (Resolve-Path '~\AppData\Local\libmutton\entries').Path @@ -12,18 +46,26 @@ function cliMUTNEntryCompleter { } try { $trimmedPaths = If (Test-Path $entryRoot) { - (Get-ChildItem -Path $entryRoot -Recurse -File).FullName.Substring($entryRoot.Length) -replace '\\', '/' -replace ' ', [char]0x259d + (Get-ChildItem -Path $entryRoot -Recurse -File).FullName.Substring($entryRoot.Length) -replace '\\', '/' } } catch { $trimmedPaths = $null # if any errors occur (especially, "You cannot call a method on a null-valued expression", set $trimmedPaths to $null } if ($null -eq $trimmedPaths) { # if no entries are found, add 'help' to $trimmedPaths $trimmedPaths = 'help' + } else { + # replace spaces with underscores, tracking the indices of the spaces in a global variable for later restoration of spaces + $trimmedPaths = $trimmedPaths | ForEach-Object { + $spaceIndices = cliMUTN-getSpaceIndices -inputString $_ + $replacedEntry = $_ -replace ' ', '_' + $replacedEntry + $cliMUTN_entriesToSpaceIndicesMap[$replacedEntry] = $spaceIndices + } } $trimmedPaths | Where-Object { $_ -like "$wordToComplete*" } } -function cliMUTNOptionCompleter { +function cliMUTN-optionCompleter { param ($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $possibleValues = @{ @@ -46,7 +88,7 @@ function mutn { [CmdletBinding()] param ( [Parameter(Position = 0)] - [ArgumentCompleter({ cliMUTNEntryCompleter @args })] + [ArgumentCompleter({ cliMUTN-entryCompleter @args })] [string]$entry, [Parameter(Position = 1)] @@ -54,13 +96,16 @@ function mutn { [string]$argument, [Parameter(Position = 2, ValueFromRemainingArguments=$true)] - [ArgumentCompleter({ cliMUTNOptionCompleter @args })] + [ArgumentCompleter({ cliMUTN-optionCompleter @args })] [string]$option ) + # replace placeholder underscores with escaped spaces + $escapedEntry = cliMUTN-getEscapedEntryName -Indices $global:cliMUTN_entriesToSpaceIndicesMap[$entry] -InputString $entry + if ($IsWindows) { - Invoke-Expression -Command ('mutn.exe ' + ($entry -replace ' ', '` ' -replace [char]0x259d, '` '), $argument, $option).Trim() + Invoke-Expression -Command ('mutn.exe ' + $escapedEntry, $argument, $option).Trim() } else { - Invoke-Expression -Command ($MUTNExecutablePath + ' ' + ($entry -replace ' ', '` ' -replace [char]0x259d, '` '), $argument, $option).Trim() + Invoke-Expression -Command ($MUTNExecutablePath + ' ' + $escapedEntry, $argument, $option).Trim() } }