mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-12-27 11:59:40 -08:00
fix(pwsh): use more reliable native invocation
Rewrite logic of passing arguments in `Start-Utf8Process`: - Use ArgumentList in PowerShell 6.1 and later. - Use a manual escaping in lower versions.
This commit is contained in:
parent
07e0d0e0c6
commit
9606d5a105
|
@ -20,21 +20,40 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
||||||
function Start-Utf8Process {
|
function Start-Utf8Process {
|
||||||
param(
|
param(
|
||||||
[string] $FileName,
|
[string] $FileName,
|
||||||
[string] $Arguments
|
[string[]] $Arguments = @()
|
||||||
)
|
)
|
||||||
|
|
||||||
$Process = New-Object System.Diagnostics.Process
|
$Process = New-Object System.Diagnostics.Process
|
||||||
$StartInfo = $Process.StartInfo
|
$StartInfo = $Process.StartInfo
|
||||||
|
$StartInfo.FileName = $FileName
|
||||||
|
if ($StartInfo.ArgumentList.Add) {
|
||||||
|
# ArgumentList is supported in PowerShell 6.1 and later (built on .NET Core 2.1+)
|
||||||
|
# ref-1: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.argumentlist?view=net-6.0
|
||||||
|
# ref-2: https://docs.microsoft.com/en-us/powershell/scripting/whats-new/differences-from-windows-powershell?view=powershell-7.2#net-framework-vs-net-core
|
||||||
|
$Arguments | ForEach-Object -Process { $StartInfo.ArgumentList.Add($_) }
|
||||||
|
} else {
|
||||||
|
# escape arguments manually in lower versions, refer to https://docs.microsoft.com/en-us/previous-versions/17w5ykft(v=vs.85)
|
||||||
|
$escapedArgs = $Arguments | ForEach-Object {
|
||||||
|
# escape N consecutive backslash(es), which are followed by a double quote, to 2N consecutive ones
|
||||||
|
$s = $_ -replace '(\\+)"', '$1$1"'
|
||||||
|
# escape N consecutive backslash(es), which are at the end of the string, to 2N consecutive ones
|
||||||
|
$s = $s -replace '(\\+)$', '$1$1'
|
||||||
|
# escape double quotes
|
||||||
|
$s = $s -replace '"', '\"'
|
||||||
|
# quote the argument
|
||||||
|
"`"$s`""
|
||||||
|
}
|
||||||
|
$StartInfo.Arguments = $escapedArgs -join ' '
|
||||||
|
}
|
||||||
$StartInfo.StandardErrorEncoding = $StartInfo.StandardOutputEncoding = [System.Text.Encoding]::UTF8
|
$StartInfo.StandardErrorEncoding = $StartInfo.StandardOutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
$StartInfo.RedirectStandardError = $StartInfo.RedirectStandardInput = $StartInfo.RedirectStandardOutput = $true
|
$StartInfo.RedirectStandardError = $StartInfo.RedirectStandardInput = $StartInfo.RedirectStandardOutput = $true
|
||||||
$StartInfo.FileName = $Filename
|
|
||||||
$StartInfo.Arguments = $Arguments
|
|
||||||
$StartInfo.UseShellExecute = $false
|
$StartInfo.UseShellExecute = $false
|
||||||
if ($PWD.Provider.Name -eq 'FileSystem') {
|
if ($PWD.Provider.Name -eq 'FileSystem') {
|
||||||
$StartInfo.WorkingDirectory = $PWD.ProviderPath
|
$StartInfo.WorkingDirectory = $PWD.ProviderPath
|
||||||
}
|
}
|
||||||
$StartInfo.CreateNoWindow = $true
|
$StartInfo.CreateNoWindow = $true
|
||||||
[void]$Process.Start()
|
[void]$Process.Start()
|
||||||
|
# we do this to remove a deadlock potential on Windows
|
||||||
$stdoutTask = $Process.StandardOutput.ReadToEndAsync()
|
$stdoutTask = $Process.StandardOutput.ReadToEndAsync()
|
||||||
$stderrTask = $Process.StandardError.ReadToEndAsync()
|
$stderrTask = $Process.StandardError.ReadToEndAsync()
|
||||||
[void]$Process.WaitForExit()
|
[void]$Process.WaitForExit()
|
||||||
|
@ -70,7 +89,7 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
||||||
$cursor = $null
|
$cursor = $null
|
||||||
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$command, [ref]$cursor)
|
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$command, [ref]$cursor)
|
||||||
$command = ($command -split " ")[0]
|
$command = ($command -split " ")[0]
|
||||||
$standardOut = @(Start-Utf8Process $script:OMPExecutable "print tooltip --pwd=""$cleanPWD"" --pswd=""$cleanPSWD"" --config=""$env:POSH_THEME"" --command=""$command"" --shell-version=""$script:PSVersion""")
|
$standardOut = @(Start-Utf8Process $script:OMPExecutable @("print", "tooltip", "--pwd=$cleanPWD", "--pswd=$cleanPSWD", "--config=$env:POSH_THEME", "--command=$command", "--shell-version=$script:PSVersion"))
|
||||||
Write-Host $standardOut -NoNewline
|
Write-Host $standardOut -NoNewline
|
||||||
$host.UI.RawUI.CursorPosition = $position
|
$host.UI.RawUI.CursorPosition = $position
|
||||||
}
|
}
|
||||||
|
@ -91,8 +110,8 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
function Enable-PoshLineError {
|
function Enable-PoshLineError {
|
||||||
$validLine = @(Start-Utf8Process $script:OMPExecutable "print valid --config=""$env:POSH_THEME""") -join "`n"
|
$validLine = @(Start-Utf8Process $script:OMPExecutable @("print", "valid", "--config=$env:POSH_THEME")) -join "`n"
|
||||||
$errorLine = @(Start-Utf8Process $script:OMPExecutable "print error --config=""$env:POSH_THEME""") -join "`n"
|
$errorLine = @(Start-Utf8Process $script:OMPExecutable @("print", "error", "--config=$env:POSH_THEME")) -join "`n"
|
||||||
Set-PSReadLineOption -PromptText $validLine, $errorLine
|
Set-PSReadLineOption -PromptText $validLine, $errorLine
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +150,7 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
||||||
$Format = 'json'
|
$Format = 'json'
|
||||||
)
|
)
|
||||||
|
|
||||||
$configString = @(Start-Utf8Process $script:OMPExecutable "config export --config=""$env:POSH_THEME"" --format=$Format")
|
$configString = @(Start-Utf8Process $script:OMPExecutable @("config", "export", "--config=$env:POSH_THEME", "--format=$Format"))
|
||||||
# if no path, copy to clipboard by default
|
# if no path, copy to clipboard by default
|
||||||
if ('' -ne $FilePath) {
|
if ('' -ne $FilePath) {
|
||||||
# https://stackoverflow.com/questions/3038337/powershell-resolve-path-that-might-not-exist
|
# https://stackoverflow.com/questions/3038337/powershell-resolve-path-that-might-not-exist
|
||||||
|
@ -198,7 +217,7 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
||||||
} else {
|
} else {
|
||||||
$themes | ForEach-Object -Process {
|
$themes | ForEach-Object -Process {
|
||||||
Write-Host "Theme: $(Get-FileHyperlink -uri $_.FullName -Name ($_.BaseName -replace '\.omp$', ''))`n"
|
Write-Host "Theme: $(Get-FileHyperlink -uri $_.FullName -Name ($_.BaseName -replace '\.omp$', ''))`n"
|
||||||
@(Start-Utf8Process $script:OMPExecutable "print primary --config=""$($_.FullName)"" --pwd=""$PWD"" --shell pwsh")
|
@(Start-Utf8Process $script:OMPExecutable @("print", "primary", "--config=$($_.FullName)", "--pwd=$PWD", "--shell=pwsh"))
|
||||||
Write-Host "`n"
|
Write-Host "`n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,12 +239,12 @@ Example:
|
||||||
$realLASTEXITCODE = $global:LASTEXITCODE
|
$realLASTEXITCODE = $global:LASTEXITCODE
|
||||||
$cleanPWD, $cleanPSWD = Get-PoshContext
|
$cleanPWD, $cleanPSWD = Get-PoshContext
|
||||||
if ($script:TransientPrompt -eq $true) {
|
if ($script:TransientPrompt -eq $true) {
|
||||||
@(Start-Utf8Process $script:OMPExecutable "print transient --error=$script:ErrorCode --pwd=""$cleanPWD"" --pswd=""$cleanPSWD"" --execution-time=$script:ExecutionTime --config=""$env:POSH_THEME"" --shell-version=""$script:PSVersion""") -join "`n"
|
@(Start-Utf8Process $script:OMPExecutable @("print", "transient", "--error=$script:ErrorCode", "--pwd=$cleanPWD", "--pswd=$cleanPSWD", "--execution-time=$script:ExecutionTime", "--config=$env:POSH_THEME", "--shell-version=$script:PSVersion")) -join "`n"
|
||||||
$script:TransientPrompt = $false
|
$script:TransientPrompt = $false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (Test-Path variable:/PSDebugContext) {
|
if (Test-Path variable:/PSDebugContext) {
|
||||||
@(Start-Utf8Process $script:OMPExecutable "print debug --pwd=""$cleanPWD"" --pswd=""$cleanPSWD"" --config=""$env:POSH_THEME""") -join "`n"
|
@(Start-Utf8Process $script:OMPExecutable @("print", "debug", "--pwd=$cleanPWD", "--pswd=$cleanPSWD", "--config=$env:POSH_THEME")) -join "`n"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Initialize-ModuleSupport
|
Initialize-ModuleSupport
|
||||||
|
@ -261,7 +280,7 @@ Example:
|
||||||
|
|
||||||
Set-PoshContext
|
Set-PoshContext
|
||||||
$terminalWidth = $Host.UI.RawUI.WindowSize.Width
|
$terminalWidth = $Host.UI.RawUI.WindowSize.Width
|
||||||
$standardOut = @(Start-Utf8Process $script:OMPExecutable "print primary --error=$script:ErrorCode --pwd=""$cleanPWD"" --pswd=""$cleanPSWD"" --execution-time=$script:ExecutionTime --stack-count=$stackCount --config=""$env:POSH_THEME"" --shell-version=""$script:PSVersion"" --terminal-width=$terminalWidth")
|
$standardOut = @(Start-Utf8Process $script:OMPExecutable @("print", "primary", "--error=$script:ErrorCode", "--pwd=$cleanPWD", "--pswd=$cleanPSWD", "--execution-time=$script:ExecutionTime", "--stack-count=$stackCount", "--config=$env:POSH_THEME", "--shell-version=$script:PSVersion", "--terminal-width=$terminalWidth"))
|
||||||
# make sure PSReadLine knows we have a multiline prompt
|
# make sure PSReadLine knows we have a multiline prompt
|
||||||
$extraLines = ($standardOut | Measure-Object -Line).Lines - 1
|
$extraLines = ($standardOut | Measure-Object -Line).Lines - 1
|
||||||
if ($extraLines -gt 0) {
|
if ($extraLines -gt 0) {
|
||||||
|
@ -273,7 +292,7 @@ Example:
|
||||||
}
|
}
|
||||||
|
|
||||||
# set secondary prompt
|
# set secondary prompt
|
||||||
Set-PSReadLineOption -ContinuationPrompt (@(Start-Utf8Process $script:OMPExecutable "print secondary --config=""$env:POSH_THEME""") -join "`n")
|
Set-PSReadLineOption -ContinuationPrompt (@(Start-Utf8Process $script:OMPExecutable @("print", "secondary", "--config=$env:POSH_THEME")) -join "`n")
|
||||||
|
|
||||||
Export-ModuleMember -Function @(
|
Export-ModuleMember -Function @(
|
||||||
"Set-PoshContext"
|
"Set-PoshContext"
|
||||||
|
|
Loading…
Reference in a new issue