pure-pwsh.psm1
$Global:log = @('Started') filter color {$_.Split('*')[0]} # the part from '*' is only for `$pure` display function asyncGitFetch() { if ($gitStatus = Get-GitStatus) { if (Get-Job Pure__* |? PSBeginTime -ge ((Get-Date).AddSeconds(-10))) { return } else { Get-Job Pure__* |? State -eq Completed | Remove-Job Get-Job Pure__* |? State -eq Stopped | Remove-Job } # get the before fetch state $currentHead = cat "$($gitStatus.GitDir)/FETCH_HEAD" $job = Start-Job -Name "Pure__GitFetch"-ScriptBlock { param($gitDir, $currentHead) git -C $gitDir fetch; $newHead = cat "$gitDir/FETCH_HEAD" Write-Verbose "Old: $currentHead `nNew: $newHead" $newHead -and ($newHead -ne $currentHead) } -ArgumentList $gitStatus.GitDir, $currentHead $name = "Pure__PostFetch_$([Guid]::NewGuid())" $null = Register-ObjectEvent $job -EventName StateChanged -MessageData $job.Id ` -SourceIdentifier $name -MaxTriggerCount 1 -Action { if ($sender.State -eq 'Completed') { $Global:log += 'status received' $hasChanged = Receive-Job -Id $event.MessageData -Keep if ($hasChanged) { $Global:log += 'updating promt' [Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt() } } } } } function global:prompt { $isError = !$? asyncGitFetch $curPath = $ExecutionContext.SessionState.Path.CurrentLocation.Path if ($curPath.ToLower().StartsWith($Home.ToLower())) { $curPath = "~" + $curPath.SubString($Home.Length) } $prompt = "`n$($pure.pwdColor | color)$curPath " $gitStatus = if ($null -ne (Get-Module posh-git)) {get-gitstatus} else {$null} if ($gitStatus) { $prompt += "$($pure.branchColor | color)$($gitStatus.branch)" if ($gitStatus.HasWorking -or $gitStatus.HasIndex) { $prompt += "*" } $prompt += " " if ($gitStatus.BehindBy) { $prompt += "$($pure.remoteColor | color)$($pure.downChar)" } if ($gitStatus.AheadBy) { $prompt += "$($pure.remoteColor | color)$($pure.upChar)" } } if ($lastCmd = Get-History -Count 1) { $diff = $lastCmd.EndExecutionTime - $lastCmd.StartExecutionTime if ($diff.TotalSeconds -gt 2) { $prompt += "$($pure.errorColor | color) ($("{0:f2}" -f $diff.TotalSeconds)s)" } } $promptColor = if ($isError) {$pure.errorColor} else {$pure.PromptColor} $prompt += "`n$($promptColor | color)$($pure.PromptChar) " $prompt } function Set-PureOption() { [CmdletBinding()] param ( [ValidateSet( 'PwdColor', 'BranchColor', 'RemoteColor', 'ErrorColor', 'PromptColor', 'PromptChar', 'UpChar', 'DownChar')] $Option, [String] $Value ) if ($Option -like '*Color') { $val = if ($Value -match '^\d*m$') {$null} else {$Value} $Value = valueOrDefault $val $Value } $Global:pure.$option = $value } function valueOrDefault($value, $default) { "$(if ($value) {$value} else {"$([char]27)[$default"})" + "*$([char]27)[0m" } function init() { $psrOptions = Get-PSReadlineOption if ($psrOptions) { Set-PSReadLineOption -PromptText ("{0} " -f $pure.PromptChar) Set-PSReadLineOption -ContinuationPrompt ("{0}{0} " -f $pure.PromptChar) Set-PSReadLineOption -Colors @{ ContinuationPrompt = $psrOptions.EmphasisColor } Set-PSReadLineOption -ExtraPromptLineCount 2 } } $Global:pure = [ordered]@{ 'PwdColor' = valueOrDefault $psrOptions.CommentColor "32m" 'BranchColor' = valueOrDefault $psrOptions.StringColor "36m" 'RemoteColor' = valueOrDefault $psrOptions.TypeColor "37m" 'ErrorColor' = valueOrDefault $psrOptions.ErrorColor "91m" 'PromptColor' = valueOrDefault $psrOptions.EmphasisColor "96m" 'PromptChar' = '❯' 'UpChar' = '⇡' 'DownChar' = '⇣' } init |