Last active
March 18, 2019 23:54
-
-
Save Trucido/32b83b88347dd2fec899a2385acea209 to your computer and use it in GitHub Desktop.
posh prompt nonsense
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
############################################################################################################################################ | |
## Prompt ## | |
############################################################################################################################################ | |
Clear-Host | |
[ScriptBlock]$Prompt = { | |
$origLastExitCode = $global:LASTEXITCODE | |
Set-StrictMode -Version 'Latest' | |
$gitLoaded = $false # skip stupid git module, adds ~1000ms to startup time. | |
# | |
# PATHS | |
# | |
<# | |
A UNC path has no drive so it's better to use the ProviderPath e.g. "\\server\share". | |
However for any path with a drive defined, it's better to use the Path property. | |
In this case, ProviderPath is "\LocalMachine\My"" whereas Path is "Cert:\LocalMachine\My". | |
The latter is more desirable. | |
#> | |
$CurrentLocation = $ExecutionContext.SessionState.Path.CurrentLocation | |
$_CD_ = if($CurrentLocation.Drive){ $CurrentLocation.Path }else{ $CurrentLocation.ProviderPath } | |
$tpwd = $_CD_ -Replace [Regex]::Escape("$HOME"),'~' -Replace '^[^:]+::','' # Replace any paths containing $HOME with '~' | |
$spwd = $tpwd -Replace '\\(\.?)([^\\])[^\\]*(?=\\)','\$1$2' # Abreviates each dir to 1 char except for last | |
$PWDMaxLen = [int]'32' # Max chars in current tilde'd path before switching to abreviation | |
$PPWD = if($tpwd.Length -and ($tpwd.Length -le $PWDMaxLen)){ $tpwd }else{ $spwd } | |
# check vars if not set | |
$PS_VERSION = [string]$PSVersionTable.PSVersion | |
$SHELL = [string]$ShellId+'.'+$PSEdition+' '+$PS_Version | |
if(!$USER){ $USER = $env:UserName } | |
if(!$HOME){ $HOME = $env:UserProfile } | |
if(!$HOSTNAME){ $HOSTNAME = [Net.Dns]::GetHostName() } | |
if($null -eq $IsAdmin){ [bool]$IsAdmin = ([Security.Principal.WindowsPrincipal]( | |
[Security.Principal.WindowsIdentity]::GetCurrent() | |
)).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } | |
# | |
# Colors (Note: PS5 has issues with backtick escape color codes, so use [char] for escapes) | |
# | |
$fg = @{ | |
# 'black' = "$([char]0x1b)[30m" | |
# 'red' = "$([char]0x1b)[31m" | |
'green' = "$([char]0x1b)[32m" | |
'yellow' = "$([char]0x1b)[33m" | |
# 'blue' = "$([char]0x1b)[34m" | |
# 'magenta' = "$([char]0x1b)[35m" | |
# 'cyan' = "$([char]0x1b)[36m" | |
# 'white' = "$([char]0x1b)[37m" | |
} | |
# bold, though technically "bright", but same difference | |
$fg_bold = @{ | |
# 'gray' = "$([char]0x1b)[90m" | |
# 'black' = "$([char]0x1b)[90m" | |
'red' = "$([char]0x1b)[91m" | |
# 'green' = "$([char]0x1b)[92m" | |
# 'yellow' = "$([char]0x1b)[93m" | |
'blue' = "$([char]0x1b)[94m" | |
# 'magenta' = "$([char]0x1b)[95m" | |
# 'cyan' = "$([char]0x1b)[96m" | |
# 'white' = "$([char]0x1b)[97m" | |
} | |
$c_reset = "$([char]0x1b)[0m" | |
$c_user = if($IsAdmin){ "$($fg_bold['red'])" }else{ "$($fg['green'])" } | |
$nl = "$([char]10)" # newline | |
# | |
# Main prompt line: User@Hostname shell.name.edition n.n.nn ~\foo\bar + newline + '> ' | |
# | |
"$($c_user+$USER+'@'+$HOSTNAME+$fg_bold['blue']+' '+$SHELL+' '+$fg['yellow']+$PPWD+$c_reset+$(if($gitLoaded-and(Test-Path ${_CD_}\.git)){Write-VcsStatus})+ | |
$nl+$('>' * ($nestedPromptLevel + 1)) ) " | |
# | |
# Window Title (short path or only current directory if Length <= 7) | |
# | |
$wpwd = if($spwd.Length -le 7){ $spwd }else{ try{ Split-Path $_CD_ -Leaf }catch{ "$([char]8734)" } } | |
$Host.UI.RawUI.WindowTitle = "$($(if($IsAdmin){'Admin: '})+$wpwd)" # prefix 'Admin: ' if elevated, else just path or cwd | |
# | |
# [Environment]::CurrentDirectory | |
# | |
[ScriptBlock]$locationChangedHandler = { | |
try { | |
# Update CurrentDirectory so .NET sees same PSPath as powershell | |
# Note: Must use Filesystem provider, PSDrives and network paths are invalid | |
[System.Environment]::CurrentDirectory = $ExecutionContext.SessionState.Path.CurrentFileSystemLocation | |
} catch [System.UnauthorizedAccessException], | |
[System.Management.Automation.MethodInvocationException], | |
[System.Management.Automation.SetValueInvocationException] { | |
# Catch UnauthorizedAccessException if any directories in path not readable | |
$Error.Remove($error[0]) | |
# And as a last ditch effort, try `Get-Location` cmdlet | |
try { | |
[System.Environment]::CurrentDirectory = Get-Location -PSProvider FileSystem | |
} catch {} | |
} | |
} | |
# Note: PS < v6 does not have LocationChangedAction, so invoke scriptblock instead for compatibility. | |
# PS6: `$ExecutionContext.InvokeCommand.LocationChangedAction = $locationChangedHandler` | |
& $locationChangedHandler | |
# Restore LastExitCode in case we contaminated it | |
$global:LASTEXITCODE = $origLastExitCode | |
Remove-Variable origLASTEXITCODE | |
return " " | |
# .Link | |
# https://go.microsoft.com/fwlink/?LinkID=225750 | |
# .ExternalHelp System.Management.Automation.dll-help.xml | |
} | |
# Tell PSReadline which part of the prompt to change red for interactive syntax validation. (PS6 only or PSReadline >= 2) | |
if ($IsCoreCLR -or (Get-Module PSReadLine).Version.Major -ge 2) { | |
Set-PSReadLineOption -PromptText '> ' | |
} | |
# Set prompt readonly to prevent unexpected altering of prompt (without -Force) | |
Set-Item 'Function:\Prompt' -Value $Prompt -Force -Option:ReadOnly -ErrorAction:Ignore -Verbose:$false |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment