Private/TabCompletion.ps1
|
function TabComplete() { $actionKeys = @( [PowerShellRun.ActionKey]::new($script:globalStore.firstActionKey, 'Insert') ) $inputScript = $null $cursorPos = $null [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$inputScript, [ref]$cursorPos) $commandCompletion = TabExpansion2 -inputScript $inputScript -cursorColumn $cursorPos if ($commandCompletion.CompletionMatches.Count -eq 0) { return } if ($commandCompletion.CompletionMatches.Count -eq 1) { $completion = $commandCompletion.CompletionMatches[0] ReplaceTabCompletionText $commandCompletion $completion return } [Microsoft.PowerShell.PSConsoleReadLine]::ClearScreen() $entries = [System.Collections.Generic.List[PowerShellRun.SelectorEntry]]::new() $noMatchRegex = [Regex]::new('\0') foreach ($completion in $commandCompletion.CompletionMatches) { $entry = [PowerShellRun.SelectorEntry]::new() $entry.UserData = $completion $entry.Icon = GetTabCompletionIcon $completion $entry.Name = $completion.ListItemText $entry.Description = "[$($completion.ResultType)] $($completion.CompletionText)" # Exclude Description from search. $entry.DescriptionSearchablePattern = $noMatchRegex $entry.PreviewAsyncScript, $entry.PreviewAsyncScriptArgumentList = GetTabCompletionPreviewScript $completion $entry.ActionKeys = $actionKeys $entries.Add($entry) } $originalCanvasTopMargin = $script:globalStore.psRunSelectorOption.Theme.CanvasTopMargin $script:globalStore.psRunSelectorOption.Theme.CanvasTopMargin += 1 $result = Invoke-PSRunSelectorCustom -Entry $entries -Option $script:globalStore.psRunSelectorOption $script:globalStore.psRunSelectorOption.Theme.CanvasTopMargin = $originalCanvasTopMargin $completion = $result.FocusedEntry.UserData if (-not $completion) { # We have to call RevertLine twice to escape from PredictionViewStyle ListView. [Microsoft.PowerShell.PSConsoleReadLine]::RevertLine() [Microsoft.PowerShell.PSConsoleReadLine]::RevertLine() [Microsoft.PowerShell.PSConsoleReadLine]::Insert($inputScript) [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursorPos) return } if ($result.KeyCombination -eq $script:globalStore.firstActionKey) { ReplaceTabCompletionText $commandCompletion $completion } } function GetTabCompletionIcon($CompletionResult) { $resultType = $CompletionResult.ResultType $icon = switch ($resultType) { ProviderContainer { '📁' } ProviderItem { '📄' } History { '📙' } Command { '🔧' } default { '📝' } } $icon } function GetTabCompletionPreviewScript($CompletionResult) { $previewDefault = { param ($completionResult) $completionResult.ToolTip } $previewFolder = { param ($completionResult) $path = $completionResult.ToolTip $childItems = Get-ChildItem $path $childItems | ForEach-Object { if ($_.PSIsContainer) { $icon = '📁' } else { $icon = '📄' } '{0} {1}' -f $icon, $_.Name } } $previewFile = { param ($completionResult) $path = $completionResult.ToolTip Get-Item $path | Out-String } $previewCommand = { param ($completionResult) $commandName = $completionResult.ListItemText $command = Get-Command -Name $commandName -ErrorAction Ignore if (-not $command) { return $completionResult.ToolTip } $preview = switch ($command.CommandType) { { $_ -in 'Alias', 'Cmdlet', 'Function', 'Filter' } { Get-Help $commandName | Out-String } default { $command | Select-Object -Property Version, Source | Out-String } } $preview } $resultType = $CompletionResult.ResultType $previewScript = switch ($resultType) { ProviderContainer { $previewFolder } ProviderItem { $previewFile } Command { $previewCommand } default { $previewDefault } } $previewScript, $CompletionResult } function ReplaceTabCompletionText($CommandCompletion, $CompletionResult) { $completionText = $CompletionResult.CompletionText $putCursorBeforeQuote = $false # If it's a folder, put DirectorySeparatorChar at the end for the next tab completion. if ($CompletionResult.ResultType -eq 'ProviderContainer') { $lastChar = $completionText[-1] if ($lastChar -eq "'" -or $lastChar -eq '"') { $completionText = $completionText.Substring(0, $completionText.Length - 1) + [System.IO.Path]::DirectorySeparatorChar + $lastChar $putCursorBeforeQuote = $true } else { $completionText += [System.IO.Path]::DirectorySeparatorChar } } [Microsoft.PowerShell.PSConsoleReadLine]::Replace($CommandCompletion.ReplacementIndex, $CommandCompletion.ReplacementLength, $completionText) if ($putCursorBeforeQuote) { [Microsoft.PowerShell.PSConsoleReadLine]::BackwardChar() } } |