mirror of
https://github.com/PowerShell/PSReadLine
synced 2026-06-08 12:12:13 +00:00
To work around PowerShell Core not loading the dll from the same directory as PSReadLine.psd1, I've renamed the dll.
213 lines
6.5 KiB
PowerShell
213 lines
6.5 KiB
PowerShell
|
|
param(
|
|
$Configuration = 'Release',
|
|
|
|
[Parameter(Mandatory)]
|
|
$OutFile
|
|
)
|
|
|
|
$errorActionPreference = "Stop"
|
|
|
|
$ourAssembly = "$PSScriptRoot\PSReadLine\bin\$Configuration\Microsoft.PowerShell.PSReadLine2.dll"
|
|
|
|
$t ='Microsoft.PowerShell.PSConsoleReadLine' -as [type]
|
|
if ($null -ne $t -and $t.Assembly.Location -ne $ourAssembly)
|
|
{
|
|
# Make sure we're runnning in a non-interactive session by relaunching
|
|
powershell -NoProfile -NonInteractive -File $PSCommandPath $Configuration $OutFile
|
|
exit $LASTEXITCODE
|
|
}
|
|
|
|
try {
|
|
|
|
Import-Module "$PSScriptRoot\bin\$Configuration\PSReadLine\PSReadLine.psd1"
|
|
|
|
$helpContent = [xml](Get-Content "$PSScriptRoot\PSReadLine\bin\$Configuration\Microsoft.PowerShell.PSReadLine.xml")
|
|
|
|
Set-PSReadLineOption -EditMode Windows
|
|
$cmdKeyBindings = Get-PSReadLineKeyHandler -Bound
|
|
|
|
Set-PSReadLineOption -EditMode Emacs
|
|
$emacsKeyBindings = Get-PSReadLineKeyHandler -Bound
|
|
|
|
Set-PSReadLineOption -EditMode Vi
|
|
$viKeyBindings = Get-PSReadLineKeyHandler -Bound
|
|
|
|
$bindableFunctionsFromReflection = ((Get-Command Set-PSReadLineKeyHandler).Parameters['Function'].Attributes).ValidValues
|
|
|
|
[enum]::GetNames([Microsoft.PowerShell.KeyHandlerGroup]) |
|
|
ForEach-Object { '{0},{1}' -f $_,[Microsoft.PowerShell.KeyHandler]::GetGroupingDescription($_) } |
|
|
ForEach-Object { $groupingDescriptions = @{} } { $k,$v = $_ -split ',',2; $groupingDescriptions[$k] = $v }
|
|
|
|
class BindableFunction
|
|
{
|
|
[string]$Function
|
|
[string]$Description
|
|
[string[]]$CmdBindings = @()
|
|
[string[]]$EmacsBindings = @()
|
|
[string[]]$ViInsBindings = @()
|
|
[string[]]$ViCmdBindings = @()
|
|
# Can't use the following type because it's not loaded at parse time
|
|
<#[Microsoft.PowerShell.KeyHandlerGroup]#>[object]$Group
|
|
}
|
|
|
|
$allFunctions = @{}
|
|
|
|
foreach ($fn in $bindableFunctionsFromReflection)
|
|
{
|
|
$bindableFn = [BindableFunction]::new()
|
|
$bindableFn.Function = $fn
|
|
$bindableFn.Group = [Microsoft.PowerShell.PSConsoleReadLine]::GetDisplayGrouping($fn)
|
|
|
|
$allFunctions[$fn] = $bindableFn
|
|
}
|
|
|
|
foreach ($member in $helpContent.doc.members.member)
|
|
{
|
|
$re = [regex]'^M:Microsoft\.PowerShell\.PSConsoleReadLine\.([a-zA-Z]+)\(System\.Nullable\{System\.ConsoleKeyInfo\},System.Object\)$'
|
|
$name = $member.GetAttribute('name')
|
|
if ($name -match $re)
|
|
{
|
|
$fn = $matches[1]
|
|
$bindableFn = $allFunctions[$fn]
|
|
if ($null -eq $bindableFn) { continue }
|
|
|
|
$summary = $member.summary
|
|
if ($summary -is [System.Xml.XmlElement])
|
|
{
|
|
# Special case to handle a cref, this is not generic code
|
|
$parts = foreach ($c in $summary.ChildNodes)
|
|
{
|
|
if ($c -is [System.Xml.XmlText])
|
|
{
|
|
$c.InnerText
|
|
}
|
|
elseif ($c -is [System.Xml.XmlElement])
|
|
{
|
|
$null = $c.cref -match $re
|
|
$matches[1]
|
|
}
|
|
}
|
|
|
|
$summary = $parts -join ''
|
|
}
|
|
|
|
$bindableFn.Description = $summary.Trim()
|
|
}
|
|
}
|
|
|
|
foreach ($binding in $cmdKeyBindings)
|
|
{
|
|
$allFunctions[$binding.Function].CmdBindings += $binding.Key
|
|
}
|
|
|
|
foreach ($binding in $emacsKeyBindings)
|
|
{
|
|
$allFunctions[$binding.Function].EmacsBindings += $binding.Key
|
|
}
|
|
|
|
foreach ($binding in $viKeyBindings)
|
|
{
|
|
$mode = if ($binding.Key[0] -eq '<') { 'ViCmdBindings' } else { 'ViInsBindings' }
|
|
# Some vi functions are private but are stil reported by Get-PSReadLineKeyHandler
|
|
$bindableFn = $allFunctions[$binding.Function]
|
|
if ($null -ne $bindableFn)
|
|
{
|
|
$bindableFn.$mode += $binding.Key
|
|
}
|
|
}
|
|
|
|
|
|
$indent = " "
|
|
$maxWidth = 90
|
|
|
|
$allFunctions.Values |
|
|
Group-Object -Property Group |
|
|
Sort-Object {[Microsoft.PowerShell.KeyHandlerGroup]$_.Name} |
|
|
ForEach-Object {
|
|
$label = $groupingDescriptions[$_.Name]
|
|
" {0}`n {1}`n" -f $label, ('-' * $label.Length)
|
|
|
|
$_.Group | Sort-Object Function | ForEach-Object {
|
|
$desc = $_.Description -replace "`n",'' -replace " +"," "
|
|
if ($desc.Length - $indent.Length -gt $maxWidth)
|
|
{
|
|
# Wrap the text
|
|
$sb = [System.Text.StringBuilder]::new()
|
|
|
|
$col = $indent.Length
|
|
$words = $desc -split ' '
|
|
foreach ($word in $words)
|
|
{
|
|
if ($col + $word.Length -gt $maxWidth)
|
|
{
|
|
$null = $sb.Append("`n$indent")
|
|
$col = $indent.Length
|
|
}
|
|
|
|
$col += ($word.Length + 1)
|
|
$null = $sb.Append($word)
|
|
$null = $sb.Append(" ")
|
|
}
|
|
|
|
$null = $sb.Remove($sb.Length - 1, 1)
|
|
$desc = $sb.ToString()
|
|
}
|
|
|
|
$sb = [System.Text.StringBuilder]::new()
|
|
|
|
$null = if ($_.CmdBindings.Length -gt 0) {
|
|
$sb.Append($indent)
|
|
$sb.Append("Cmd: <")
|
|
$sb.Append($_.CmdBindings -join '>, <')
|
|
$sb.Append('>')
|
|
}
|
|
$null = if ($_.EmacsBindings.Length -gt 0) {
|
|
if ($sb.Length -gt 0) { $sb.AppendLine() }
|
|
$sb.Append($indent)
|
|
$sb.Append("Emacs: <")
|
|
$sb.Append($_.EmacsBindings -join '>, <')
|
|
$sb.Append('>')
|
|
}
|
|
$null = if ($_.ViInsBindings.Length -gt 0) {
|
|
if ($sb.Length -gt 0) { $sb.AppendLine() }
|
|
$sb.Append($indent)
|
|
$sb.Append("Vi insert mode: <")
|
|
$sb.Append($_.ViInsBindings -join '>, <')
|
|
$sb.Append('>')
|
|
}
|
|
$null = if ($_.ViCmdBindings.Length -gt 0) {
|
|
if ($sb.Length -gt 0) { $sb.AppendLine() }
|
|
$sb.Append($indent)
|
|
$sb.Append("Vi command mode: ")
|
|
$sb.Append($_.ViCmdBindings -join ', ')
|
|
}
|
|
|
|
if ($sb.Length -eq 0)
|
|
{
|
|
$bindings = "${indent}Function is unbound."
|
|
}
|
|
else {
|
|
$bindings = $sb.ToString()
|
|
}
|
|
|
|
" {0}:`n`n{1}{2}`n`n{3}`n" -f $_.Function, $indent, $desc, $bindings
|
|
}
|
|
} | Out-File -LiteralPath $OutFile -Encoding ascii
|
|
|
|
} catch
|
|
{
|
|
& {
|
|
[Microsoft.PowerShell.PSConsoleReadLine].Assembly.Location | Out-String
|
|
$_ | Out-String
|
|
$_.Exception | Out-String
|
|
$_.Exception.StackTrace | Out-String
|
|
$_.Exception.InnerException | Out-String
|
|
$_.Exception.InnerException.StackTrace | Out-String
|
|
|
|
} | Out-Host
|
|
exit 1
|
|
}
|
|
|
|
exit 0
|