From 3bb6ad594744da0e06681d55d3a49acf984749e9 Mon Sep 17 00:00:00 2001 From: Josh Dearing Date: Wed, 21 May 2025 08:17:20 -0500 Subject: [PATCH] Added the ability to explore parameters --- ModuleExplorer/ModuleExplorer.psd1 | 2 +- .../functions/Show-ModuleCommandViewer.ps1 | 302 +++++++++++++----- 2 files changed, 222 insertions(+), 82 deletions(-) diff --git a/ModuleExplorer/ModuleExplorer.psd1 b/ModuleExplorer/ModuleExplorer.psd1 index 3264384..9ac4a16 100644 --- a/ModuleExplorer/ModuleExplorer.psd1 +++ b/ModuleExplorer/ModuleExplorer.psd1 @@ -12,7 +12,7 @@ RootModule = 'ModuleExplorer.psm1' # Version number of this module. -ModuleVersion = '0.1.1' +ModuleVersion = '0.1.2' # Supported PSEditions CompatiblePSEditions = 'Core' diff --git a/ModuleExplorer/functions/Show-ModuleCommandViewer.ps1 b/ModuleExplorer/functions/Show-ModuleCommandViewer.ps1 index db689b3..bf51653 100644 --- a/ModuleExplorer/functions/Show-ModuleCommandViewer.ps1 +++ b/ModuleExplorer/functions/Show-ModuleCommandViewer.ps1 @@ -16,8 +16,8 @@ Right Pane: Initially displays the synopsis of the selected command. After selecting a command (Right Arrow or Enter), it shows help options - (Examples, Detailed, Full, Online). Selecting a help option displays - the corresponding help content, which can be scrolled. + (Examples, Detailed, Full, Online, Parameters). Selecting any help option + or a specific parameter displays the corresponding help content. Navigation is primarily through arrow keys, Enter, and Escape. Instructions for key bindings are displayed at the bottom of the viewer. @@ -43,7 +43,7 @@ This is a private function and is not intended to be called directly by users of the ModuleExplorer module. It is used internally to provide UI capabilities. - Requires the Spectre.Console PowerShell module to be available. + Requires the PwshSpectreConsole module to be available. The function attempts to dynamically adjust the displayed list sizes based on console window height. This works best when expanding the window; shrinking may not immediately reflect without reselecting the module. @@ -57,21 +57,27 @@ - Type characters: Filter the command list. - Backspace/Left Arrow (when search string active): Delete last character from search. - Right Arrow / Enter: Select command and move to Help Options view. - - Left Arrow (no search string): Go back (effectively exits in this initial context if called from a parent menu). + - Left Arrow (no search string): Go back. - Escape: Exit the viewer. - Help Options (Right Pane - After selecting a command): - - Up/Down Arrows: Navigate help options (Examples, Detailed, Full, Online). - - Right Arrow / Enter: View selected help content. + - Up/Down Arrows: Navigate help options. + - Right Arrow / Enter: View selected help content or parameter list. - Left Arrow: Return to Command List (Description view). - Escape: Exit the viewer. - - Help Content (Right Pane - After selecting a help option): - - Up/Down Arrows: Scroll through help content. - - Right Arrow / Enter (if "Online" help was selected and is pending): Open online help in browser. + - Parameter List (Right Pane - After selecting "Parameters"): + - Up/Down Arrows: Navigate parameter list (common parameters are grey). + - Right Arrow / Enter: View help for selected parameter. - Left Arrow: Return to Help Options view. - Escape: Exit the viewer. + - Help Content / Parameter Help Content (Right Pane): + - Up/Down Arrows: Navigate through help content. + - Right Arrow / Enter (if "Online" help was selected): Open online help. + - Left Arrow: Return to Help Options view or Parameter List view. + - Escape: Exit the viewer. + .EXAMPLE # This is a private function. The following shows conceptual internal usage: @@ -82,7 +88,7 @@ # This would launch the interactive command viewer for the 'Pester' module. .LINK - None + https://github.com/DearingDev/ModuleExplorer/blob/main/ModuleExplorer/functions/Show-ModuleCommandViewer.ps1 #> function Show-ModuleCommandViewer { param ( @@ -90,6 +96,13 @@ function Show-ModuleCommandViewer { [PSObject]$SelectedModule ) + # Define common PowerShell parameters + $commonParameterNames = @( + 'Verbose', 'Debug', 'ErrorAction', 'ErrorVariable', 'WarningAction', + 'WarningVariable', 'OutBuffer', 'OutVariable', 'PipelineVariable', + 'InformationAction', 'InformationVariable', 'ProgressAction' + ) + $commands = Get-Command -Module $SelectedModule.Name | Sort-Object CommandType, Name if (-not $commands) { @@ -138,7 +151,6 @@ function Show-ModuleCommandViewer { $commandListPaneLayout = New-SpectreLayout -Name "commandListPane" -Data $initialCommandListContent -Ratio 1 $rightPaneLayout = New-SpectreLayout -Name "rightPane" -Data $initialRightPanelContent -Ratio 3 - $combinedPanel = New-SpectreLayout -Name "combinedPanel" -Columns @($commandListPaneLayout , $rightPaneLayout) -Ratio 10 $titleRenderable = Write-SpectreHost "`n[green bold]Cmdlets[/], [blue bold]Functions[/], and [magenta bold]Aliases[/] in $($SelectedModule.Name)" -PassThru | Format-SpectrePadded -Top 0 -Right 0 -Bottom 0 -Left 1 @@ -154,31 +166,36 @@ function Show-ModuleCommandViewer { # Set default variables for the live UI $currentCommandIndex = 0 $currentHelpOptionIndex = 0 + $currentParameterIndex = 0 $rightPaneView = 'Description' $searchString = "" $filteredCommandObjects = $allCommandObjects $currentCommandObjectForHelp = $null + $currentParameterObjectForHelp = $null + $commandParametersForHelp = @() # Holds Parameter objects, sorted with common params last - # Estimate for fixed rows header, footer, borders, instrucitons - $fixedRowsOverhead = 5 + # Dynamic sizing based on console height + $fixedRowsOverhead = 5 # Approximate rows for title, instructions, borders $dynamicPageSize = ($Host.UI.RawUI.WindowSize.Height - $fixedRowsOverhead) - if ($dynamicPageSize -lt 1) {$dynamicPageSize = 1} + if ($dynamicPageSize -lt 1) {$dynamicPageSize = 1} # Ensure at least 1 $commandListPageSize = $dynamicPageSize $commandListScrollOffset = 0 - $helpOptions = @("Examples", "Detailed", "Full", "Online" ) - $currentHelpContentLines = @() + $helpOptions = @("Examples", "Detailed", "Full", "Online", "Parameters") + $currentHelpContentLines = @() # Stores text current help view $helpContentScrollOffset = 0 $helpContentPageSize = $dynamicPageSize - + + $parameterListPageSize = $dynamicPageSize + $parameterListScrollOffset = 0 try { while ($true) { - # Recalculate dynamic page sizes in case console was resized + # Recalculate dynamic page sizes if console was resized # This doesn't work when shrinking the console, but it does when expanding - # Will need to revisit to see if I can resolve that issue + # Will need to revisit to see if I can resolve that issue. $newDynamicPageSize = ($Host.UI.RawUI.WindowSize.Height - $fixedRowsOverhead) if ($newDynamicPageSize -lt 1) {$newDynamicPageSize = 1} @@ -186,30 +203,37 @@ function Show-ModuleCommandViewer { $dynamicPageSize = $newDynamicPageSize $commandListPageSize = $dynamicPageSize $helpContentPageSize = $dynamicPageSize + $parameterListPageSize = $dynamicPageSize - # Re-clamp scroll offsets if page size changes - $commandListTotalItemsForClamp = $filteredCommandObjects.Count # Use current filtered count + # Re-clamp scroll offsets + $commandListTotalItemsForClamp = $filteredCommandObjects.Count if ($commandListTotalItemsForClamp -gt 0) { $commandListScrollOffset = [System.Math]::Min($commandListScrollOffset, [System.Math]::Max(0, $commandListTotalItemsForClamp - $commandListPageSize)) } else { $commandListScrollOffset = 0 } + + if ($commandParametersForHelp.Count -gt 0 -and $rightPaneView -eq 'ParameterList') { + $parameterListScrollOffset = [System.Math]::Min($parameterListScrollOffset, [System.Math]::Max(0, $commandParametersForHelp.Count - $parameterListPageSize)) + } else { + $commandListScrollOffset = 0 + } if ($currentHelpContentLines.Count -gt 0) { $helpContentScrollOffset = [System.Math]::Min($helpContentScrollOffset, [System.Math]::Max(0, $currentHelpContentLines.Count - $helpContentPageSize)) } else { - $helpContentScrollOffset = 0 + $commandListScrollOffset = 0 } } - # Filter commands based on search string + # Filter command list based on search string if ($searchString -ne "") { $filteredCommandObjects = $allCommandObjects | Where-Object { $_.Name -like "*$searchString*" } + # Adjust current index and scroll if filter changes if ($currentCommandIndex -ge $filteredCommandObjects.Count -and $filteredCommandObjects.Count -gt 0) { - $currentCommandIndex = $filteredCommandObjects.Count - 1 # Select last item + $currentCommandIndex = $filteredCommandObjects.Count - 1 # Select last item } elseif ($filteredCommandObjects.Count -eq 0) { - $currentCommandIndex = -1 # No item selected + $currentCommandIndex = -1 } - # Reset scroll if filter changes and current index is off-page or invalid if ($currentCommandIndex -eq -1 -or $currentCommandIndex -lt $commandListScrollOffset -or $currentCommandIndex -ge ($commandListScrollOffset + $commandListPageSize)) { $commandListScrollOffset = [System.Math]::Max(0, $currentCommandIndex - [System.Math]::Floor($commandListPageSize / 2)) if ($commandListTotalItems -gt 0) { @@ -218,12 +242,12 @@ function Show-ModuleCommandViewer { $commandListScrollOffset = 0 } } - } else { $filteredCommandObjects = $allCommandObjects } $commandListTotalItems = $filteredCommandObjects.Count + # Ensure currentCommandIndex is valid if ($commandListTotalItems -eq 0) { $currentCommandIndex = -1 $commandListScrollOffset = 0 @@ -233,7 +257,6 @@ function Show-ModuleCommandViewer { $commandListScrollOffset = 0 } - # Command List Panel (Left Pane) $listItems = New-Object System.Collections.Generic.List[string] $commandListPanelHeader = "[bold]($($commandListTotalItems) total)[/]" @@ -257,11 +280,10 @@ function Show-ModuleCommandViewer { 'Alias' { "[magenta]$displayName[/]" } default { $displayName } } - if ($i -eq $currentCommandIndex) { $listItems.Add("[yellow bold]>[/] $($styledName)") } + if ($i -eq $currentCommandIndex) { $listItems.Add("[yellow bold]>[/] $($styledName)") } # Highlight selected else { $listItems.Add(" $($styledName)") } } if ($visibleListEndIndex -lt ($commandListTotalItems - 1)) { $listItems.Add("[grey] ↓ ...[/]")} - } else { $listItems.Add("[grey] (No commands to display) [/]") } @@ -295,9 +317,43 @@ function Show-ModuleCommandViewer { else { " $($helpOptions[$i])" } } $rightPanelContentRenderable = ($helpOptionListItems | Format-SpectreRows | Format-SpectrePanel -Header $rightPanelHeader -Expand -Border Rounded) - } elseif ($rightPaneView -eq 'HelpContent') { - $rightPanelHeader = "[bold]Help: $($currentCommandObjectForHelp.Name) - $($helpOptions[$currentHelpOptionIndex])[/]" + + } elseif ($rightPaneView -eq 'ParameterList') { + $rightPanelHeader = "[bold]Parameters for $($currentCommandObjectForHelp.Name)[/]" + $paramListItems = New-Object System.Collections.Generic.List[string] + if ($commandParametersForHelp.Count -gt 0) { + if ($parameterListScrollOffset -gt 0) { $paramListItems.Add("[grey] ↑ ...[/]")} + + $visibleParamListStartIndex = $parameterListScrollOffset + $visibleParamListEndIndex = [System.Math]::Min(($parameterListScrollOffset + $parameterListPageSize - 1), ($commandParametersForHelp.Count - 1)) + + for ($p = $visibleParamListStartIndex; $p -le $visibleParamListEndIndex; $p++) { + if ($p -lt 0 -or $p -ge $commandParametersForHelp.Count) { continue } + $paramMetadata = $commandParametersForHelp[$p] + $paramName = $paramMetadata.Name + $styledParamName = if ($commonParameterNames -contains $paramName) { # Style common parameters + "[grey]$paramName[/]" + } else { + $paramName + } + if ($p -eq $currentParameterIndex) { $paramListItems.Add("[yellow bold]>[/] $($styledParamName)") } + else { $paramListItems.Add(" $($styledParamName)") } + } + if ($visibleParamListEndIndex -lt ($commandParametersForHelp.Count - 1)) { $paramListItems.Add("[grey] ↓ ...[/]")} + } else { + $paramListItems.Add("[grey](No parameters found or command does not support parameters)[/]") + } + $rightPanelContentRenderable = ($paramListItems | Format-SpectreRows | Format-SpectrePanel -Header $rightPanelHeader -Expand -Border Rounded) + + } elseif ($rightPaneView -eq 'HelpContent' -or $rightPaneView -eq 'ParameterHelpContent') { + # Determine header based on whether it's general help or parameter-specific help + if ($rightPaneView -eq 'ParameterHelpContent') { + $rightPanelHeader = "[bold]Parameter: $($currentParameterObjectForHelp.Name) in $($currentCommandObjectForHelp.Name)[/]" + } else { # HelpContent + $rightPanelHeader = "[bold]Help: $($currentCommandObjectForHelp.Name) - $($helpOptions[$currentHelpOptionIndex])[/]" + } + # Display scrolled content $visibleHelpLines = New-Object System.Collections.Generic.List[string] if ($currentHelpContentLines.Count -gt 0) { if ($helpContentScrollOffset -gt 0) { $visibleHelpLines.Add("[grey] ↑ ...[/]")} @@ -335,7 +391,7 @@ function Show-ModuleCommandViewer { $searchString += $keyInfo.KeyChar $currentCommandIndex = 0 $commandListScrollOffset = 0 - continue + continue # Re-render with new search } # More Input Handling! @@ -362,10 +418,10 @@ function Show-ModuleCommandViewer { $currentCommandObjectForHelp = $filteredCommandObjects[$currentCommandIndex] $rightPaneView = 'HelpOptions' $currentHelpOptionIndex = 0 - $searchString = "" + $searchString = "" # Clear search when moving to help } } - ([System.ConsoleKey]::LeftArrow) { + ([System.ConsoleKey]::LeftArrow) { # Backspace for search or exit if ($searchString.Length -gt 0) { $searchString = $searchString.Substring(0, $searchString.Length - 1) $currentCommandIndex = 0 @@ -381,8 +437,7 @@ function Show-ModuleCommandViewer { $commandListScrollOffset = 0 } } - # This is just a mirror of the right arrow - ([System.ConsoleKey]::Enter) { + ([System.ConsoleKey]::Enter) { # Same as RightArrow if ($currentCommandIndex -ge 0 -and $currentCommandIndex -lt $filteredCommandObjects.Count) { $currentCommandObjectForHelp = $filteredCommandObjects[$currentCommandIndex] $rightPaneView = 'HelpOptions' @@ -401,110 +456,195 @@ function Show-ModuleCommandViewer { } ([System.ConsoleKey]::RightArrow) { $selectedHelpType = $helpOptions[$currentHelpOptionIndex] - $currentHelpContent = "[grey]Fetching help...[/]" - $currentHelpContentLines = @() + $currentHelpContentLines = @("[grey]Fetching help...[/]") # Placeholder $helpContentScrollOffset = 0 - $rightPaneView = 'HelpContent' - $LiveContext.Refresh() - - if ($selectedHelpType -eq "Online") { - $currentHelpContent = "[yellow]Press Right Arrow or Enter to open online help (if available), or Left Arrow to go back.[/]" - $currentHelpContentLines = @($currentHelpContent.ToString()) - } else { + + if ($selectedHelpType -eq "Parameters") { # Handle "Parameters" selection + $allParams = $currentCommandObjectForHelp.CommandInfo.Parameters.Values + $nonCommonParams = $allParams | Where-Object { $commonParameterNames -notcontains $_.Name } | Sort-Object Name + $commonParamsFromCmd = $allParams | Where-Object { $commonParameterNames -contains $_.Name } | Sort-Object Name + $commandParametersForHelp = $nonCommonParams + $commonParamsFromCmd # Non-common first + + $currentParameterIndex = 0 + $parameterListScrollOffset = 0 + $rightPaneView = 'ParameterList' + } elseif ($selectedHelpType -eq "Online") { + $currentHelpContentLines = @("[yellow]Press Right Arrow or Enter to open online help (if available), or Left Arrow to go back.[/]") + $rightPaneView = 'HelpContent' + } else { # For Examples, Detailed, Full + $rightPaneView = 'HelpContent' + $LiveContext.Refresh() # Show "Fetching help..." try { $helpText = "" switch($selectedHelpType) { - # "Synopsis" { $helpText = Get-Help $currentCommandObjectForHelp.CommandInfo | Out-String } "Examples" { $helpText = Get-Help $currentCommandObjectForHelp.CommandInfo -Examples | Out-String } "Detailed" { $helpText = Get-Help $currentCommandObjectForHelp.CommandInfo -Detailed | Out-String } "Full" { $helpText = Get-Help $currentCommandObjectForHelp.CommandInfo -Full | Out-String } } $currentHelpContentLines = ($helpText | Get-SpectreEscapedText) -split "`r?`n" - if ($currentHelpContentLines.Count -eq 0) {$currentHelpContentLines = @("[grey](No content for this help type)[/]")} + if ($currentHelpContentLines.Count -eq 0 -or ($currentHelpContentLines.Count -eq 1 -and [string]::IsNullOrWhiteSpace($currentHelpContentLines[0]))) { + $currentHelpContentLines = @("[grey](No content for this help type)[/]") + } } catch { $currentHelpContentLines = @(("[red]Could not retrieve help: $($_.Exception.Message | Get-SpectreEscapedText)[/]" -split "`r?`n")) } } } - ([System.ConsoleKey]::LeftArrow) { + ([System.ConsoleKey]::LeftArrow) { # Go back to Description view $rightPaneView = 'Description' $currentCommandObjectForHelp = $null $currentHelpContentLines = @(); $helpContentScrollOffset = 0 } - ([System.ConsoleKey]::Enter) { # Mirror Right Arrow + ([System.ConsoleKey]::Enter) { # Same as RightArrow $selectedHelpType = $helpOptions[$currentHelpOptionIndex] - $currentHelpContent = "[grey]Fetching help...[/]" - $currentHelpContentLines = @() + $currentHelpContentLines = @("[grey]Fetching help...[/]") $helpContentScrollOffset = 0 - $rightPaneView = 'HelpContent' - $LiveContext.Refresh() - - if ($selectedHelpType -eq "Online") { - $currentHelpContent = "[yellow]Press Right Arrow or Enter to open online help (if available), or Left Arrow to go back.[/]" - $currentHelpContentLines = @($currentHelpContent.ToString()) + + if ($selectedHelpType -eq "Parameters") { + $allParams = $currentCommandObjectForHelp.CommandInfo.Parameters.Values + $nonCommonParams = $allParams | Where-Object { $commonParameterNames -notcontains $_.Name } | Sort-Object Name + $commonParamsFromCmd = $allParams | Where-Object { $commonParameterNames -contains $_.Name } | Sort-Object Name + $commandParametersForHelp = $nonCommonParams + $commonParamsFromCmd + + $currentParameterIndex = 0 + $parameterListScrollOffset = 0 + $rightPaneView = 'ParameterList' + } elseif ($selectedHelpType -eq "Online") { + $currentHelpContentLines = @("[yellow]Press Right Arrow or Enter to open online help (if available), or Left Arrow to go back.[/]") + $rightPaneView = 'HelpContent' } else { + $rightPaneView = 'HelpContent' + $LiveContext.Refresh() try { $helpText = "" switch($selectedHelpType) { - # "Synopsis" { $helpText = Get-Help $currentCommandObjectForHelp.CommandInfo | Out-String } "Examples" { $helpText = Get-Help $currentCommandObjectForHelp.CommandInfo -Examples | Out-String } "Detailed" { $helpText = Get-Help $currentCommandObjectForHelp.CommandInfo -Detailed | Out-String } "Full" { $helpText = Get-Help $currentCommandObjectForHelp.CommandInfo -Full | Out-String } } $currentHelpContentLines = ($helpText | Get-SpectreEscapedText) -split "`r?`n" - if ($currentHelpContentLines.Count -eq 0) {$currentHelpContentLines = @("[grey](No content for this help type)[/]")} + if ($currentHelpContentLines.Count -eq 0 -or ($currentHelpContentLines.Count -eq 1 -and [string]::IsNullOrWhiteSpace($currentHelpContentLines[0]))) { + $currentHelpContentLines = @("[grey](No content for this help type)[/]") + } } catch { $currentHelpContentLines = @(("[red]Could not retrieve help: $($_.Exception.Message | Get-SpectreEscapedText)[/]" -split "`r?`n")) } } } } - } elseif ($rightPaneView -eq 'HelpContent') { + } elseif ($rightPaneView -eq 'ParameterList') { switch ($keyInfo.Key) { - ([System.ConsoleKey]::LeftArrow) { - $rightPaneView = 'HelpOptions' - $currentHelpContentLines = @(); $helpContentScrollOffset = 0 + ([System.ConsoleKey]::UpArrow) { + if ($currentParameterIndex -gt 0) { + $currentParameterIndex-- + if ($currentParameterIndex -lt $parameterListScrollOffset) { + $parameterListScrollOffset = $currentParameterIndex + } + } + } + ([System.ConsoleKey]::DownArrow) { + if ($commandParametersForHelp.Count -gt 0 -and $currentParameterIndex -lt ($commandParametersForHelp.Count - 1)) { + $currentParameterIndex++ + if ($currentParameterIndex -ge ($parameterListScrollOffset + $parameterListPageSize)) { + $parameterListScrollOffset++ + } + } } ([System.ConsoleKey]::RightArrow) { - if ($helpOptions[$currentHelpOptionIndex] -eq "Online") { - try { Get-Help $currentCommandObjectForHelp.CommandInfo -Online + if ($commandParametersForHelp.Count -gt 0 -and $currentParameterIndex -ge 0 -and $currentParameterIndex -lt $commandParametersForHelp.Count) { + $currentParameterObjectForHelp = $commandParametersForHelp[$currentParameterIndex] # This is ParameterMetadata + $currentHelpContentLines = @("[grey]Fetching parameter help...[/]") + $helpContentScrollOffset = 0 + $rightPaneView = 'ParameterHelpContent' + $LiveContext.Refresh() + try { + $paramHelpText = Get-Help $currentCommandObjectForHelp.Name -Parameter $currentParameterObjectForHelp.Name | Out-String + if ([string]::IsNullOrWhiteSpace($paramHelpText) -and $currentParameterObjectForHelp.HelpMessage) { # Fallback + $paramHelpText = $currentParameterObjectForHelp.HelpMessage + } + + if (-not [string]::IsNullOrWhiteSpace($paramHelpText)) { + $currentHelpContentLines = ($paramHelpText | Get-SpectreEscapedText) -split "`r?`n" + } else { + $currentHelpContentLines = @("[grey](No specific help message found for this parameter.)[/]") + } } catch { - $currentHelpContentLines = "[red]Could not retrieve online help[/]" + $currentHelpContentLines = @(("[red]Could not retrieve help for parameter '$($currentParameterObjectForHelp.Name)': $($_.Exception.Message | Get-SpectreEscapedText)[/]" -split "`r?`n")) } - $rightPaneView = 'HelpOptions' - $currentHelpContentLines = @(); $helpContentScrollOffset = 0 } } - ([System.ConsoleKey]::Enter) { - if ($helpOptions[$currentHelpOptionIndex] -eq "Online") { - try { Get-Help $currentCommandObjectForHelp.CommandInfo -Online - } - catch { - $currentHelpContentLines = "[red]Could not retrieve online help[/]" + ([System.ConsoleKey]::LeftArrow) { # Go back to Help Options + $rightPaneView = 'HelpOptions' + $commandParametersForHelp = @() + $currentParameterObjectForHelp = $null + } + ([System.ConsoleKey]::Enter) { # Same as RightArrow + if ($commandParametersForHelp.Count -gt 0 -and $currentParameterIndex -ge 0 -and $currentParameterIndex -lt $commandParametersForHelp.Count) { + $currentParameterObjectForHelp = $commandParametersForHelp[$currentParameterIndex] + $currentHelpContentLines = @("[grey]Fetching parameter help...[/]") + $helpContentScrollOffset = 0 + $rightPaneView = 'ParameterHelpContent' + $LiveContext.Refresh() + try { + $paramHelpText = Get-Help $currentCommandObjectForHelp.Name -Parameter $currentParameterObjectForHelp.Name | Out-String + if ([string]::IsNullOrWhiteSpace($paramHelpText) -and $currentParameterObjectForHelp.HelpMessage) { + $paramHelpText = $currentParameterObjectForHelp.HelpMessage + } + if (-not [string]::IsNullOrWhiteSpace($paramHelpText)) { + $currentHelpContentLines = ($paramHelpText | Get-SpectreEscapedText) -split "`r?`n" + } else { + $currentHelpContentLines = @("[grey](No specific help message found for this parameter.)[/]") + } + } catch { + $currentHelpContentLines = @(("[red]Could not retrieve help for parameter '$($currentParameterObjectForHelp.Name)': $($_.Exception.Message | Get-SpectreEscapedText)[/]" -split "`r?`n")) } + } + } + } + } elseif ($rightPaneView -eq 'HelpContent' -or $rightPaneView -eq 'ParameterHelpContent') { + switch ($keyInfo.Key) { + ([System.ConsoleKey]::LeftArrow) { # Go back to previous view + if ($rightPaneView -eq 'ParameterHelpContent') { + $rightPaneView = 'ParameterList' + } else { # HelpContent $rightPaneView = 'HelpOptions' - $currentHelpContentLines = @(); $helpContentScrollOffset = 0 } + $currentHelpContentLines = @(); $helpContentScrollOffset = 0 # Clear content } - ([System.ConsoleKey]::UpArrow) { + ([System.ConsoleKey]::RightArrow) { # Only for Online help + if ($rightPaneView -eq 'HelpContent' -and $helpOptions[$currentHelpOptionIndex] -eq "Online") { + try { Get-Help $currentCommandObjectForHelp.CommandInfo -Online } + catch { $currentHelpContentLines = @("[red]Could not retrieve online help. Press Left to go back.[/]") } + # Don't automatically go back, let user see message if it fails. + } + } + ([System.ConsoleKey]::Enter) { # Only for Online help + if ($rightPaneView -eq 'HelpContent' -and $helpOptions[$currentHelpOptionIndex] -eq "Online") { + try { Get-Help $currentCommandObjectForHelp.CommandInfo -Online } + catch { $currentHelpContentLines = @("[red]Could not retrieve online help. Press Left to go back.[/]") } + } + } + ([System.ConsoleKey]::UpArrow) { # Scroll up if ($helpContentScrollOffset -gt 0) { $helpContentScrollOffset-- } } - ([System.ConsoleKey]::DownArrow) { + ([System.ConsoleKey]::DownArrow) { # Scroll down if (($helpContentScrollOffset + $helpContentPageSize) -lt $currentHelpContentLines.Count) { $helpContentScrollOffset++ } } } } - } # End while + } # End while ($true) } catch { + # Catch any unexpected errors during the live display Write-SpectreHost "[bold red]Error within Invoke-SpectreLive: $($_.Exception.ToString() | Get-SpectreEscapedText)[/]" Read-SpectrePause -Message "[grey]Press Enter to acknowledge error and return...[/]" -NoNewline return $null } + # This return should ideally not be reached if Escape is the main exit. return $null - } # End Spectre Live session + } # End Invoke-SpectreLive ScriptBlock - Clear-Host + Clear-Host # Clean up the console after exiting the live display } \ No newline at end of file