private/CompletePaths.ps1
function CompletePaths { param( [Switch] $dirsOnly, [Switch] $filesOnly, $commandName, $parameterName, $wordToComplete, $commandAst, $boundParameters ) $force = $boundParameters -and [bool]$boundParameters['Force'] # given a full path, $_, return a fully formed completion result # logic: use a relative path if the supplied word isn't rooted (like /temp/... or ~/... C:\...) # *and* the resolved path is a child of the current directory or its parent # for absolute paths, replace home dir location with tilde filter CompletionResult { # add normalised trailing directory separator; quote if contains spaces $trailChar = if ($_.PSIsContainer) { ${/} } $fullPath = $_ | select -Expand PSPath | Convert-Path $completionText = if ($wordToComplete -match '^\.{1,2}$') { $wordToComplete } elseif (!($wordToComplete | IsRooted) -and ($fullPath | IsDescendedFrom ..)) { $_ | Resolve-Path -Relative } elseif ($homeDir = (Get-Location).Provider.Home) { $_ -replace "^$($homeDir | NormaliseAndEscape)", "~" } else { $fullPath } $completionText = $completionText | RemoveTrailingSeparator | SurroundAndTerminate $trailChar # there seems to be a weird bug in PowerShell where square brackets must be escaped # by every/many(?) command(s) _except_ Get-ChildItem, where they must *not* be escaped if ($commandName -ne 'Get-ChildItem') { $completionText = $completionText | EscapeSquareBrackets } # hack to support registry provider if ($_.PSProvider.Name -eq 'Registry') { $completionText = $completionText -replace $_.PSDrive.Root, "$($_.PSDrive.Name):" } # dirColors support $listItemText = if ( ($cde.ColorCompletion) -and ($_.PSProvider.Name -eq 'FileSystem') -and (Test-Path Function:\Format-ColorizedFilename)) { Format-ColorizedFilename $_ } else { $_.PSChildName } [Management.Automation.CompletionResult]::new( $completionText, $listItemText, 'ParameterValue', ($fullPath | DefaultIfEmpty { $_ }) ) } $switches = @{ File = $filesOnly; Directory = $dirsOnly; Force = $force } $completions = Expand-Path @switches $wordToComplete -MaxResults $cde.MaxCompletions #replace cdable_vars $variCompletions = if ( $cde.CDABLE_VARS -and $wordToComplete -match '[^/\\]+' -and ($maybeVar = Get-Variable "$($Matches[0])*" -ValueOnly | where { Test-Path $_ -PathType Container }) ) { Expand-Path @switches ($wordToComplete -replace $Matches[0], $maybeVar) -MaxResults $cde.MaxCompletions } @($completions) + @($variCompletions) | select -Unique | select -First $cde.MaxCompletions | CompletionResult } |