Skip to content

Instantly share code, notes, and snippets.

@scrthq
Last active June 1, 2019 19:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scrthq/6b2dfc7efc459399c872d23a663d7914 to your computer and use it in GitHub Desktop.
Save scrthq/6b2dfc7efc459399c872d23a663d7914 to your computer and use it in GitHub Desktop.
PowerShell Profile components
$global:PSProfileConfig = @{
_internal = @{
ProfileLoadStart = Get-Date
}
Settings = @{
Prompt = 'Slim'
PSVersionStringLength = 3
}
Variables = @{
Environment = @{
USERPROFILE = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::UserProfile)
}
Global = @{
CodeProfile = $PSScriptRoot
PathAliasDirectorySeparator = [System.IO.Path]::DirectorySeparatorChar
AltPathAliasDirectorySeparator = [char]0xe0b1
}
}
GitPaths = @{
Work = 'WorkGit'
Personal = 'ScrtGit'
Other = 'E:\Git'
}
PathAliases = @(
@{
Alias = '~'
Path = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::UserProfile)
}
)
GistsToInvoke = @(
@{
Id = '6b2dfc7efc459399c872d23a663d7914'
Metadata = @{
Description = 'PowerShell Profile Components'
}
}
)
ModulesToImport = @(
'PSChef'
'PSToolbelt'
'MyConfig'
)
}
$log = {
Param(
$Message,
$Section = "Info",
$Action = "Log",
$Start = $(if ($global:PSProfileConfig._internal.ProfileLoadStart){$global:PSProfileConfig._internal.ProfileLoadStart}else{Get-Date})
)
$now = Get-Date
$ls = if ($null -eq $script:LastProfileCommandTime) {
$now - $Start
}
else {
$now - $script:LastProfileCommandTime
}
$ts = $now - $Start
Write-Host -ForegroundColor Cyan ("[L+{0:00}.{1:000}s] [T+{2:00}.{3:000}s] [{4}] [{5}] {6}" -f ([Math]::Floor($ls.TotalSeconds)),$ls.Milliseconds,([Math]::Floor($ts.TotalSeconds)),$ts.Milliseconds,"$Section".PadRight(10,'.'),"$Action".PadRight(9,'.'),$Message)
$script:LastProfileCommandTime = Get-Date
}
function Get-Gist {
[CmdletBinding()]
Param (
[parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position = 0)]
[String]
$Id,
[parameter(ValueFromPipelineByPropertyName)]
[Alias('Files')]
[String[]]
$File,
[parameter(ValueFromPipelineByPropertyName)]
[String]
$Sha,
[parameter(ValueFromPipelineByPropertyName,ValueFromRemainingArguments)]
[Object]
$Metadata,
[parameter()]
[Switch]
$Invoke
)
Process {
$Uri = [System.Collections.Generic.List[string]]@(
'https://api.github.com'
'/gists/'
$PSBoundParameters['Id']
)
if ($PSBoundParameters.ContainsKey('Sha')) {
$Uri.Add("/$($PSBoundParameters['Sha'])")
Write-Verbose "[$($PSBoundParameters['Id'])] Getting gist info @ SHA '$($PSBoundParameters['Sha'])'"
}
else {
Write-Verbose "[$($PSBoundParameters['Id'])] Getting gist info"
}
$gistInfo = Invoke-RestMethod -Uri ([Uri](-join $Uri)) -Verbose:$false
$fileNames = if ($PSBoundParameters.ContainsKey('File')) {
$PSBoundParameters['File']
}
else {
$gistInfo.files.PSObject.Properties.Name
}
foreach ($fileName in $fileNames) {
Write-Verbose "[$fileName] Getting gist file content"
$fileInfo = $gistInfo.files.$fileName
$content = if ($fileInfo.truncated) {
(Invoke-WebRequest -Uri ([Uri]$fileInfo.raw_url)).Content
}
else {
$fileInfo.content
}
$lines = ($content -split "`n").Count
if ($Invoke) {
Write-Verbose "[$fileName] Parsing gist file content ($lines lines)"
$noScopePattern = '^function\s+(?<Name>[\w+_-]{1,})\s+\{'
$globalScopePattern = '^function\s+global\:'
$noScope = [RegEx]::Matches($content, $noScopePattern, "Multiline, IgnoreCase")
$globalScope = [RegEx]::Matches($content,$globalScopePattern,"Multiline, IgnoreCase")
if ($noScope.Count -ge $globalScope.Count) {
foreach ($match in $noScope) {
$fullValue = ($match.Groups | Where-Object { $_.Name -eq 0 }).Value
$funcName = ($match.Groups | Where-Object { $_.Name -eq 'Name' }).Value
Write-Verbose "[$fileName::$funcName] Updating function to global scope to ensure it imports correctly."
$content = $content.Replace($fullValue, "function global:$funcName {")
}
}
Write-Verbose "[$fileName] Invoking gist file content"
$ExecutionContext.InvokeCommand.InvokeScript(
$false,
([scriptblock]::Create($content)),
$null,
$null
)
}
[PSCustomObject]@{
File = $fileName
Sha = $Sha
Count = $lines
Content = $content -join "`n"
}
}
}
}
Write-Host -ForegroundColor Yellow "
[LastTime.] [TotalTime] [Section...] [Action...] Log Message...
----------- ----------- ------------ ----------- ---------------------------------------------------------------------"
if (-not (Test-Path $profile.CurrentUserAllHosts)) {
&$log "Creating CurrentUserAllHosts file" "Profile" "Maint"
New-Item $profile.CurrentUserAllHosts -Force
}
#region: Apply the $global:PSProfileConfig
foreach ($var in $global:PSProfileConfig.Variables.Environment.Keys) {
&$log "`$env:$var = '$($global:PSProfileConfig.Variables.Environment[$var])'" "Variable" "Set"
Set-Item "Env:\$var" -Value $global:PSProfileConfig.Variables.Environment[$var] -Force
}
foreach ($var in $global:PSProfileConfig.Variables.Global.Keys) {
&$log "`$global:$var = '$($global:PSProfileConfig.Variables.Global[$var])'" "Variable" "Set"
Set-Variable -Name $var -Value $global:PSProfileConfig.Variables.Global[$var] -Scope Global -Force
}
$aliasMapJson = @{ }
foreach ($category in $global:PSProfileConfig.GitPaths.Keys) {
$aliasIcon = switch ($category) {
Work {
'$'
}
Personal {
'@'
}
default {
'#'
}
}
if ($global:PSProfileConfig.GitPaths[$category] -notmatch [RegEx]::Escape(([System.IO.Path]::DirectorySeparatorChar))) {
$paired = $false
$env:USERPROFILE,$PWD.Path,$PWD.Drive.Root | ForEach-Object {
if (-not $paired) {
$gitPath = Join-Path $_ $global:PSProfileConfig.GitPaths[$category]
if (Test-Path $gitPath) {
$paired = $true
}
}
}
}
else {
$gitPath = $global:PSProfileConfig.GitPaths[$category]
}
&$log "'$($aliasIcon)git' = '$($gitPath)'" "PathAlias" "Set"
$aliasMapJson["$($aliasIcon)git"] = $gitPath
}
foreach ($alias in $global:PSProfileConfig.PathAliases) {
&$log "'$($alias['Alias'])' = '$($alias['Path'])'" "PathAlias" "Set"
$aliasMapJson[$alias['Alias']] = $alias['Path']
}
$global:PSProfileConfig['_internal']['PathAliasMap'] = $aliasMapJson
$global:PSProfileConfig['_internal']['GitPathMap'] = @{ CodeProfile = $global:CodeProfile }
$global:PSProfileConfig['_internal']['PSBuildPathMap'] = @{}
foreach ($key in $global:PSProfileConfig.GitPaths.Keys) {
$fullPath = if (Test-Path ($global:PSProfileConfig.GitPaths[$key])) {
$global:PSProfileConfig.GitPaths[$key]
}
elseif (Test-Path (Join-Path "~" $global:PSProfileConfig.GitPaths[$key])) {
Join-Path "~" $global:PSProfileConfig.GitPaths[$key]
}
elseif (Test-Path (Join-Path $PWD.Drive.Root $global:PSProfileConfig.GitPaths[$key])) {
Join-Path $PWD.Drive.Root $global:PSProfileConfig.GitPaths[$key]
}
else {
"???<$($global:PSProfileConfig.GitPaths[$key])>"
}
&$log "$key[$fullPath]" "GitRepos" "Discover"
$g = 0
$b = 0
if ($fullPath -notmatch '^\?\?\?' -and (Test-Path $fullPath)) {
Get-ChildItem $fullPath -Recurse -Filter '.git' -Directory -Force | ForEach-Object {
$global:PSProfileConfig['_internal']['GitPathMap'][$_.Parent.BaseName] = $_.Parent.FullName
$g++
if (Test-Path (Join-Path $_.Parent.FullName "build.ps1")) {
$global:PSProfileConfig['_internal']['PSBuildPathMap'][$_.Parent.BaseName] = $_.Parent.FullName
$b++
}
}
}
&$log "$key[$fullPath] :: $g git | $b build" "GitRepos" "Report"
}
#endregion: Apply the $global:PSProfileConfig
if (-not $env:DemoInProgress) {
$global:PSProfileConfig.ModulesToImport | ForEach-Object {
&$log $_ "Module" "Import"
Import-Module $_ -ErrorAction SilentlyContinue
}
if ($global:PSProfileConfig.Settings.Prompt) {
Switch-Prompt -Prompt $global:PSProfileConfig.Settings.Prompt
}
}
else {
demo
}
Write-Host ("Loading personal profile alone took {0}ms." -f ([Math]::Round(((Get-Date) - $global:PSProfileConfig._internal.ProfileLoadStart).TotalMilliseconds,0)))
function Start-Demo {
param(
[parameter(Mandatory = $false, Position = 0)]
[string]
$File = ".\demo.txt",
[parameter(Mandatory = $false, Position = 1)]
[int]
$Command = 0
)
Switch-Prompt -Prompt Fast
$_starttime = [DateTime]::now
Write-Host -for Yellow "<Demo [$file] Started>"
try {
$_lines = Get-Content $file -ErrorAction Stop
}
catch {
Write-Warning "$file not found! Skipping demo"
}
# We use a FOR and an INDEX ($_i) instead of a FOREACH because
# it is possible to start at a different location and/or jump
# around in the order.
for ($_i = $Command; $_i -lt $_lines.count; $_i++) {
$_SimulatedLine = $("`n[$_i]PS> " + $($_Lines[$_i]))
Write-Host -NoNewLine $_SimulatedLine
# Put the current command in the Window Title along with the demo duration
$_Duration = [DateTime]::Now - $_StartTime
$Host.UI.RawUI.WindowTitle = "[{0}m, {1}s] {2}" -f [int]$_Duration.TotalMinutes, [int]$_Duration.Seconds, $($_Lines[$_i])
if ($_lines[$_i].StartsWith("#")) {
continue
}
$_input = [System.Console]::ReadLine()
switch ($_input) {
"?" {
Write-Host -ForeGroundColor Yellow "Running demo: $file`n(q) Quit (!) Suspend (#x) Goto Command #x (fx) Find cmds using X`n(t) Timecheck (s) Skip (d) Dump demo"
$_i -= 1
}
"q" {
Write-Host -ForeGroundColor Yellow "<Quit demo>"
return
}
"s" {
Write-Host -ForeGroundColor Yellow "<Skipping Cmd>"
}
"d" {
for ($_ni = 0; $_ni -lt $_lines.Count; $_ni++) {
if ($_i -eq $_ni) {
Write-Host -ForeGroundColor Red ("*" * 80)
}
Write-Host -ForeGroundColor Yellow ("[{0,2}] {1}" -f $_ni, $_lines[$_ni])
}
$_i -= 1
}
"t" {
$_Duration = [DateTime]::Now - $_StartTime
Write-Host -ForeGroundColor Yellow $("Demo has run {0} Minutes and {1} Seconds" -f [int]$_Duration.TotalMinutes, [int]$_Duration.Seconds)
$_i -= 1
}
{$_.StartsWith("f")} {
for ($_ni = 0; $_ni -lt $_lines.Count; $_ni++) {
if ($_lines[$_ni] -match $_.SubString(1)) {
Write-Host -ForeGroundColor Yellow ("[{0,2}] {1}" -f $_ni, $_lines[$_ni])
}
}
$_i -= 1
}
{$_.StartsWith("!")} {
if ($_.Length -eq 1) {
Write-Host -ForeGroundColor Yellow "<Suspended demo - type ‘Exit’ to resume>"
$host.EnterNestedPrompt()
}
else {
trap [System.Exception] {
Write-Error $_;continue;
}
Invoke-Expression $($_.SubString(1) + "| out-host")
}
$_i -= 1
}
{$_.StartsWith("#")} {
$_i = [int]($_.SubString(1)) - 1
continue
}
default {
trap [System.Exception] {
Write-Error $_;continue;
}
Invoke-Expression $($_lines[$_i] + "| out-host")
$_Duration = [DateTime]::Now - $_StartTime
$Host.UI.RawUI.WindowTitle = "[{0}m, {1}s] {2}" -f [int]$_Duration.TotalMinutes, [int]$_Duration.Seconds, $($_Lines[$_i])
[System.Console]::ReadLine()
}
}
}
$_Duration = [DateTime]::Now - $_StartTime
Write-Host -ForeGroundColor Yellow $("<Demo Complete {0} Minutes and {1} Seconds>" -f [int]$_Duration.TotalMinutes, [int]$_Duration.Seconds)
Write-Host -ForeGroundColor Yellow $([DateTime]::now)
}
function Stop-Demo {
demo -exit
}
function demo {
[CmdletBinding()]
Param (
[parameter()]
[Alias('e')]
[switch]
$exit
)
Process {
if ($exit -and $null -ne $env:DemoInProgress) {
$env:DemoInProgress = $null
[System.Environment]::SetEnvironmentVariable('DemoInProgress',$null,[System.EnvironmentVariableTarget]::User)
. $profile.CurrentUserAllHosts
}
elseif (-not $exit -and $null -eq $env:DemoInProgress) {
[System.Environment]::SetEnvironmentVariable('DemoInProgress',(-not $exit),[System.EnvironmentVariableTarget]::User)
$env:DemoInProgress = -not $exit
Switch-Prompt Basic
}
}
}
function USA {
Write-host "`n 'MURICA"
Write-host "------------------------"
Write-host "░░░░░░░░░░" -BackgroundColor Blue -NoNewline
Write-host " " -BackgroundColor red
Write-host "░░░░░░░░░░" -BackgroundColor Blue -NoNewline
Write-host " " -BackgroundColor White
Write-host "░░░░░░░░░░" -BackgroundColor Blue -NoNewline
Write-host " " -BackgroundColor red
Write-host " " -BackgroundColor White
Write-host " " -BackgroundColor red
Write-host " " -BackgroundColor White
Write-host " `n" -BackgroundColor red
}
function FRANCE {
Write-host "`n FRANCE"
Write-host "------------------------"
Write-host " " -BackgroundColor Blue -NoNewline
Write-host " " -BackgroundColor White -NoNewline
Write-host " " -BackgroundColor Red
Write-host " " -BackgroundColor Blue -NoNewline
Write-host " " -BackgroundColor White -NoNewline
Write-host " " -BackgroundColor Red
Write-host " " -BackgroundColor Blue -NoNewline
Write-host " " -BackgroundColor White -NoNewline
Write-host " " -BackgroundColor Red
Write-host " " -BackgroundColor Blue -NoNewline
Write-host " " -BackgroundColor White -NoNewline
Write-host " " -BackgroundColor Red
Write-host " " -BackgroundColor Blue -NoNewline
Write-host " " -BackgroundColor White -NoNewline
Write-host " " -BackgroundColor Red
}
function Fabulous {
Write-host "`n Extra Fabulous"
Write-host "------------------------"
Write-host " " -BackgroundColor Red
Write-host " " -BackgroundColor DarkRed
Write-host " " -BackgroundColor Yellow
Write-host " " -BackgroundColor Green
Write-host " " -BackgroundColor Blue
Write-host " `n" -BackgroundColor Magenta
}
function Disable-ProfileClear {
[System.Environment]::SetEnvironmentVariable("PSProfileClear", 0, [System.EnvironmentVariableTarget]::User)
$env:PSProfileClear = 0
}
function Enable-ProfileClear {
[System.Environment]::SetEnvironmentVariable("PSProfileClear", 1, [System.EnvironmentVariableTarget]::User)
$env:PSProfileClear = 1
}
if ($null -eq (Get-Command open -ErrorAction SilentlyContinue)) {
New-Alias -Name open -Value Invoke-Item -Scope Global -Force
}
function Invoke-Profile {
[CmdletBinding()]
Param (
[parameter(Mandatory = $false,Position = 0)]
[ValidateSet("Fast","Slim","Full","Demo","macOS",$null)]
[String]
$Level = $null
)
. $profile.CurrentUserAllHosts $Level
}
function Disable-PoshGit {
$env:DisablePoshGit = $true
}
function Enable-PoshGit {
$env:DisablePoshGit = $false
}
function Syntax {
[CmdletBinding()]
param (
$Command
)
$check = Get-Command -Name $Command
$params = @{
Name = if ($check.CommandType -eq 'Alias') {
Get-Command -Name $check.Definition
}
else {
$Command
}
Syntax = $true
}
(Get-Command @params) -replace '(\s(?=\[)|\s(?=-))', "`r`n "
}
function Show-Colors ([Switch]$Grid) {
$colors = [enum]::GetValues([System.ConsoleColor])
if ($Grid) {
Foreach ($bgcolor in $colors) {
Foreach ($fgcolor in $colors) {
Write-Host "$fgcolor|" -ForegroundColor $fgcolor -BackgroundColor $bgcolor -NoNewLine
}
Write-Host " on $bgcolor"
}
}
else {
$max = ($colors | ForEach-Object { "$_ ".Length } | Measure-Object -Maximum).Maximum
foreach ( $color in $colors ) {
Write-Host (" {0,2} {1,$max} " -f [int]$color,$color) -NoNewline
Write-Host "$color" -Foreground $color
}
}
}
function global:Get-Prompt {
$i = 0
$leadingWhiteSpace = $null
"function global:prompt {`n" + $((Get-Command prompt).Definition -split "`n" | ForEach-Object {
if (-not [String]::IsNullOrWhiteSpace($_)) {
if ($null -eq $leadingWhiteSpace) {
$leadingWhiteSpace = ($_ | Select-String -Pattern '^\s+').Matches[0].Value
}
$_ -replace "^$leadingWhiteSpace",' '
"`n"
}
elseif ($i) {
$_
"`n"
}
$i++
}) + "}"
}
function global:Get-PSVersion {
[OutputType('System.String')]
[CmdletBinding()]
Param (
[parameter(Position = 0)]
[AllowNull()]
[int]
$Places
)
Process {
$version = $PSVersionTable.PSVersion.ToString()
if ($PSBoundParameters.ContainsKey('Places') -and $null -ne $Places) {
$split = ($version -split '\.')[0..($Places - 1)]
if ("$($split[-1])".Length -gt 1) {
$split[-1] = "$($split[-1])".Substring(0,1)
}
$joined = $split -join '.'
if ($version -match '[a-zA-Z]+') {
$joined += "-$(($Matches[0]).Substring(0,1))"
if ($version -match '\d+$') {
$joined += $Matches[0]
}
}
$joined
}
else {
$version
}
}
}
function global:Test-IfGit {
[CmdletBinding()]
Param ()
Process {
try {
$topLevel = git rev-parse --show-toplevel *>&1
if ($topLevel -like 'fatal: *') {
$false
}
else {
$origin = git remote get-url origin
$repo = Split-Path -Leaf $origin
[PSCustomObject]@{
TopLevel = (Resolve-Path $topLevel).Path
Origin = $origin
Repo = $(if ($repo -notmatch '(\.git|\.ssh|\.tfs)$') {$repo} else {$repo.Substring(0,($repo.LastIndexOf('.')))})
}
}
}
catch {
$false
}
}
}
function global:Get-PathAlias {
[CmdletBinding()]
Param (
[parameter(Position = 0)]
[string]
$Path = $PWD.Path,
[parameter(Position = 1)]
[string]
$DirectorySeparator = $global:PathAliasDirectorySeparator
)
Begin {
try {
$origPath = $Path
if ($null -eq $global:PSProfileConfig) {
$global:PSProfileConfig = @{
_internal = @{
PathAliasMap = @{
'~' = $env:USERPROFILE
}
}
}
}
elseif ($null -eq $global:PSProfileConfig['_internal']) {
$global:PSProfileConfig['_internal'] = @{
PathAliasMap = @{
'~' = $env:USERPROFILE
}
}
}
elseif ($null -eq $global:PSProfileConfig['_internal']['PathAliasMap']) {
$global:PSProfileConfig['_internal']['PathAliasMap'] = @{
'~' = $env:USERPROFILE
}
}
if ($gitRepo = Test-IfGit) {
$gitIcon = [char]0xe0a0
$key = $gitIcon + $gitRepo.Repo
if (-not $global:PSProfileConfig['_internal']['PathAliasMap'].ContainsKey($key)) {
$global:PSProfileConfig['_internal']['PathAliasMap'][$key] = $gitRepo.TopLevel
}
}
$leaf = Split-Path $Path -Leaf
if (-not $global:PSProfileConfig['_internal']['PathAliasMap'].ContainsKey('~')) {
$global:PSProfileConfig['_internal']['PathAliasMap']['~'] = $env:USERPROFILE
}
Write-Verbose "Alias map => JSON: $($global:PSProfileConfig['_internal']['PathAliasMap'] | ConvertTo-Json -Depth 5)"
$aliasKey = $null
$aliasValue = $null
foreach ($hash in $global:PSProfileConfig['_internal']['PathAliasMap'].GetEnumerator() | Sort-Object {$_.Value.Length} -Descending) {
if ($Path -like "$($hash.Value)*") {
$Path = $Path.Replace($hash.Value,$hash.Key)
$aliasKey = $hash.Key
$aliasValue = $hash.Value
Write-Verbose "AliasKey [$aliasKey] || AliasValue [$aliasValue]"
break
}
}
}
catch {
Write-Error $_
return $origPath
}
}
Process {
try {
if ($null -ne $aliasKey -and $origPath -eq $aliasValue) {
Write-Verbose "Matched original path! Returning alias base path"
$finalPath = $Path
}
elseif ($null -ne $aliasKey) {
Write-Verbose "Matched alias key [$aliasKey]! Returning path alias with leaf"
$drive = "$($aliasKey)\"
$finalPath = if ((Split-Path $origPath -Parent) -eq $aliasValue) {
"$($drive)$($leaf)"
}
else {
"$($drive)$([char]0x2026)\$($leaf)"
}
}
else {
$drive = (Get-Location).Drive.Name + ':\'
Write-Verbose "Matched base drive [$drive]! Returning base path"
$finalPath = if ($Path -eq $drive) {
$drive
}
elseif ((Split-Path $Path -Parent) -eq $drive) {
"$($drive)$($leaf)"
}
else {
"$($drive)..\$($leaf)"
}
}
if ($DirectorySeparator -notin @($null,([System.IO.Path]::DirectorySeparatorChar))) {
$finalPath.Replace(([System.IO.Path]::DirectorySeparatorChar),$DirectorySeparator)
}
else {
$finalPath
}
}
catch {
Write-Error $_
return $origPath
}
}
}
function global:Get-Elapsed {
[CmdletBinding()]
param(
[Parameter()]
[int]
$Id,
[Parameter()]
[string]
$Format = "{0:h\:mm\:ss\.ffff}"
)
$null = $PSBoundParameters.Remove("Format")
$LastCommand = Get-History -Count 1 @PSBoundParameters
if (!$LastCommand) {
return "0:00:00.0000"
}
elseif ($null -ne $LastCommand.Duration) {
$Format -f $LastCommand.Duration
}
else {
$Duration = $LastCommand.EndExecutionTime - $LastCommand.StartExecutionTime
$Format -f $Duration
}
}
function global:Switch-Prompt {
[CmdletBinding()]
Param (
[parameter(Position = 0,ValueFromPipeline)]
[ValidateSet('Basic','BasicPlus','Original','Clean','Fast','Demo','Slim','Rayner','Full','PowerLine')]
[String]
$Prompt = 'Basic',
[parameter()]
[Alias('ng')]
[switch]
$NoGit,
[parameter()]
[Alias('nc')]
[switch]
$NoClear
)
Begin {
if (-not $NoClear) {
if (-not (Test-Path Env:\PSProfileClear) -or (($env:PSProfileClear -as [int]) -as [bool])) {
Clear-Host
}
}
if (-not $PSBoundParameters.ContainsKey('Prompt') -and $MyInvocation.InvocationName -in @('Set-DemoPrompt','Start-Demo','demo')) {
$Prompt = 'Demo'
$NoGit = $true
}
if ($Prompt -eq 'Fast') {
$Prompt = 'Slim'
$NoGit = $true
}
elseif ($Prompt -in @('Clean','Basic')) {
$NoGit = $true
}
elseif ($Prompt -in @('Full','PowerLine')) {
Import-Module PowerLine
Set-PowerLinePrompt -PowerLineFont -Verbose:$false
}
if (-not $NoGit) {
Import-Module posh-git -Verbose:$false
$GitPromptSettings.EnableWindowTitle = "Repo Info: "
}
$global:PreviousPrompt = if ($global:CurrentPrompt) {
$global:CurrentPrompt
}
else {
$null
}
$global:CurrentPrompt = $Prompt
$global:_useGit = -not $NoGit
}
Process {
if ($Prompt) {
Write-Verbose "Setting prompt to [$Prompt]"
switch ($Prompt) {
Slim {
<# Appearance:
[#12] [0:00:00.0347] ~\Personal-Settings [master ≡ +3 ~3 -1 !]
[PS 6.2]>
#>
function global:prompt {
$lastStatus = $?
$lastColor = if ($lastStatus -eq $true) {
'Green'
}
else {
"Red"
}
Write-Host "[" -NoNewline
Write-Host -ForegroundColor Cyan "#$($MyInvocation.HistoryId)" -NoNewline
Write-Host "] " -NoNewline
Write-Host "[" -NoNewline
Write-Host -ForegroundColor $lastColor ("{0}" -f (Get-Elapsed)) -NoNewline
Write-Host "] [" -NoNewline
Write-Host ("{0}" -f $(Get-PathAlias)) -NoNewline -ForegroundColor DarkYellow
Write-Host "]" -NoNewline
if (Test-IfGit) {
Write-VcsStatus
}
Write-Host "`n[" -NoNewLine
$verColor = @{
ForegroundColor = if ($PSVersionTable.PSVersion.Major -eq 7) {
'Yellow'
}
elseif ($PSVersionTable.PSVersion.Major -eq 6) {
'Magenta'
}
else {
'Cyan'
}
}
Write-Host @verColor ("PS {0}" -f (Get-PSVersion $global:PSProfileConfig.Settings.PSVersionStringLength)) -NoNewline
Write-Host "]" -NoNewLine
$('>' * ($nestedPromptLevel + 1) + ' ')
}
}
Clean {
$global:CleanNumber = 0
function global:prompt {
$global:CleanNumber++
-join @(
'[CLN#'
$global:CleanNumber
'] ['
[Math]::Round((Get-History -Count 1).Duration.TotalMilliseconds,0)
'ms] '
$(Get-PathAlias)
("`n[PS {0}" -f (Get-PSVersion $global:PSProfileConfig.Settings.PSVersionStringLength))
']>> '
)
}
}
Basic {
function global:prompt {
"PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) ";
# .Link
# https://go.microsoft.com/fwlink/?LinkID=225750
# .ExternalHelp System.Management.Automation.dll-help.xml
}
}
BasicPlus {
function global:prompt {
-join @(
'<# PS {0} | ' -f (Get-PSVersion $global:PSProfileConfig.Settings.PSVersionStringLength)
Get-PathAlias
' #> '
)
}
}
Original {
function global:prompt {
$ra = [char]0xe0b0
$fg = @{
ForegroundColor = $Host.UI.RawUI.BackgroundColor
}
$cons = if ($psEditor) {
'Code'
}
elseif ($env:ConEmuPID) {
'ConEmu'
}
else {
'PS'
}
switch ($PSVersionTable.PSVersion.Major) {
5 {
$idColor = 'Green'
$verColor = 'Cyan'
}
6 {
$idColor = 'Cyan'
$verColor = 'Green'
}
7 {
$idColor = 'Cyan'
$verColor = 'Yellow'
}
}
Write-Host @fg -BackgroundColor $idColor "$ra[$($MyInvocation.HistoryId)]" -NoNewline
Write-Host -ForegroundColor $idColor $ra -NoNewline
Write-Host @fg -BackgroundColor $verColor "$ra[$("PS {0}" -f (Get-PSVersion $global:PSProfileConfig.Settings.PSVersionStringLength))]" -NoNewline
Write-Host -ForegroundColor $verColor $ra -NoNewline
if ($global:_useGit -and $PWD.Path -notlike "G:\GDrive\GoogleApps*" -and (git config -l --local *>&1) -notmatch '^fatal') {
Write-Host @fg -BackgroundColor Yellow "$ra[$(Get-Elapsed) @ $(Get-Date -Format T)]" -NoNewline
Write-Host -ForegroundColor Yellow $ra -NoNewline
Write-VcsStatus
Write-Host ""
}
else {
Write-Host @fg -BackgroundColor Yellow "$ra[$(Get-Elapsed) @ $(Get-Date -Format T)]" -NoNewline
Write-Host -ForegroundColor Yellow $ra
}
Write-Host @fg -BackgroundColor Magenta "$ra[$(Get-PathAlias)]" -NoNewline
Write-Host -ForegroundColor Magenta $ra -NoNewline
Write-Host "`n[I " -NoNewline
Write-Host -ForegroundColor Red "$([char]9829)" -NoNewline
" $cons]$('>' * ($nestedPromptLevel + 1)) "
}
}
Rayner {
<# Adapted from @thomasrayner's dev-workstation prompt:
https://github.com/thomasrayner/dev-workstation/blob/master/prompt.ps1
#>
<# Appearance (looks better in full color):
0004»1CPSGSuitemaster 0:00:00.018210:52:23 PM
PS 6.2>
#>
$forePromptColor = 0
[System.Collections.Generic.List[ScriptBlock]]$global:PromptRight = @(
# right aligned
{ "$foreground;${errorStatus}m{0}" -f $lArrow }
{ "$foreground;${forePromptColor}m$background;${errorStatus}m{0}" -f $(Get-Elapsed) }
{ "$foreground;7m$background;${errorStatus}m{0}" -f $lArrow }
{ "$foreground;0m$background;7m{0}" -f $(get-date -format "hh:mm:ss tt") }
)
[System.Collections.Generic.List[ScriptBlock]]$global:PromptLeft = @(
# left aligned
{ "$foreground;${forePromptColor}m$background;${global:platform}m{0}" -f $('{0:d4}' -f $MyInvocation.HistoryId) }
{ "$background;22m$foreground;${global:platform}m{0}" -f $($rArrow) }
{ "$background;22m$foreground;${forePromptColor}m{0}" -f $(if ($pushd = (Get-Location -Stack).count) {
"$([char]187)" + $pushd
}) }
{ "$foreground;22m$background;5m{0}" -f $rArrow }
{ "$background;5m$foreground;${forePromptColor}m{0}" -f $($pwd.Drive.Name) }
{ "$background;14m$foreground;5m{0}" -f $rArrow }
{ "$background;14m$foreground;${forePromptColor}m{0}$escape[0m" -f $(Split-Path $pwd -leaf) }
)
function global:prompt {
$global:errorStatus = if ($?) {
22
}
else {
1
}
$global:platform = if ($isWindows) {
11
}
else {
117
}
$global:lArrow = [char]0xe0b2
$global:rArrow = [char]0xe0b0
$escape = "$([char]27)"
$foreground = "$escape[38;5"
$background = "$escape[48;5"
$prompt = ''
$gitTest = $global:_useGit -and $PWD.Path -notlike "G:\GDrive\GoogleApps*" -and (git config -l --local *>&1) -notmatch '^fatal'
if ($gitTest) {
$branch = git symbolic-ref --short -q HEAD
$aheadbehind = git status -sb
$distance = ''
if (-not [string]::IsNullOrEmpty($(git diff --staged))) {
$branchbg = 3
}
else {
$branchbg = 5
}
if (-not [string]::IsNullOrEmpty($(git status -s))) {
$arrowfg = 3
}
else {
$arrowfg = 5
}
if ($aheadbehind -match '\[\w+.*\w+\]$') {
$ahead = [regex]::matches($aheadbehind, '(?<=ahead\s)\d+').value
$behind = [regex]::matches($aheadbehind, '(?<=behind\s)\d+').value
$distance = "$background;15m$foreground;${arrowfg}m{0}$escape[0m" -f $rArrow
if ($ahead) {
$distance += "$background;15m$foreground;${forePromptColor}m{0}$escape[0m" -f "a$ahead"
}
if ($behind) {
$distance += "$background;15m$foreground;${forePromptColor}m{0}$escape[0m" -f "b$behind"
}
$distance += "$foreground;15m{0}$escape[0m" -f $rArrow
}
else {
$distance = "$foreground;${arrowfg}m{0}$escape[0m" -f $rArrow
}
[System.Collections.Generic.List[ScriptBlock]]$gitPrompt = @(
{ "$background;${branchbg}m$foreground;14m{0}$escape[0m" -f $rArrow }
{ "$background;${branchbg}m$foreground;${forePromptColor}m{0}$escape[0m" -f $branch }
{ "{0}$escape[0m" -f $distance }
)
$prompt = -join @($global:PromptLeft + $gitPrompt + { " " }).Invoke()
}
else {
$prompt = -join @($global:PromptLeft + { "$foreground;14m{0}$escape[0m" -f $rArrow } + { " " }).Invoke()
}
$rightPromptString = -join ($global:promptRight).Invoke()
$offset = $global:host.UI.RawUI.BufferSize.Width - 24
$returnedPrompt = -join @($prompt, "$escape[${offset}G", $rightPromptString, "$escape[0m" + ("`n`r`PS {0}.{1}> " -f $PSVersionTable.PSVersion.Major,$PSVersionTable.PSVersion.Minor))
$returnedPrompt
}
}
Demo {
<# Appearance:
CMD# [2] | Dir: [~\Personal-Settings] | Last: [0:00:00.0087] | Git: [master ≡ +3 ~3 -1 !]
PS [6.2]>
#>
function global:prompt {
$lastStatus = $?
Write-Host "CMD# " -NoNewline
Write-Host -ForegroundColor Green "[$($MyInvocation.HistoryId)] " -NoNewline
#Write-Host -ForegroundColor Cyan "[$((Get-Location).Path.Replace($env:HOME,'~'))] " -NoNewline
$lastColor = if ($lastStatus -eq $true) {
"Yellow"
}
else {
"Red"
}
Write-Host "| Dir: " -NoNewLine
Write-Host -ForegroundColor Cyan "[$(Get-PathAlias)] " -NoNewline
Write-Host "| Last: " -NoNewLine
Write-Host -ForegroundColor $lastColor "[$(Get-Elapsed)] " -NoNewline
if ($global:_useGit -and $PWD.Path -notlike "G:\GDrive\GoogleApps*" -and (git config -l --local *>&1) -notmatch '^fatal') {
Write-Host "| Git:" -NoNewLine
Write-VcsStatus
}
Write-Host "`nPS " -NoNewline
$verColor = if ($PSVersionTable.PSVersion.Major -lt 6) {
@{
ForegroundColor = 'Cyan'
BackgroundColor = $host.UI.RawUI.BackgroundColor
}
}
elseif ($PSVersionTable.PSVersion.Major -eq 6) {
@{
ForegroundColor = $host.UI.RawUI.BackgroundColor
BackgroundColor = 'Cyan'
}
}
elseif ($PSVersionTable.PSVersion.Major -eq 7) {
@{
ForegroundColor = $host.UI.RawUI.BackgroundColor
BackgroundColor = 'Yellow'
}
}
Write-Host @verColor ("[{0}]" -f (Get-PSVersion $global:PSProfileConfig.Settings.PSVersionStringLength)) -NoNewline
('>' * ($nestedPromptLevel + 1)) + ' '
}
}
PowerLine {
Set-PowerLinePrompt -PowerLineFont -SetCurrentDirectory -RestoreVirtualTerminal -Newline -Timestamp -Colors ([PoshCode.Pansies.RgbColor]::ConsolePalette)
Add-PowerLineBlock { if ($pushed = (Get-Location -Stack).count) {
"&raquo;$pushed"
} } -Index 1
Add-PowerLineBlock { Write-VcsStatus } -Index 3
}
Full {
if ( -not $env:ConEmuPID ) {
function global:prompt {
$E = "$([char]27)"
$F = "$E[38;5"
$B = "$E[48;5"
"$B;255m$F;0mI $F;1m$([char]9829) $F;0mPS $F;0m$B;255m$([char]8250)$E[0m "
}
}
else {
[ScriptBlock[]]$global:Prompt = @(
# right aligned
{ " " * ($Host.UI.RawUI.BufferSize.Width - 29) }
{ "$F;${er}m{0}" -f [char]0xe0b2 }
{ "$F;15m$B;${er}m{0}" -f $(if (@(get-history).Count -gt 0) {
(get-history)[-1] | ForEach-Object { "{0:c}" -f (new-timespan $_.StartExecutionTime $_.EndExecutionTime) }
}
else {
'00:00:00.0000000'
}) }
{ "$F;7m$B;${er}m{0}" -f [char]0xe0b2 }
{ "$F;0m$B;7m{0}" -f $(get-date -format "hh:mm:ss tt") }
# left aligned
{ "$F;15m$B;117m{0}" -f $('{0:d4}' -f $MyInvocation.HistoryId) }
{ "$B;22m$F;117m{0}" -f $([char]0xe0b0) }
{ "$B;22m$F;15m{0}" -f $(if ($pushd = (Get-Location -Stack).count) {
"$([char]187)" + $pushd
}) }
{ "$F;22m$B;5m{0}" -f $([char]0xe0b0) }
{ "$B;5m$F;15m{0}" -f $($pwd.Drive.Name) }
{ "$B;20m$F;5m{0}" -f $([char]0xe0b0) }
{ "$B;20m$F;15m{0}$E[0m" -f $(Split-Path $pwd -leaf) }
{ "$F;20m{0}$E[0m" -f $([char]0xe0b0) }
)
function global:prompt {
$global:er = if ($?) {
22
}
else {
1
}
$E = "$([char]27)"
$F = "$E[38;5"
$B = "$E[48;5"
-join $global:Prompt.Invoke()
}
}
}
}
}
}
}
Set-Alias -Name sprompt -Value Switch-Prompt -Option AllScope -Force
Set-Alias -Name pro -Value Switch-Prompt -Option AllScope -Force
if ($null -ne (Get-Module PSReadline)) {
Set-PSReadLineKeyHandler -Chord Tab -Function MenuComplete
Set-PSReadLineOption -HistorySearchCursorMovesToEnd
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward
Set-PSReadLineKeyHandler -Chord 'Ctrl+W' -Function BackwardKillWord
Set-PSReadLineKeyHandler -Chord 'Ctrl+z' -Function MenuComplete
Set-PSReadLineKeyHandler -Chord 'Ctrl+D' -Function KillWord
Set-PSReadLineKeyHandler -Chord 'Ctrl+D,Ctrl+C' -Function CaptureScreen
if ($PSVersionTable.PSVersion.Major -le 5 -or ($PSVersionTable.PSVersion.Major -ge 7 -and $IsWindows)) {
Set-PSReadLineKeyHandler -Key F7 `
-BriefDescription History `
-LongDescription 'Show command history' `
-ScriptBlock {
$pattern = $null
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$pattern, [ref]$null)
if ($pattern) {
$pattern = [regex]::Escape($pattern)
}
$history = [System.Collections.ArrayList]@(
$last = ''
$lines = ''
foreach ($line in [System.IO.File]::ReadLines((Get-PSReadLineOption).HistorySavePath)) {
if ($line.EndsWith('`')) {
$line = $line.Substring(0, $line.Length - 1)
$lines = if ($lines) {
"$lines`n$line"
}
else {
$line
}
continue
}
if ($lines) {
$line = "$lines`n$line"
$lines = ''
}
if (($line -cne $last) -and (!$pattern -or ($line -match $pattern))) {
$last = $line
$line
}
}
)
$history.Reverse()
$command = $history | Out-GridView -Title History -PassThru
if ($command) {
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
[Microsoft.PowerShell.PSConsoleReadLine]::Insert(($command -join "`n"))
}
}
}
Set-PSReadLineKeyHandler -Key Backspace `
-BriefDescription SmartBackspace `
-LongDescription "Delete previous character or matching quotes/parens/braces" `
-ScriptBlock {
param($key, $arg)
$line = $null
$cursor = $null
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
if ($cursor -gt 0) {
$toMatch = $null
if ($cursor -lt $line.Length) {
switch ($line[$cursor]) {
<#case#> '"' {
$toMatch = '"'; break
}
<#case#> "'" {
$toMatch = "'"; break
}
<#case#> ')' {
$toMatch = '('; break
}
<#case#> ']' {
$toMatch = '['; break
}
<#case#> '}' {
$toMatch = '{'; break
}
}
}
if ($toMatch -ne $null -and $line[$cursor - 1] -eq $toMatch) {
[Microsoft.PowerShell.PSConsoleReadLine]::Delete($cursor - 1, 2)
}
else {
[Microsoft.PowerShell.PSConsoleReadLine]::BackwardDeleteChar($key, $arg)
}
}
}
Set-PSReadLineKeyHandler -Key Alt+w `
-BriefDescription SaveInHistory `
-LongDescription "Save current line in history but do not execute" ` `
-ScriptBlock {
param($key, $arg)
$line = $null
$cursor = $null
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
[Microsoft.PowerShell.PSConsoleReadLine]::AddToHistory($line)
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
}
# Insert text from the clipboard as a here string
Set-PSReadLineKeyHandler -Key Ctrl+Shift+v `
-BriefDescription PasteAsHereString `
-LongDescription "Paste the clipboard text as a here string" `
-ScriptBlock {
param($key, $arg)
Add-Type -Assembly PresentationCore
if ([System.Windows.Clipboard]::ContainsText()) {
# Get clipboard text - remove trailing spaces, convert \r\n to \n, and remove the final \n.
$text = ([System.Windows.Clipboard]::GetText() -replace "\p{Zs}*`r?`n","`n").TrimEnd()
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("@'`n$text`n'@")
}
else {
[Microsoft.PowerShell.PSConsoleReadLine]::Ding()
}
}
# Sometimes you want to get a property of invoke a member on what you've entered so far
# but you need parens to do that. This binding will help by putting parens around the current selection,
# or if nothing is selected, the whole line.
Set-PSReadLineKeyHandler -Key 'Alt+(','Alt+{','Alt+[','Alt+"',"Alt+'" `
-BriefDescription WrapSelection `
-LongDescription "Put parenthesis/brackets/braces/quotes around the selection or entire line and move the cursor to after the closing parenthesis" `
-ScriptBlock {
param($key, $arg)
switch -Regex ($key.KeyChar) {
'\(' {
$openChar = [char]'('
$closeChar = [char]')'
break
}
'\{' {
$openChar = [char]'{'
$closeChar = [char]'}'
break
}
'\[' {
$openChar = [char]'['
$closeChar = [char]']'
break
}
'\"' {
$openChar = $closeChar = [char]'"'
break
}
"\'" {
$openChar = $closeChar = [char]"'"
break
}
}
$selectionStart = $null
$selectionLength = $null
[Microsoft.PowerShell.PSConsoleReadLine]::GetSelectionState([ref]$selectionStart, [ref]$selectionLength)
$line = $null
$cursor = $null
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)
if ($selectionStart -ne -1) {
[Microsoft.PowerShell.PSConsoleReadLine]::Replace($selectionStart, $selectionLength, $openChar + $line.SubString($selectionStart, $selectionLength) + $closeChar)
[Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($selectionStart + $selectionLength + 2)
}
else {
[Microsoft.PowerShell.PSConsoleReadLine]::Replace(0, $line.Length, $openChar + $line + $closeChar)
[Microsoft.PowerShell.PSConsoleReadLine]::EndOfLine()
}
}
# This example will replace any aliases on the command line with the resolved commands.
Set-PSReadLineKeyHandler -Key "Alt+%" `
-BriefDescription ExpandAliases `
-LongDescription "Replace all aliases with the full command" `
-ScriptBlock {
param($key, $arg)
$ast = $null
$tokens = $null
$errors = $null
$cursor = $null
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$ast, [ref]$tokens, [ref]$errors, [ref]$cursor)
$startAdjustment = 0
foreach ($token in $tokens) {
if ($token.TokenFlags -band [System.Management.Automation.Language.TokenFlags]::CommandName) {
$alias = $ExecutionContext.InvokeCommand.GetCommand($token.Extent.Text, 'Alias')
if ($alias -ne $null) {
$resolvedCommand = $alias.ResolvedCommandName
if ($resolvedCommand -ne $null) {
$extent = $token.Extent
$length = $extent.EndOffset - $extent.StartOffset
[Microsoft.PowerShell.PSConsoleReadLine]::Replace(
$extent.StartOffset + $startAdjustment,
$length,
$resolvedCommand)
# Our copy of the tokens won't have been updated, so we need to
# adjust by the difference in length
$startAdjustment += ($resolvedCommand.Length - $length)
}
}
}
}
}
# F1 for help on the command line - naturally
Set-PSReadLineKeyHandler -Key F1 `
-BriefDescription CommandHelp `
-LongDescription "Open the help window for the current command" `
-ScriptBlock {
param($key, $arg)
$ast = $null
$tokens = $null
$errors = $null
$cursor = $null
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$ast, [ref]$tokens, [ref]$errors, [ref]$cursor)
$commandAst = $ast.FindAll( {
$node = $args[0]
$node -is [System.Management.Automation.Language.CommandAst] -and
$node.Extent.StartOffset -le $cursor -and
$node.Extent.EndOffset -ge $cursor
}, $true) | Select-Object -Last 1
if ($commandAst -ne $null) {
$commandName = $commandAst.GetCommandName()
if ($commandName -ne $null) {
$command = $ExecutionContext.InvokeCommand.GetCommand($commandName, 'All')
if ($command -is [System.Management.Automation.AliasInfo]) {
$commandName = $command.ResolvedCommandName
}
if ($commandName -ne $null) {
Get-Help $commandName -ShowWindow
}
}
}
}
#
# Ctrl+Shift+j then type a key to mark the current directory.
# Ctrj+j then the same key will change back to that directory without
# needing to type cd and won't change the command line.
#
$global:PSReadLineMarks = @{ }
Set-PSReadLineKeyHandler -Key Ctrl+Shift+j `
-BriefDescription MarkDirectory `
-LongDescription "Mark the current directory" `
-ScriptBlock {
param($key, $arg)
$key = [Console]::ReadKey($true)
$global:PSReadLineMarks[$key.KeyChar] = $pwd
}
Set-PSReadLineKeyHandler -Key Ctrl+j `
-BriefDescription JumpDirectory `
-LongDescription "Goto the marked directory" `
-ScriptBlock {
param($key, $arg)
$key = [Console]::ReadKey()
$dir = $global:PSReadLineMarks[$key.KeyChar]
if ($dir) {
cd $dir
[Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt()
}
}
Set-PSReadLineKeyHandler -Key Alt+j `
-BriefDescription ShowDirectoryMarks `
-LongDescription "Show the currently marked directories" `
-ScriptBlock {
param($key, $arg)
$global:PSReadLineMarks.GetEnumerator() | % {
[PSCustomObject]@{Key = $_.Key; Dir = $_.Value } } |
Format-Table -AutoSize | Out-Host
[Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt()
}
Set-PSReadLineOption -CommandValidationHandler {
param([CommandAst]$CommandAst)
switch ($CommandAst.GetCommandName()) {
'git' {
$gitCmd = $CommandAst.CommandElements[1].Extent
switch ($gitCmd.Text) {
'cmt' {
[Microsoft.PowerShell.PSConsoleReadLine]::Replace(
$gitCmd.StartOffset, $gitCmd.EndOffset - $gitCmd.StartOffset, 'commit')
}
}
}
}
}
}
<#
This is my ever growing collection of PowerShell / workstation configuration bits.
#>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment