Created
November 28, 2019 08:13
-
-
Save bplasmeijer/40e61e55fa043be6a270df40fee7082e to your computer and use it in GitHub Desktop.
PowerShell Core custom prompt (use a PowerLine or nerdfonts.com font) and history persistence per machine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#requires -Version 6 | |
function Get-BranchName | |
{ | |
$currentPath = Get-Location | |
while ($true) | |
{ | |
try | |
{ | |
if ([string]::IsNullOrEmpty($currentPath)) | |
{ | |
return | |
} | |
$git = (Join-Path $currentPath "\.git") | |
if (Test-Path $git) | |
{ | |
$head = (Get-Content (Join-Path $git "\HEAD") | Out-String).Trim().Replace("ref: refs/heads/", "") | |
if ([string]::IsNullOrEmpty($head)) | |
{ | |
return | |
} | |
return $head | |
} | |
$currentPath = Split-Path $currentPath | |
} | |
catch | |
{ | |
throw "GetBranchName failed..." | |
return | |
} | |
} | |
} | |
function Write-AnsiVT100 | |
{ | |
param( | |
[Parameter(Mandatory = $true)] | |
[ValidateNotNull()] | |
[string]$Message | |
, | |
[Parameter(Mandatory = $false)] | |
[ValidateNotNull()] | |
[int]$ForegroundColor = 255 | |
, | |
[Parameter(Mandatory = $false)] | |
[ValidateNotNull()] | |
[int]$BackgroundColor = 0 | |
) | |
$esc = "$([char]27)" | |
return "$esc[38;5;$ForegroundColor`m$esc[48;5;$BackgroundColor`m$Message$esc[0m$esc[0m" | |
} | |
# persistent history on exit | |
Register-EngineEvent -SupportEvent PowerShell.Exiting -Action { | |
# setup | |
$historyRootPath = Join-Path $PSScriptRoot "\History" | |
$mergeFilePath = Join-Path $historyRootPath ("\merged-{0}.csv" -f $env:COMPUTERNAME) | |
# save history | |
Get-History | Export-Csv -Path (Join-Path $historyRootPath ("\history-{0}-{1}.csv" -f $env:COMPUTERNAME, $PID)) -Append | |
# merge session history | |
Get-ChildItem -Path $historyRootPath -Filter ("history-{0}-*.csv" -f $env:COMPUTERNAME) | ForEach-Object { | |
Import-Csv -Path $_.FullName | |
} | Sort-Object -Property CommandLine -Unique | Export-Csv -Path $mergeFilePath -Append | |
# delete old session history | |
Get-ChildItem -Path $historyRootPath -Filter ("history-{0}-*.csv" -f $env:COMPUTERNAME) | Remove-Item -Force; | |
} | |
# setup prompt | |
function Prompt | |
{ | |
# was the last command executed successful ? | |
[bool]$script:success = $? | |
# shorten and decorate current path | |
$pathArray = ($ExecutionContext.SessionState.Path.CurrentLocation) -split "\\" | |
if ($pathArray.Count -gt 3) | |
{ | |
$driveSegement = $pathArray | Select-Object -First 1 | |
$pathSegment = ($pathArray | Select-Object -Last 3) -join " `u{e0b1} " | |
$currentLocation = "$driveSegement `u{e0b1} $([char]0x2026) `u{e0b1} $pathSegment" | |
} | |
else | |
{ | |
$currentLocation = $pathArray -join " `u{e0b1} " | |
} | |
# measure how long the last command took to execute | |
$lastCommand = Get-History -Count 1 | |
if ($lastCommand) | |
{ | |
$duration = $lastCommand.EndExecutionTime - $lastCommand.StartExecutionTime | |
$elapsed = "{0:h\:mm\:ss\.ffff}" -f $duration | |
} | |
else | |
{ | |
$elapsed = "0:00:00.0000" | |
} | |
# get branch name | |
$branch = Get-BranchName | |
if ([string]::IsNullOrEmpty($branch)) | |
{ | |
$branch = "n/a" | |
} | |
# write prompt | |
$seperator = "`u{e0b0}" | |
$prompt = "" | |
$prompt += Write-AnsiVT100 "$seperator" -ForegroundColor 0 -BackgroundColor 23 | |
$prompt += Write-AnsiVT100 " `u{26a1} " -ForegroundColor 226 -BackgroundColor 23 | |
$prompt += Write-AnsiVT100 "$seperator" -ForegroundColor 23 -BackgroundColor 31 | |
$prompt += Write-AnsiVT100 " $elapsed " -ForegroundColor 255 -BackgroundColor 31 | |
$prompt += Write-AnsiVT100 "$seperator" -ForegroundColor 31 -BackgroundColor 38 | |
$prompt += Write-AnsiVT100 (" {0:HH\:mm\:ss\.ffff} " -f (Get-Date)) -ForegroundColor 0 -BackgroundColor 38 | |
$prompt += Write-AnsiVT100 "$seperator" -ForegroundColor 38 -BackgroundColor 236 | |
$prompt += Write-AnsiVT100 " $($MyInvocation.HistoryId - 1) " -ForegroundColor 250 -BackgroundColor 236 | |
$prompt += Write-AnsiVT100 "$seperator" -ForegroundColor 236 -BackgroundColor 36 | |
$prompt += Write-AnsiVT100 " `u{e0a0} $branch " -ForegroundColor 254 -BackgroundColor 36 | |
$prompt += Write-AnsiVT100 "$seperator" -ForegroundColor 36 -BackgroundColor 237 | |
$prompt += Write-AnsiVT100 " $currentLocation " -ForegroundColor 253 -BackgroundColor 237 | |
$prompt += Write-AnsiVT100 "$seperator" -ForegroundColor 237 -BackgroundColor 0 | |
$prompt += "`n" | |
$commandStateColor = @{ $true = 254; $false = 9 }[$script:success] | |
$prompt += Write-AnsiVT100 "$seperator" -ForegroundColor 0 -BackgroundColor $commandStateColor | |
$prompt += Write-AnsiVT100 " `u{2665} " -ForegroundColor 160 -BackgroundColor $commandStateColor | |
$prompt += Write-AnsiVT100 "$seperator" -ForegroundColor $commandStateColor -BackgroundColor 251 | |
$prompt += Write-AnsiVT100 " PS " -ForegroundColor 234 -BackgroundColor 251 | |
$prompt += Write-AnsiVT100 "$seperator" -ForegroundColor 251 -BackgroundColor 0 | |
return $prompt | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment