Last active
May 20, 2024 12:54
-
-
Save binaryfunt/fab7efd33ed8922a4ed0d362a26cb99c to your computer and use it in GitHub Desktop.
Posh-git style powershell prompt
This file contains 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
# IPython-like history search: | |
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward | |
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward | |
function Get-BranchName () { | |
try { | |
$branch = git rev-parse --abbrev-ref HEAD | |
if ($branch -eq "HEAD") { | |
# we're probably in detached HEAD state | |
$tag = git describe --tags --exact-match | |
if ($tag) { | |
return "($tag)" | |
} | |
$sha = git rev-parse --short HEAD | |
if ($sha) { | |
return "($sha...)" | |
} | |
$isBare = git rev-parse --is-bare-repository | |
if ($isBare -eq "true") { | |
return "(BARE)" | |
} | |
# probably an empty repo | |
return "(HEAD)" | |
} | |
# else we're on an actual branch, so print it | |
return $branch | |
} catch { | |
return "(UNKNOWN)" | |
} | |
} | |
function Get-TrackingStatus () { | |
$color = "cyan" | |
try { | |
$status = git status -sb | |
$hasUpstream = $status | Select-String -Pattern '^## .*(\.\.\.)' | |
$gone = $status | Select-String -Pattern '^## .* \[gone\]' | |
if ($gone) { | |
$str = [char]0x00D7 | |
} elseif ($hasUpstream) { | |
$match = $status | Select-String -Pattern '^## .*\[ahead (\d+)' | |
try { | |
$aheadNum = $match.Matches.Groups[1] | |
} catch {} | |
$match = $status | Select-String -Pattern '^## .*behind (\d+)\]' | |
try { | |
$behindNum = $match.Matches.Groups[1] | |
} catch {} | |
if ($aheadNum -and $behindNum) { | |
$str = "$([char]0x2193)$behindNum $([char]0x2191)$aheadNum" | |
$color = "yellow" | |
} elseif ($aheadNum) { | |
$str = "$([char]0x2191)$aheadNum" | |
$color = "green" | |
} elseif ($behindNum) { | |
$str = "$([char]0x2193)$behindNum" | |
$color = "red" | |
} else { | |
$str = [char]0x2261 | |
} | |
} else { | |
$str = "?" | |
} | |
} catch { | |
$str = "?" | |
} | |
return $str, $color, $status | |
} | |
function Write-Status () { | |
$branchStr = Get-BranchName | |
$trackingStr, $trackingColor, $status = Get-TrackingStatus | |
if ($status) { | |
$match = $status | Select-String -Pattern '^([MARC][ MD]|D[ RC])' | |
$stagedChanges = $match.Matches.Count | |
$match = $status | Select-String -Pattern '^([ MARC][MD]| A|[ D][RC])' | |
$unstagedChanges = $match.Matches.Count | |
$match = $status | Select-String -Pattern '^(D[DU]|A[AU]|U[DAU])' | |
$conflicts = $match.Matches.Count | |
$match = $status | Select-String -Pattern '^\?\?' | |
$untrackedFiles = $match.Matches.Count | |
} | |
Write-Host " [" -NoNewline -ForegroundColor "gray" | |
Write-Host "$branchStr $trackingStr" -NoNewline -ForegroundColor $trackingColor | |
if ($stagedChanges) { | |
Write-Host " ~$stagedChanges" -NoNewline -ForegroundColor "darkgreen" | |
if ($unstagedChanges -or $conflicts -or $untrackedFiles) { | |
Write-Host " |" -NoNewline -ForegroundColor "gray" | |
} | |
} | |
if ($unstagedChanges) { | |
Write-Host " ~$unstagedChanges" -NoNewline -ForegroundColor "darkred" | |
} | |
if ($conflicts) { | |
Write-Host " !$conflicts" -NoNewline -ForegroundColor "darkred" | |
} | |
if ($untrackedFiles) { | |
Write-Host " ?$untrackedFiles" -NoNewline -ForegroundColor "darkred" | |
} | |
Write-Host "]" -NoNewline -ForegroundColor "gray" | |
} | |
function prompt { | |
$base = "PS" | |
$path = "$($executionContext.SessionState.Path.CurrentLocation)" | |
$userPrompt = "$('>' * ($nestedPromptLevel + 1)) " | |
Write-Host "`n$base $path" -NoNewline | |
if (git rev-parse --git-dir) { | |
Write-Status | |
} | |
return $userPrompt | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment