Skip to content

Commit

Permalink
Add RepeatPrompt instead of NoCache or Transient
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaykul committed Aug 16, 2023
1 parent eb99667 commit e3523db
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 106 deletions.
17 changes: 8 additions & 9 deletions Source/Classes/PowerLineTheme.ps1
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
using namespace PoshCode
class PowerLineTheme {
[TerminalBlock[]]$Prompt
[BlockCaps]$DefaultCaps
[string]$DefaultSeparator
[TerminalBlock[]]$Prompt
[scriptblock]$Title
[bool]$SetCurrentDirectory
[bool]$HideErrors
[string]$RepeatPrompt
[RgbColor[]]$PSReadLineErrorColor
[string]$PSReadLineContinuationPrompt
[string]$PSReadLineContinuationPromptColor
[string[]]$PSReadLinePromptText
[bool]$SetCurrentDirectory
[bool]$HideErrors
[bool]$SimpleTransient
[bool]$NoCache
[scriptblock]$Title
[int]$DefaultAddIndex = -1
}

Expand All @@ -23,10 +23,9 @@ Add-MetadataConverter @{
)
PSReadLineContinuationPrompt = '$($_.PSReadLineContinuationPrompt)'
PSReadLineContinuationPromptColor = '$($_.PSReadLineContinuationPromptColor)'
PSReadLinePromptText = '$($_.PSReadLinePromptText -join "','")'
PSReadLineErrorColor = '$($_.PSReadLineErrorColor -join "','")'
HideErrors = $(if ($_.HideErrors) { '$true' } else { '$false' })
SimpleTransient = $(if ($_.SimpleTransient) { '$true' } else { '$false' })
NoCache = $(if ($_.NoCache) { '$true' } else { '$false' })
RepeatPrompt = '$(if ($_.RepeatPrompt) { $_.RepeatPrompt } else { 'CachedPrompt' })'
SetCurrentDirectory = $(if ($_.SetCurrentDirectory) { '$true' } else { '$false' })$(
if (![string]::IsNullOrWhiteSpace($_.Title)) {
"`n Title = ScriptBlock @'`n$($_.Title)`n'@"
Expand Down
2 changes: 1 addition & 1 deletion Source/Configuration.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ PSObject @{
)
PSReadLineContinuationPrompt = ''
PSReadLineContinuationPromptColor = ''
PSReadLinePromptText = '[48;2;99;184;255m[38;2;255;255;255m[49m[38;2;99;184;255m[0m','[48;2;139;34;82m[38;2;255;255;255m[49m[38;2;139;34;82m[0m'
PSReadLineErrorColor = 'Tomato'
SetCurrentDirectory = $false
}
61 changes: 29 additions & 32 deletions Source/Examples/BackgroundData.ps1
Original file line number Diff line number Diff line change
@@ -1,49 +1,46 @@
#requires -module @{ModuleName='PowerLine';ModuleVersion='3.4.0'}
# If this is re-run, clear up the old job:
Get-Job -Name WeatherQuery -EA 0 | Stop-Job -PassThru | Remove-Job
$global:WeatherJob = Start-ThreadJob -Name WeatherQuery {

# If this is re-run, clear up the old job, and start a new one
Get-Job -Name WeatherQuery -ErrorAction Ignore | Stop-Job -PassThru | Remove-Job
$null = Start-ThreadJob -Name WeatherQuery {
while ($true) {
Invoke-RestMethod "wttr.in?format=%c%t"
(Invoke-RestMethod "wttr.in?format=%c%t") -replace " +", " "
Start-Sleep 300 # This job will update the weather every 5 minutes
}
}

Set-PowerLinePrompt -SetCurrentDirectory -PowerLineFont -SimpleTransient -Title {
$ContinuationPromptColor = [RgbColor]"DeepSkyBlue"

Set-PSReadLineOption -ContinuationPrompt █ -Colors @{ ContinuationPrompt = $ContinuationPromptColor.ToVt() }

Set-PowerLinePrompt -SetCurrentDirectory -PowerLineFont -RepeatPrompt LastLine -PSReadlineErrorColor Tomato -Title {
-join @(
if (Test-Elevation) { "Admin: " }
"PS" + $PSVersionTable.PSVersion.Major + " "
Convert-Path $pwd
)
} -Prompt @(
Show-ElapsedTime -Autoformat -BackgroundColor 00688B -ForegroundColor White
Show-ElapsedTime -Autoformat -Bg White -Fg Black -Prefix "" -Caps '',''
New-TerminalBlock -Newline
New-TerminalBlock {
# Consume the output of the job:
# In this case, I only want the most recent output, so [-1]
$global:WeatherJob.Output[-1]
} -BackgroundColor 00BFFF -ForegroundColor Black
Show-NestedPromptLevel -RepeatCharacter "&Gear;" -Postfix " " -BackgroundColor 473C8B -ForegroundColor White
Show-Path -HomeString "&House;" -Separator '' -Bg B23AEE -Fg White
Show-PoshGitStatus -Bg Gray30

Show-Date -Format "h\:mm" -Bg DeepSkyBlue -Fg Black
Show-JobOutput -Name WeatherQuery -Bg DeepSkyBlue3 -Fg Black
Show-NestedPromptLevel -RepeatCharacter "&Gear;" -Postfix " " -Bg DeepSkyBlue4 -Fg White
New-TerminalBlock -Spacer
Show-Date -Bg 7D26CD

Show-PoshGitStatus -Bg Gray30
Show-Path -HomeString "&House;" -Separator '' -Bg SkyBlue4 -Fg White
New-TerminalBlock -Newline

# This is basically Show-HistoryId, but I want to use it as the last part of my prompt, and have PSReadLine updated.
New-TerminalBlock {
# In order for PSReadLine to work properly, it needs the $PromptText set to match the end of my prompt...
$MyInvocation.HistoryId

# Because I don't have a "Write-TerminalBlock" I am doing all this by hand:This is
# Need to draw ">ID>" but the > each have to be FOREGROUND = the BACKGROUND of the previous block
# AND the color changes depending on whether nestedPrompt rendered or not
[string]$CS = [PoshCode.Pansies.Entities]::ExtendedCharacters["ColorSeparator"]
$thisBg = $NestedPromptLevel ? $bg:SteelBlue2 : $bg:SkyBlue2
$previousFg = $NestedPromptLevel ? $fg:SkyBlue2 : $fg:DeepSkyBlue2
$thisFg = $NestedPromptLevel ? $fg:SteelBlue2 : $fg:SkyBlue2

Set-PSReadlineOption -PromptText @(
($thisBg + $previousFg + $CS + $fg:white + $MyInvocation.HistoryId + $thisFg + $bg:clear + $CS)
($bg:Gray44 + $previousFg + $CS + $fg:white + $MyInvocation.HistoryId + $fg:Gray44 + $bg:clear + $CS)
)
} -BackgroundColor SteelBlue2 -ForegroundColor Black
# New-TerminalBlock {
# # In order for PSReadLine to work properly, it needs the $PromptText set to match the end of my prompt...
# $ContinuationPromptColor = (Get-PSReadLineOption).ContinuationPromptColor
# $fg:Black + ($ContinuationPromptColor -replace "\[3","[4") + "&ColorSeparator;" + $ContinuationPromptColor + $bg:LightSkyBlue + "&ColorSeparator;" + $Fg:Black + $MyInvocation.HistoryId

# } -BackgroundColor LightSkyBlue -ForegroundColor Black
# New-TerminalBlock -Spacer
New-TerminalBlock -Content "&ColorSeparator;" -Background $ContinuationPromptColor -Foreground Black
Show-HistoryId -Bg LightSkyBlue -Fg Black
)

6 changes: 2 additions & 4 deletions Source/Examples/ConvertFrom-Metadata.ps1
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
ConvertFrom-Metadata @'
(PowerLineTheme @{
(PSObject @{
DefaultCaps = '', ''
DefaultSeparator = ''
Prompt = @(
Expand All @@ -18,10 +18,8 @@ ConvertFrom-Metadata @'
)
PSReadLineContinuationPrompt = '▌ '
PSReadLineContinuationPromptColor = ''
PSReadLinePromptText = '',''
HideErrors = $false
SimpleTransient = $false
NoCache = $false
RepeatPrompt = 'LastLine'
SetCurrentDirectory = $false
})
'@ | Set-PowerLinePrompt
2 changes: 1 addition & 1 deletion Source/Examples/Darkly.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ Set-PowerLinePrompt -SetCurrentDirectory -DefaultSeparator "$([char]0xE0B1)" -De
Show-Date -Format "h\:mm" -Prefix "🕒" -Background 'Gray23'
Show-ElapsedTime -Autoformat -Prefix "⏱️" -Background 'Gray47'
New-TerminalBlock -DFg 'White' -DBg '#63B8FF' -EFg 'White' -Cap '‍' -Content ''
) -Verbose -PSReadLineContinuationPrompt '' -PSReadLineContinuationPromptColor '[38;2;99;184;255m' -PSReadLinePromptText '[48;2;99;184;255m[38;2;255;255;255m[49m[38;2;99;184;255m[0m','[48;2;139;34;82m[38;2;255;255;255m[49m[38;2;139;34;82m[0m'
) -Verbose -PSReadLineContinuationPrompt '' -PSReadLineContinuationPromptColor '[38;2;99;184;255m'
20 changes: 8 additions & 12 deletions Source/Examples/UsingPoshGit.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@ Set-PowerLinePrompt -SetCurrentDirectory -PowerLineFont -Title {
Convert-Path $pwd
)
} -Prompt @(
{ New-TerminalBlock -Fg Gray95 -Bg Gray20 -EBg VioletRed4 $MyInvocation.HistoryId }
{ Show-ElapsedTime -Trim } # only shows the minimum portion of elapsed time necessary
{ Get-Date -f "HH:mm" } # 24-hour format
{ Write-VcsStatus }
{ Get-SegmentedPath }
{ "`n" }
{ New-TerminalBlock -Fg Gray95 -Bg Gray40 "I ${Fg:Green}♥${Fg:Gray95} PS" }
) -PSReadLinePromptText @(
# Let PSReadLine use a red heart to let us know about syntax errors
New-TerminalBlock -Fg Gray95 -Bg Gray40 "I ${Fg:Green}♥${Fg:Gray95} PS${fg:Gray40}${bg:Clear}&ColorSeparator;"
New-TerminalBlock -Fg Gray95 -Bg Gray40 "I ${Fg:Red}♥${Fg:Gray95} PS${fg:Gray40}${bg:Clear}&ColorSeparator;"
) -Colors Gray54, Gray26
New-TerminalBlock -Fg Gray95 -Bg Gray20 -EBg VioletRed4 $MyInvocation.HistoryId
Show-ElapsedTime -Trim # only shows the minimum portion of elapsed time necessary
Show-Date -f "HH:mm" # 24-hour format
Show-PoshGitStatus
Show-Path
New-TerminalBlock -Newline
New-TerminalBlock -Fg Gray95 -Bg Gray40 "I ${Fg:Green}♥${Fg:Gray95} PS"
)
23 changes: 10 additions & 13 deletions Source/PowerLine.format.ps1xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,16 @@
<ScriptBlock>
$CurrentTheme = Get-PowerLineTheme
# temporarily change the theme so we can use our functions to _render_ this one:
$_ | Set-PowerLineTheme
"$( Write-PowerLinePrompt )`n`n$(
$PSRL = $_.PSReadLinePromptText
@(if ($PSRL.Count -ge 2) {
"PSReadLine PromptText:"
$PSRL[0] + "$([char]27)[0m'Normal Prompt'"
$PSRL[1] + "$([char]27)[0m'Incomplete"
}) -join "`n"
if ($_.PSReadLineContinuationPrompt) {
"`n" + $_.PSReadLineContinuationPromptColor + $_.PSReadLineContinuationPrompt + "$([char]27)[0mContinuation..."
}
)"
$CurrentTheme | Set-PowerLineTheme
try {
$_ | Set-PowerLineTheme
"$( Write-PowerLinePrompt )$(
if ($_.PSReadLineContinuationPrompt) {
"`n" + $_.PSReadLineContinuationPromptColor + $_.PSReadLineContinuationPrompt + "$([char]27)[0mContinuation..."
}
)"
} finally {
$CurrentTheme | Set-PowerLineTheme
}
</ScriptBlock>
</ExpressionBinding>
</CustomItem>
Expand Down
3 changes: 1 addition & 2 deletions Source/Public/Get-PowerLineTheme.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ function Get-PowerLineTheme {

if (Get-Command Get-PSReadLineOption) {
$PSReadLineOptions = Get-PSReadLineOption
# PromptText and ContinuationPrompt can have colors in them
$Configuration.PSReadLinePromptText = $PSReadLineOptions.PromptText
# ContinuationPrompt can have colors in them
$Configuration.PSReadLineContinuationPrompt = $PSReadLineOptions.ContinuationPrompt
# If the ContinuationPrompt has color in it, this is irrelevant, but keep it anyway
$Configuration.PSReadLineContinuationPromptColor = $PSReadLineOptions.ContinuationPromptColor
Expand Down
54 changes: 30 additions & 24 deletions Source/Public/Set-PowerLinePrompt.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@ function Set-PowerLinePrompt {
[Parameter(ParameterSetName = "PowerLine", Mandatory)]
[switch]$PowerLineFont,

# The cap character(s) that will be used (by default) on normal, left-aligned blocks
# PowerLine uses TerminalBlocks, and the DefaultCaps parameter sets [PoshCode.TerminalBlocks]::DefaultCaps
# These are the cap character(s) that will be used (by default) on blocks
# Pass two characters: the first for the left side, the second for the right side.
[Parameter(ParameterSetName = "Manual", ValueFromPipelineByPropertyName)]
[PoshCode.BlockCaps]$DefaultCaps,

# The Left pointing and Right pointing separator characters are used when a script-based PowerLine block outputs multiple objects
# Pass two strings. The first for blocks that are Left-aligned, the second for right-aligned blocks, like: "",""
# PowerLine uses TerminalBlocks, and the DefaultSeparator parameter sets [PoshCode.TerminalBlocks]::DefaultSeparator
# The separator character is used by some TerminalBlocks to separate multiple objects (like a path separator)
[Parameter(ParameterSetName = "Manual", ValueFromPipelineByPropertyName)]
[Alias("Separator")]
[string]$DefaultSeparator,
Expand Down Expand Up @@ -71,23 +72,26 @@ function Set-PowerLinePrompt {
[Parameter(ValueFromPipelineByPropertyName)]
[switch]$HideErrors,

# If set, when the prompt is run multiple times without a command (e.g. pressing enter repeatedly, or hitting Ctrl+C)
# The prompt will render only the PSReadlinePromptText, and not the full prompt
# How to render repeated prompts. A prompt is considered a repeat if it's run multiple times without a command,
# such as when pressing enter repeatedly, or hitting Ctrl+C or Ctrl+L (any time the $MyInvcation.HistoryId does not change)
#
# By default, PowerLine uses "CachedPrompt" which repeats the whole prompt, but doesn't re-run the prompt blocks.
#
# You can choose to render only the last block, or the last line of the prompt, or to Recalculate the whole prompt.
[Parameter(ValueFromPipelineByPropertyName)]
[switch]$SimpleTransient,

# If set, disables caching of output from the prompt blocks.
# Caching only affects blocks when you render the same prompt multiple times
# (i.e. pressing enter multiple times, or pressing Ctrl+C or Ctrl+L), but
# you may want to disable caching if you do that regularly and you have things
# in your prompt that change externally while you're not using your terminal, like the time, or git status, etc.
[switch]$NoCache,

# When there's a parse error, PSReadLine changes a part of the prompt...
# Use this option to override PSReadLine by either specifying the characters it should replace, or by specifying both the normal and error strings.
# If you specify two strings, they should both be the same length (ignoring escape sequences)
[ValidateSet("LastBlock", "LastLine", "CachedPrompt", "Recalculate")]
[string]$RepeatPrompt,

# When there's a parse error, PSReadLine changes a part of the prompt based on it's PromptText configuration.
# This setting causes PowerLine to update the PSReadLiine PromptText on each run.
#
# By default, if the last prompt block has a background color, it will be set to tomato red (otherwise, the foreground color)
# If you pass just one color, that color will be used instead of tomato red.
# If you pass a pair of colors, the first will be replaced with the second throughout the entire last line of the prompt
#
# To disable this feature, pass an empty array, and PowerLine will not change the PromptText
[Parameter(ValueFromPipelineByPropertyName)]
[string[]]$PSReadLinePromptText,
[RgbColor[]]$PSReadLineErrorColor,

# When you type a command that requires a second line (like if you type | and hit enter)
# This is the prompt text. Can be an empty string. Can be anything, really.
Expand All @@ -110,7 +114,7 @@ function Set-PowerLinePrompt {
}

# Switches have a (non-null) default value, so we need to set them in case they were not passed explicitly
$Configuration = Import-Configuration -ErrorAction SilentlyContinue| Update-Object @{
$Configuration = Import-Configuration -ErrorAction SilentlyContinue | Update-Object @{
HideErrors = $HideErrors
SetCurrentDirectory = $SetCurrentDirectory
}
Expand Down Expand Up @@ -181,7 +185,6 @@ function Set-PowerLinePrompt {

Write-Verbose "Setting global:Prompt"
# We want to support modifying the global:prompt variable outside this function
[System.Collections.Generic.List[PoshCode.TerminalBlock]]$global:Prompt = `
[PoshCode.TerminalBlock[]]$PowerLineConfig.Prompt = @(
if ($PSBoundParameters.ContainsKey("Prompt")) {
Write-Verbose "Setting global:Prompt from prompt parameter"
Expand Down Expand Up @@ -209,6 +212,13 @@ function Set-PowerLinePrompt {
$global:Prompt
}
)
if ($NoBackground) {
$PowerLineConfig.Prompt | ForEach-Object {
$_.BackgroundColor = $null
}
}

[System.Collections.Generic.List[PoshCode.TerminalBlock]]$global:Prompt = $PowerLineConfig.Prompt

if ($null -eq $PowerLineConfig.DefaultAddIndex) {
$PowerLineConfig.DefaultAddIndex = -1
Expand All @@ -218,10 +228,6 @@ function Set-PowerLinePrompt {

if (Get-Module PSReadLine) {
$Options = @{}
if ($PowerLineConfig.PSReadLinePromptText) {
$Options["PromptText"] = $PowerLineConfig.PSReadLinePromptText
}

if ($PowerLineConfig.PSReadLineContinuationPrompt) {
$Options["ContinuationPrompt"] = $PowerLineConfig.PSReadLineContinuationPrompt
}
Expand Down
35 changes: 27 additions & 8 deletions Source/Public/Write-PowerlinePrompt.ps1
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
function Write-PowerlinePrompt {
[CmdletBinding()]
[OutputType([string])]
param(
[switch]$NoCache
)
param()

try {
# Stuff these into static properties in case I want to use them from C#
Expand Down Expand Up @@ -33,14 +31,19 @@ function Write-PowerlinePrompt {
}
}

if ($Script:PowerLineConfig.SimpleTransient -and $MyInvocation.HistoryId -eq $Script:LastHistoryId) {
# if we're transient, and SimpleTransient, just output the last line
$LastLine = 1 + $Prompt.FindLastIndex([Predicate[PoshCode.TerminalBlock]] { $args[0].Content -eq "NewLine" })
$local:Prompt = $Prompt.GetRange($LastLine, $Prompt.Count - $LastLine)
if ($MyInvocation.HistoryId -eq $Script:LastHistoryId) {
if ($Script:PowerLineConfig.RepeatPrompt -eq "LastLine") {
# Repeat only the last line
$LastLine = 1 + $Prompt.FindLastIndex([Predicate[PoshCode.TerminalBlock]] { $args[0].Content -in "NewLine", "`n" })
$local:Prompt = $Prompt.GetRange($LastLine, $Prompt.Count - $LastLine)
} elseif ($Script:PowerLineConfig.RepeatPrompt -eq "LastBlock") {
# Repeat only the last block
$local:Prompt = $Prompt.GetRange($Prompt.Count - 1, 1)
}
}

$CacheKey = $Script:LastHistoryId = $MyInvocation.HistoryId
if ($NoCache -or $Script:PowerLineConfig.NoCache) {
if ($Script:PowerLineConfig.RepeatPrompt -eq "Recalculate") {
$CacheKey = $null
}

Expand Down Expand Up @@ -108,6 +111,22 @@ function Write-PowerlinePrompt {
$null = $builder.Append($Block.ToString($PreviousNeighbor.BackgroundColor, $NextNeighbor.BackgroundColor, $CacheKey))
}

if ($Colors = $PowerLineConfig.PSReadLineErrorColor) {
$DefaultColor, $Replacement = if ($Colors.Count -eq 1) {
$Prompt.BackgroundColor.Where({$_},"Last",1)
$Colors[0]
} else {
$Colors[0]
$Colors[-1]
}

$LastLine = $builder.ToString().Split("`n")[-1]
Set-PSReadLineOption -PromptText @(
$LastLine
$LastLine -replace ([regex]::escape($DefaultColor.ToVt())), $Replacement.ToVt() -replace ([regex]::escape($DefaultColor.ToVt($true))), $Replacement.ToVt($true)
)
}

# At the end, output everything that's left
$builder.ToString()
# Add-Content -Value "return prompt:`n$($Builder.ToString())" -Path $HOME\PowerLine.log
Expand Down

0 comments on commit e3523db

Please sign in to comment.