mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Fix help paging issues on macOS/Linux and with custom pager that takes arguments (#9033)
* Pipe help system output through Out-String -Width when not using more This fixes #7175 by using Out-String to properly wrap text before sending to less or the user specified PAGER. * Set the string output width when sending help to pager app Fix #7175 * Fix #8912 by using PS tokenize to get custom pager cmd & args * Fix macOS/Linux test failures * It appears that while running in tests, ConsoleWidth is 0, set min val * Address PR feedback
This commit is contained in:
@@ -4176,40 +4176,61 @@ param(
|
||||
}
|
||||
elseif ($help -ne $null)
|
||||
{
|
||||
$customPagerCommand = """"
|
||||
$customPagerCommandArgs = """"
|
||||
$customPagerCommandLine = """"
|
||||
# By default use more on Windows and less on Linux.
|
||||
if ($IsWindows) {
|
||||
$pagerCommand = 'more.com'
|
||||
$pagerArgs = $null
|
||||
}
|
||||
else {
|
||||
$pagerCommand = 'less'
|
||||
$pagerArgs = '-Ps""Page %db?B of %D:.\. Press h for help or q to quit\.$""'
|
||||
}
|
||||
|
||||
if ($env:PAGER)
|
||||
{
|
||||
$customPagerCommandLine = $env:PAGER
|
||||
|
||||
# Split the command line into tokens, respecting quoting.
|
||||
$customPagerCommand, $customPagerCommandArgs = & { Write-Output -- $customPagerCommandLine }
|
||||
|
||||
# See if the first token refers to a known command (executable),
|
||||
# and if not, see if the command line as a whole is an executable path.
|
||||
$cmds = Get-Command $customPagerCommand, $customPagerCommandLine -ErrorAction Ignore
|
||||
if (-not $cmds) {
|
||||
# Custom command is invalid; ignore it, but issue a warning.
|
||||
Write-Warning ""Ignoring invalid custom-paging utility command line specified in `$env:PAGER: $customPagerCommandLine""
|
||||
$customPagerCommand = $null # use default command
|
||||
# Respect PAGER environment variable which allows user to specify a custom pager.
|
||||
# Ignore a pure whitespace PAGER value as that would cause the tokenizer to return 0 tokens.
|
||||
if (![string]::IsNullOrWhitespace($env:PAGER)) {
|
||||
if (Get-Command $env:PAGER -ErrorAction Ignore) {
|
||||
# Entire PAGER value corresponds to a single command.
|
||||
$pagerCommand = $env:PAGER
|
||||
$pagerArgs = $null
|
||||
}
|
||||
elseif ($cmds.Count -eq 1 -and $cmds[0].Source -eq $customPagerCommandLine) {
|
||||
# The full command line is an unquoted path to an existing executable
|
||||
# with embedded spaces.
|
||||
$customPagerCommand = $customPagerCommandLine
|
||||
$customPagerCommandArgs = $null
|
||||
else {
|
||||
# PAGER value is not a valid command, check if PAGER command and arguments have been specified.
|
||||
# Tokenize the specified $env:PAGER value. Ignore tokenizing errors since any errors may be valid
|
||||
# argument syntax for the paging utility.
|
||||
$errs = $null
|
||||
$tokens = [System.Management.Automation.PSParser]::Tokenize($env:PAGER, [ref]$errs)
|
||||
|
||||
$customPagerCommand = $tokens[0].Content
|
||||
if (!(Get-Command $customPagerCommand -ErrorAction Ignore)) {
|
||||
# Custom pager command is invalid, issue a warning.
|
||||
Write-Warning ""Custom-paging utility command not found. Ignoring command specified in `$env:PAGER: $env:PAGER""
|
||||
}
|
||||
else {
|
||||
# This approach will preserve all the pagers args.
|
||||
$pagerCommand = $customPagerCommand
|
||||
$pagerArgs = if ($tokens.Count -gt 1) {$env:PAGER.Substring($tokens[1].Start)} else {$null}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Respect PAGER, use more on Windows, and use less on Linux
|
||||
if ($customPagerCommand) {
|
||||
$help | & $customPagerCommand $customPagerCommandArgs
|
||||
} elseif ($IsWindows) {
|
||||
$help | more.com
|
||||
} else {
|
||||
$help | less -Ps""Page %db?B of %D:.\. Press h for help or q to quit\.$""
|
||||
# If the pager is an application, format the output width before sending to the app.
|
||||
if ((Get-Command $pagerCommand -ErrorAction Ignore).CommandType -eq 'Application') {
|
||||
$consoleWidth = [System.Math]::Max([System.Console]::WindowWidth, 20)
|
||||
|
||||
if ($pagerArgs) {
|
||||
# Supply pager arguments to an application without any PowerShell parsing of the arguments.
|
||||
# Leave environment variable to help user debug arguments supplied in $env:PAGER.
|
||||
$env:__PSPAGER_ARGS = $pagerArgs
|
||||
$help | Out-String -Stream -Width ($consoleWidth - 1) | & $pagerCommand --% %__PSPAGER_ARGS%
|
||||
}
|
||||
else {
|
||||
$help | Out-String -Stream -Width ($consoleWidth - 1) | & $pagerCommand
|
||||
}
|
||||
}
|
||||
else {
|
||||
# The pager command is a PowerShell function, script or alias, so pipe directly into it.
|
||||
$help | & $pagerCommand $pagerArgs
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
Reference in New Issue
Block a user