Last active
April 14, 2021 02:07
-
-
Save zhengbli/7fce33eb4a0e8104d2cb814a40a0a70c to your computer and use it in GitHub Desktop.
Powershell Profile
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
#Requires -Version 7 | |
#Requires -Module Terminal-Icons | |
# Version 1.0.4 | |
# check if newer version | |
$gistUrl = "https://api.github.com/gists/7fce33eb4a0e8104d2cb814a40a0a70c" | |
$latestVersionFile = [System.IO.Path]::Combine("$HOME",'.latest_profile_version') | |
$versionRegEx = "# Version (?<version>\d+\.\d+\.\d+)" | |
$profile_initialized = $false | |
if ([System.IO.File]::Exists($latestVersionFile)) { | |
$latestVersion = [System.IO.File]::ReadAllText($latestVersionFile) | |
$currentProfile = [System.IO.File]::ReadAllText($profile) | |
[version]$currentVersion = "0.0.0" | |
if ($currentProfile -match $versionRegEx) { | |
$currentVersion = $matches.Version | |
} | |
if ([version] $latestVersion -gt $currentVersion) { | |
Write-Verbose "Your version: $currentVersion" -Verbose | |
Write-Verbose "New version: $latestVersion" -Verbose | |
$choice = Read-Host -Prompt "Found newer profile, install? (Y)" | |
if ($choice -eq "Y" -or $choice -eq "") { | |
try { | |
$gist = Invoke-RestMethod $gistUrl -ErrorAction Stop | |
$gistProfile = $gist.Files."profile.ps1".Content | |
Set-Content -Path $profile -Value $gistProfile | |
Write-Verbose "Installed newer version of profile" -Verbose | |
. $profile | |
return | |
} | |
catch { | |
# we can hit rate limit issue with GitHub since we're using anonymous | |
Write-Verbose -Verbose "Was not able to access gist, try again next time" | |
} | |
} | |
} | |
} | |
function prompt { | |
function Initialize-Profile { | |
Write-Host "Profile initializing..." | |
$null = Start-ThreadJob -Name "Get version of `$profile from gist" -ArgumentList $gistUrl, $latestVersionFile, $versionRegEx -ScriptBlock { | |
param ($gistUrl, $latestVersionFile, $versionRegEx) | |
try { | |
$gist = Invoke-RestMethod $gistUrl -ErrorAction Stop | |
$gistProfile = $gist.Files."profile.ps1".Content | |
[version]$gistVersion = "0.0.0" | |
if ($gistProfile -match $versionRegEx) { | |
$gistVersion = $matches.Version | |
Set-Content -Path $latestVersionFile -Value $gistVersion | |
} | |
} | |
catch { | |
# we can hit rate limit issue with GitHub since we're using anonymous | |
Write-Verbose -Verbose "Was not able to access gist to check for newer version" | |
} | |
} | |
if ((Get-Module PSReadLine).Version -lt 2.2) { | |
throw "Profile requires PSReadLine 2.2+" | |
} | |
Set-PSReadLineOption -Colors @{ Selection = "`e[92;7m"; InLinePrediction = "`e[36;7;238m" } -PredictionSource History | |
Set-PSReadLineKeyHandler -Chord "Ctrl+f" -Function ForwardWord | |
Set-PSReadLineKeyHandler -Chord "Ctrl+b" -Function BackwardWord | |
Set-PSReadLineKeyHandler -Chord Alt+f1 -Function ShowCommandHelp | |
Set-PSReadLineOption -PredictionViewStyle ListView | |
if ($IsWindows) { | |
Set-PSReadLineKeyHandler -Chord Ctrl+Shift+c -Function Copy | |
Set-PSReadLineKeyHandler -Chord Ctrl+Shift+v -Function Paste | |
} | |
else { | |
try { | |
Import-UnixCompleters | |
} | |
catch [System.Management.Automation.CommandNotFoundException] { | |
Install-Module Microsoft.PowerShell.UnixCompleters -Repository PSGallery -AcceptLicense -Force | |
Import-UnixCompleters | |
} | |
} | |
# add path to dotnet global tools | |
$env:PATH += [System.IO.Path]::PathSeparator + [System.IO.Path]::Combine("$HOME", '.dotnet', 'tools') | |
# ensure dotnet cli is in path | |
$dotnet = Get-Command dotnet -CommandType Application -ErrorAction Ignore | |
if ($null -eq $dotnet) { | |
if ([System.IO.File]::Exists("$HOME/.dotnet/dotnet")) { | |
$env:PATH += [System.IO.Path]::PathSeparator + [System.IO.Path]::Combine("$HOME", '.dotnet') | |
} | |
} | |
# Test z.lua | |
if (-Not (Get-Command z -ErrorAction SilentlyContinue)) { | |
$zPath = [System.IO.Path]::Combine($HOME, 'z.lua', 'z.lua'); | |
Invoke-Expression (& { (lua $zPath --init powershell) -join "`n" }) | |
} | |
Import-Module Terminal-Icons | |
} | |
if (!$global:profile_initialized) { | |
Initialize-Profile | |
$global:profile_initialized = $true | |
} | |
$currentLastExitCode = $LASTEXITCODE | |
$lastSuccess = $? | |
$color = @{ | |
Reset = "`e[0m" | |
Red = "`e[31;1m" | |
Green = "`e[32;1m" | |
Yellow = "`e[33;1m" | |
Grey = "`e[37;0m" | |
White = "`e[37;1m" | |
Invert = "`e[7m" | |
RedBackground = "`e[41m" | |
} | |
# set color of PS based on success of last execution | |
if ($lastSuccess -eq $false) { | |
$lastExit = $color.Red | |
} | |
else { | |
$lastExit = $color.Green | |
} | |
# get the execution time of the last command | |
$lastCmdTime = "" | |
$lastCmd = Get-History -Count 1 | |
if ($null -ne $lastCmd) { | |
$cmdTime = $lastCmd.Duration.TotalMilliseconds | |
$units = "ms" | |
$timeColor = $color.Green | |
if ($cmdTime -gt 250 -and $cmdTime -lt 1000) { | |
$timeColor = $color.Yellow | |
} | |
elseif ($cmdTime -ge 1000) { | |
$timeColor = $color.Red | |
$units = "s" | |
$cmdTime = $lastCmd.Duration.TotalSeconds | |
if ($cmdTime -ge 60) { | |
$units = "m" | |
$cmdTIme = $lastCmd.Duration.TotalMinutes | |
} | |
} | |
$lastCmdTime = "$($color.Grey)[$timeColor$($cmdTime.ToString("#.##"))$units$($color.Grey)]$($color.Reset) " | |
} | |
# get git branch information if in a git folder or subfolder | |
$gitBranch = "" | |
$path = Get-Location | |
while ($path -ne "") { | |
if (Test-Path ([System.IO.Path]::Combine($path, '.git'))) { | |
# need to do this so the stderr doesn't show up in $error | |
$ErrorActionPreferenceOld = $ErrorActionPreference | |
$ErrorActionPreference = 'Ignore' | |
$branch = git rev-parse --abbrev-ref --symbolic-full-name '@{u}' | |
$ErrorActionPreference = $ErrorActionPreferenceOld | |
# handle case where branch is local | |
if ($lastexitcode -ne 0 -or $null -eq $branch) { | |
$branch = git rev-parse --abbrev-ref HEAD | |
} | |
$branchColor = $color.Green | |
if ($branch -match "/master") { | |
$branchColor = $color.Red | |
} | |
$gitBranch = " $($color.Grey)[$branchColor$branch$($color.Grey)]$($color.Reset)" | |
break | |
} | |
$path = Split-Path -Path $path -Parent | |
} | |
# truncate the current location if too long | |
$currentDirectory = $executionContext.SessionState.Path.CurrentLocation.Path.Replace($HOME, "~") | |
$consoleWidth = [Console]::WindowWidth | |
$maxPath = [int]($consoleWidth / 2) | |
if ($currentDirectory.Length -gt $maxPath) { | |
$currentDirectory = "`u{2026}" + $currentDirectory.SubString($currentDirectory.Length - $maxPath) | |
} | |
# check if running dev built pwsh | |
$devBuild = '' | |
if ($PSHOME.Contains("publish")) { | |
$devBuild = " $($color.White)$($color.RedBackground)DevPwsh$($color.Reset)" | |
} | |
"${lastCmdTime}${currentDirectory}${gitBranch}${devBuild}`n${lastExit}PS$($color.Reset)$('>' * ($nestedPromptLevel + 1)) " | |
# set window title | |
try { | |
$prefix = '' | |
if ($isWindows) { | |
$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent() | |
$windowsPrincipal = [Security.Principal.WindowsPrincipal]::new($identity) | |
if ($windowsPrincipal.IsInRole("Administrators") -eq 1) { | |
$prefix = "Admin:" | |
} | |
} | |
$Host.ui.RawUI.WindowTitle = "$prefix$PWD" | |
} | |
catch { | |
# do nothing if can't be set | |
} | |
$global:LASTEXITCODE = $currentLastExitCode | |
} | |
Set-Alias ll ls | |
function gs { | |
git status -u | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment