-
-
Save bradwilson/d965fa17fd3b3eee168270122e0f7da4 to your computer and use it in GitHub Desktop.
######## POSH-GIT | |
# ... Import-Module for posh-git here ... | |
# Background colors | |
$GitPromptSettings.AfterStash.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.AfterStatus.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.BeforeIndex.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.BeforeStash.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.BeforeStatus.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.BranchAheadStatusSymbol.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.BranchBehindAndAheadStatusSymbol.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.BranchBehindStatusSymbol.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.BranchColor.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.BranchGoneStatusSymbol.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.BranchIdenticalStatusSymbol.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.DefaultColor.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.DelimStatus.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.ErrorColor.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.IndexColor.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.LocalDefaultStatusSymbol.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.LocalStagedStatusSymbol.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.LocalWorkingStatusSymbol.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.StashColor.BackgroundColor = 0x5F5FAF | |
$GitPromptSettings.WorkingColor.BackgroundColor = 0x5F5FAF | |
# Foreground colors | |
$GitPromptSettings.AfterStash.ForegroundColor = 0xF49797 | |
$GitPromptSettings.AfterStatus.ForegroundColor = 0x729FCF | |
$GitPromptSettings.BeforeStash.ForegroundColor = 0xF49797 | |
$GitPromptSettings.BeforeStatus.ForegroundColor = 0x729FCF | |
$GitPromptSettings.BranchAheadStatusSymbol.ForegroundColor = 0x8AE234 | |
$GitPromptSettings.BranchBehindAndAheadStatusSymbol.ForegroundColor = 0xFCE94F | |
$GitPromptSettings.BranchBehindStatusSymbol.ForegroundColor = 0xF49797 | |
$GitPromptSettings.BranchColor.ForegroundColor = 0xFBFBFB | |
$GitPromptSettings.BranchGoneStatusSymbol.ForegroundColor = 0x729FCF | |
$GitPromptSettings.BranchIdenticalStatusSymbol.ForegroundColor = 0x729FCF | |
$GitPromptSettings.DefaultColor.ForegroundColor = 0xB5BBAE | |
$GitPromptSettings.DelimStatus.ForegroundColor = 0x729FCF | |
$GitPromptSettings.ErrorColor.ForegroundColor = 0xF49797 | |
$GitPromptSettings.IndexColor.ForegroundColor = 0x2EC3C3 | |
$GitPromptSettings.StashColor.ForegroundColor = 0xF49797 | |
$GitPromptSettings.WorkingColor.ForegroundColor = 0xFCE94F | |
# Prompt shape | |
$GitPromptSettings.AfterStatus.Text = " " | |
$GitPromptSettings.BeforeStatus.Text = " " | |
$GitPromptSettings.BranchAheadStatusSymbol.Text = "" | |
$GitPromptSettings.BranchBehindStatusSymbol.Text = "" | |
$GitPromptSettings.BranchGoneStatusSymbol.Text = "" | |
$GitPromptSettings.BranchBehindAndAheadStatusSymbol.Text = "" | |
$GitPromptSettings.BranchIdenticalStatusSymbol.Text = "" | |
$GitPromptSettings.BranchUntrackedText = "" | |
$GitPromptSettings.DelimStatus.Text = " ॥" | |
$GitPromptSettings.LocalStagedStatusSymbol.Text = "" | |
$GitPromptSettings.LocalWorkingStatusSymbol.Text = "" | |
$GitPromptSettings.PathStatusSeparator = "" | |
$GitPromptSettings.EnableStashStatus = $false | |
$GitPromptSettings.ShowStatusWhenZero = $false | |
######## INI FILE PARSER | |
function parseIniFile { | |
[CmdletBinding()] | |
param( | |
[Parameter(Position = 0)] | |
[String] $Inputfile | |
) | |
if ($Inputfile -eq "") { | |
Write-Error "Ini File Parser: No file specified or selected to parse." | |
Break | |
} | |
else { | |
$ContentFile = Get-Content $Inputfile | |
# commented Section | |
$COMMENT_CHARACTERS = ";" | |
# match section header | |
$HEADER_REGEX = "\[+[A-Z0-9._ %<>/#+-]+\]" | |
$OccurenceOfComment = 0 | |
$ContentComment = $ContentFile | Where-Object { ($_ -match "^\s*$COMMENT_CHARACTERS") -or ($_ -match "^$COMMENT_CHARACTERS") } | ForEach-Object { | |
[PSCustomObject]@{ Comment = $_ ; | |
Index = [Array]::IndexOf($ContentFile, $_) | |
} | |
$OccurenceOfComment++ | |
} | |
$COMMENT_INI = @() | |
foreach ($COMMENT_ELEMENT in $ContentComment) { | |
$COMMENT_OBJ = New-Object PSObject | |
$COMMENT_OBJ | Add-Member -type NoteProperty -name Index -value $COMMENT_ELEMENT.Index | |
$COMMENT_OBJ | Add-Member -type NoteProperty -name Comment -value $COMMENT_ELEMENT.Comment | |
$COMMENT_INI += $COMMENT_OBJ | |
} | |
$CONTENT_USEFUL = $ContentFile | Where-Object { ($_ -notmatch "^\s*$COMMENT_CHARACTERS") -or ($_ -notmatch "^$COMMENT_CHARACTERS") } | |
$ALL_SECTION_HASHTABLE = $CONTENT_USEFUL | Where-Object { $_ -match $HEADER_REGEX } | ForEach-Object { [PSCustomObject]@{ Section = $_ ; Index = [Array]::IndexOf($CONTENT_USEFUL, $_) } } | |
#$ContentUncomment | Select-String -AllMatches $HEADER_REGEX | Select-Object -ExpandProperty Matches | |
$SECTION_INI = @() | |
foreach ($SECTION_ELEMENT in $ALL_SECTION_HASHTABLE) { | |
$SECTION_OBJ = New-Object PSObject | |
$SECTION_OBJ | Add-Member -type NoteProperty -name Index -value $SECTION_ELEMENT.Index | |
$SECTION_OBJ | Add-Member -type NoteProperty -name Section -value $SECTION_ELEMENT.Section | |
$SECTION_INI += $SECTION_OBJ | |
} | |
$INI_FILE_CONTENT = @() | |
$NBR_OF_SECTION = $SECTION_INI.count | |
$NBR_MAX_LINE = $CONTENT_USEFUL.count | |
#********************************************* | |
# select each lines and value of each section | |
#********************************************* | |
for ($i = 1; $i -le $NBR_OF_SECTION ; $i++) { | |
if ($i -ne $NBR_OF_SECTION) { | |
if (($SECTION_INI[$i - 1].Index + 1) -eq ($SECTION_INI[$i].Index )) { | |
$CONVERTED_OBJ = @() #There is nothing between the two section | |
} | |
else { | |
$SECTION_STRING = $CONTENT_USEFUL | Select-Object -Index (($SECTION_INI[$i - 1].Index + 1)..($SECTION_INI[$i].Index - 1)) | Out-String | |
$CONVERTED_OBJ = convertfrom-stringdata -stringdata $SECTION_STRING | |
} | |
} | |
else { | |
if (($SECTION_INI[$i - 1].Index + 1) -eq $NBR_MAX_LINE) { | |
$CONVERTED_OBJ = @() #There is nothing between the two section | |
} | |
else { | |
$SECTION_STRING = $CONTENT_USEFUL | Select-Object -Index (($SECTION_INI[$i - 1].Index + 1)..($NBR_MAX_LINE - 1)) | Out-String | |
$CONVERTED_OBJ = convertfrom-stringdata -stringdata $SECTION_STRING | |
} | |
} | |
$CURRENT_SECTION = New-Object PSObject | |
$CURRENT_SECTION | Add-Member -Type NoteProperty -Name Section -Value $SECTION_INI[$i - 1].Section | |
$CURRENT_SECTION | Add-Member -Type NoteProperty -Name Content -Value $CONVERTED_OBJ | |
$INI_FILE_CONTENT += $CURRENT_SECTION | |
} | |
return $INI_FILE_CONTENT | |
} | |
} | |
######## FIND A FILE/PATTERN HERE OR IN ANY PARENT FOLDER | |
function findHereOrParent { | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory = $true)] | |
[string[]] $filePaths | |
) | |
try { | |
$currentFolder = Get-Location | |
while ($currentFolder -ne "") { | |
foreach ($filePath in $filePaths) { | |
if ((Get-ChildItem -ErrorAction Ignore -LiteralPath $currentFolder -Filter $filePath).Count -gt 0) { | |
return $true | |
} | |
} | |
$currentFolder = Split-Path $currentFolder | |
} | |
} | |
catch { | |
$Error.Clear() | |
} | |
return $false | |
} | |
######## PROMPT | |
set-content Function:prompt { | |
# Start with a blank line, for breathing room :) | |
Write-Host "" | |
# Reset the foreground color to default | |
$Host.UI.RawUI.ForegroundColor = "Gray" | |
Write-Host " " -NoNewLine | |
# Write ERR for any PowerShell errors | |
if ($Error.Count -ne 0) { | |
Write-Host "$([char]27)[38;5;131;40m$([char]27)[38;5;227;48;5;131m ERR $([char]27)[38;5;131;40m" -NoNewLine | |
$Error.Clear() | |
} | |
# Write Ctrl+C separately | |
if ($LASTEXITCODE -eq -1073741510) { | |
Write-Host "$([char]27)[38;5;131;40m$([char]27)[38;5;227;48;5;131m Ctrl-C $([char]27)[38;5;131;40m" -NoNewLine | |
$LASTEXITCODE = "" | |
} | |
# Write non-zero exit code from last launched process | |
if ($LASTEXITCODE -ne "") { | |
Write-Host "$([char]27)[38;5;131;40m$([char]27)[38;5;227;48;5;131m $LASTEXITCODE $([char]27)[38;5;131;40m" -NoNewLine | |
$LASTEXITCODE = "" | |
} | |
# Write any custom prompt environment (f.e., from vs2017.ps1) | |
if (get-content variable:\PromptEnvironment -ErrorAction Ignore) { | |
Write-Host "$([char]27)[38;5;183;40m$([char]27)[38;5;54;48;5;183m$PromptEnvironment$([char]27)[38;5;183;40m" -NoNewLine | |
} | |
# Write Go version | |
if (($null -ne (Get-Command "go" -ErrorAction Ignore)) -and (findHereOrParent go.mod)) { | |
$goVersion = (& go version).split()[2].substring(2) | |
Write-Host "$([char]27)[38;5;80;48;5;0m$([char]27)[38;5;16;48;5;80m $goVersion $([char]27)[38;5;80;40m" -NoNewLine | |
} | |
# Write Rust version | |
if (($null -ne (Get-Command "rustc" -ErrorAction Ignore)) -and (findHereOrParent Cargo.toml)) { | |
$rustVersion = (& rustc --version).Split()[1] | |
Write-Host "$([char]27)[38;5;172;40m$([char]27)[38;5;231;48;5;172m $rustVersion $([char]27)[38;5;172;40m" -NoNewLine | |
} | |
# Write .NET SDK version | |
if (($null -ne (Get-Command "dotnet" -ErrorAction Ignore)) -and (findHereOrParent *.sln,*.csproj)) { | |
$dotNetVersion = (& dotnet --version) | |
Write-Host "$([char]27)[38;5;54;40m$([char]27)[38;5;254;48;5;54m $dotNetVersion $([char]27)[38;5;54;40m" -NoNewLine | |
} | |
# Write the current kubectl context | |
if ($null -ne (Get-Command "kubectl" -ErrorAction Ignore)) { | |
$currentContext = (& kubectl config current-context 2> $null) | |
if (($Error.Count -eq 0) -and ($currentContext -ne $null)) { | |
Write-Host "$([char]27)[38;5;242;40m$([char]27)[38;5;112;48;5;242m $([char]27)[38;5;254m$currentContext $([char]27)[38;5;242;40m" -NoNewLine | |
} | |
else { | |
$Error.Clear() | |
} | |
} | |
# Write the current public cloud Azure CLI subscription | |
# NOTE: You will need sed from somewhere (for example, from Git for Windows) | |
if (Test-Path ~/.azure/clouds.config) { | |
$cloudsConfig = parseIniFile ~/.azure/clouds.config | |
$azureCloud = $cloudsConfig | Where-Object { $_.Section -eq "[AzureCloud]" } | |
if ($null -ne $azureCloud) { | |
$currentSub = $azureCloud.Content.subscription | |
if ($null -ne $currentSub) { | |
$currentAccount = (Get-Content ~/.azure/azureProfile.json | ConvertFrom-Json).subscriptions | Where-Object { $_.id -eq $currentSub } | |
if ($null -ne $currentAccount) { | |
Write-Host "$([char]27)[38;5;30;40m$([char]27)[38;5;227;48;5;30m $([char]27)[38;5;254m$($currentAccount.name) $([char]27)[38;5;30;40m" -NoNewLine | |
} | |
} | |
} | |
} | |
# Write the current Git information | |
if ($null -ne (Get-Command "Get-GitDirectory" -ErrorAction Ignore)) { | |
if (Get-GitDirectory -ne $null) { | |
Write-Host "$([char]27)[38;5;61;40m$(Write-VcsStatus)$([char]27)[38;5;61;40m" -NoNewLine | |
} | |
} | |
# Write the current directory, with home folder normalized to ~ | |
$currentPath = (get-location).Path.replace($home, "~") | |
$idx = $currentPath.IndexOf("::") | |
if ($idx -gt -1) { $currentPath = $currentPath.Substring($idx + 2) } | |
$host.UI.RawUI.WindowTitle = $currentPath | |
Write-Host "$([char]27)[38;5;28;40m$([char]27)[38;5;227;48;5;28m $([char]27)[38;5;254m$currentPath " -NoNewline | |
# Reset LASTEXITCODE so we don't show it over and over again | |
$global:LASTEXITCODE = 0 | |
# Write one + for each level of the pushd stack | |
if ((get-location -stack).Count -gt 0) { | |
Write-Host ("$([char]27)[38;5;227;48;5;28m" + ("«" * ((get-location -stack).Count)) + " ") -NoNewLine | |
} | |
# Newline | |
Write-Host "$([char]27)[38;5;28;40m$([char]27)[30;40m $([char]27)[0m" | |
# Determine if the user is admin, so we color the prompt green or red | |
$isAdmin = $false | |
$isDesktop = ($PSVersionTable.PSEdition -eq "Desktop") | |
if ($isDesktop -or $IsWindows) { | |
$windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent() | |
$windowsPrincipal = new-object 'System.Security.Principal.WindowsPrincipal' $windowsIdentity | |
$isAdmin = $windowsPrincipal.IsInRole("Administrators") -eq 1 | |
} | |
else { | |
$isAdmin = ((& id -u) -eq 0) | |
} | |
if ($isAdmin) { $color = "Red"; } | |
else { $color = "Green"; } | |
# Write PS> for desktop PowerShell, pwsh> for PowerShell Core | |
if ($isDesktop) { | |
Write-Host " PS>" -NoNewLine -ForegroundColor $color | |
} | |
else { | |
Write-Host " pwsh>" -NoNewLine -ForegroundColor $color | |
} | |
# Always have to return something or else we get the default prompt | |
return " " | |
} |
param( | |
[string]$edition, | |
[string]$version = "2022", | |
[string]$basePath = "", | |
[switch]$noWeb = $false | |
) | |
function append-path { | |
param( | |
[string[]][Parameter(Mandatory = $true)]$pathsToAdd | |
) | |
$local:separator = ";" | |
if (($PSVersionTable.PSVersion.Major -gt 5) -and ($PSVersionTable.Platform -eq "Unix")) { | |
$local:separator = ":" | |
} | |
$env:PATH = $env:PATH + $local:separator + ($pathsToAdd -join $local:separator) | |
} | |
# Only support one prompt environment at a time | |
if ($PromptEnvironment -ne $null) { | |
write-host "error: Prompt is already in a custom environment." -ForegroundColor Red | |
exit 1 | |
} | |
# Look in the standard installation locations unless they override | |
if ($basePath -eq "") { | |
$basePath = join-path (join-path ${env:ProgramFiles(x86)} "Microsoft Visual Studio") $version | |
if ((test-path $basePath) -eq $false) { | |
$basePath = join-path (join-path ${env:ProgramFiles} "Microsoft Visual Studio") $version | |
} | |
} | |
if ((test-path $basePath) -eq $false) { | |
write-warning "Visual Studio $version is not installed in '$basePath'." | |
exit 1 | |
} | |
# If edition wasn't specified, see what's there, and bail out if there is more than 1 | |
if ($edition -eq "") { | |
$editions = (get-childitem $basePath | where-object { $_.PSIsContainer }) | |
if ($editions.Count -eq 0) { | |
write-warning "Visual Studio $version is not installed." | |
exit 1 | |
} | |
if ($editions.Count -gt 1) { | |
write-warning "Multiple editions of Visual Studio $version are installed. Please specify one of the editions ($($($editions | Foreach-Object { "'" + $_.Name + "'" }) -join ', ')) with the -edition switch." | |
exit 1 | |
} | |
$edition = $editions[0].Name | |
} | |
# Find VsDevCmd.bat | |
$path = join-path (join-path (join-path $basePath $edition) "Common7") "Tools" | |
if ((test-path $path) -eq $false) { | |
write-warning "Visual Studio $version edition '$edition' could not be found." | |
exit 1 | |
} | |
$cmdPath = join-path $path "VsDevCmd.bat" | |
if ((test-path $cmdPath) -eq $false) { | |
write-warning "File not found: $cmdPath" | |
exit 1 | |
} | |
# Run VsDevCmd.bat and then dump all environment variables, so we can | |
# overwrite ours with theirs | |
$tempFile = [IO.Path]::GetTempFileName() | |
cmd /c " `"$cmdPath`" && set > `"$tempFile`" " | |
Get-Content $tempFile | %{ | |
if ($_ -match "^(.*?)=(.*)$") { | |
Set-Content "env:\$($matches[1])" $matches[2] | |
} | |
} | |
# Optionally add the external web tools unless skipped | |
if ($noWeb -eq $false) { | |
$path = join-path (join-path (join-path $basePath $edition) "Web") "External" | |
if (test-path $path) { | |
append-path $path | |
} else { | |
write-warning "Path $path not found; specify -noWeb to skip searching for web tools" | |
} | |
} | |
# Set the prompt environment variable (printed in our prompt function) | |
$global:PromptEnvironment = " $version " |
param( | |
[string]$edition, | |
[string]$basePath = "", | |
[switch]$noWeb = $false | |
) | |
$folder = Split-Path $PSCommandPath | |
$script = Join-Path $folder "vs.ps1" | |
& $script -edition:$edition -version:"2017" -basePath:$basePath -noWeb:$noWeb |
param( | |
[string]$edition, | |
[string]$basePath = "", | |
[switch]$noWeb = $false | |
) | |
$folder = Split-Path $PSCommandPath | |
$script = Join-Path $folder "vs.ps1" | |
& $script -edition:$edition -version:"2019" -basePath:$basePath -noWeb:$noWeb |
param( | |
[string]$edition, | |
[string]$basePath = "", | |
[switch]$noWeb = $false | |
) | |
$folder = Split-Path $PSCommandPath | |
$script = Join-Path $folder "vs.ps1" | |
& $script -edition:$edition -version:"2022" -basePath:$basePath -noWeb:$noWeb |
param( | |
[string]$edition, | |
[string]$basePath = "", | |
[switch]$noWeb = $false | |
) | |
$folder = Split-Path $PSCommandPath | |
$script = Join-Path $folder "vs.ps1" | |
& $script -edition:$edition -version:"Preview" -basePath:$basePath -noWeb:$noWeb |
Potential enhancement for showing the current dotnet SDK version:
# Write the current dotnet version.
if ((Get-Command "dotnet" -ErrorAction Ignore) -ne $null) {
$dotnetVersion = (& dotnet --version 2> $null)
Write-Host " " -NoNewLine
Write-Host " ◉" -NoNewLine -BackgroundColor Gray -ForegroundColor Blue
Write-Host " $dotnetVersion " -NoNewLine -BackgroundColor Gray -ForegroundColor Black
}
Also, I found I could fairly consistently shave about 40 - 100ms off the rendering of the prompt by running the external commands (kubectl
, sed
, dotnet
, etc.) in parallel using PowerShell runspaces. It makes the script more complicated since you have to separate the retrieval of the data from the rendering of the data, but the prompt feels a little faster. Like:
$dotnetScript = {
# Get the current dotnet version.
$dotnetVersion = $null
if ((Get-Command "dotnet" -ErrorAction Ignore) -ne $null) {
$dotnetVersion = (& dotnet --version 2> $null)
}
return $dotnetVersion
}
$kubectlScript = {
# Get the current kubectl context.
$currentContext = $null
if ((Get-Command "kubectl" -ErrorAction Ignore) -ne $null) {
$currentContext = (& kubectl config current-context 2> $null)
}
return $currentContext
}
$azureScript = {
# Get the current public cloud Azure CLI subscription.
# NOTE: You will need sed from somewhere (for example, from Git for Windows).
$currentAccount = $null
$cloudConfigPath = Resolve-Path "~/.azure/clouds.config"
if ((Test-Path $cloudConfigPath) -and ((Get-Command "sed" -ErrorAction Ignore) -ne $null)) {
$currentSub = & sed -nr "/^\[AzureCloud\]/ { :l /^subscription[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" "$($cloudConfigPath.Path)"
if ($null -ne $currentSub) {
$currentAccount = (Get-Content ~/.azure/azureProfile.json | ConvertFrom-Json).subscriptions | Where-Object { $_.id -eq $currentSub } | Select-Object -ExpandProperty Name
}
}
return $currentAccount
}
# Create the set of jobs to run, each in a runspace. Not using RunspacePool
# because there aren't a lot of jobs and it's really hard to set the current
# working directory in a pool.
$scripts = @{ "azure" = $azureScript; "dotnet" = $dotnetScript; "kubectl" = $kubectlScript }
$jobs = @()
foreach ($key in $scripts.Keys) {
$thread = [powershell]::Create().AddScript($scripts[$key])
$runspace = [RunspaceFactory]::CreateRunspace()
$runspace.Open()
$runspace.SessionStateProxy.Path.SetLocation($pwd.Path) | Out-Null
$thread.Runspace = $runspace
$handle = $thread.BeginInvoke()
$jobs += @{ "Handle" = $handle; "Thread" = $thread; "Name" = $key }
}
while (@($jobs | Where-Object {$_.Handle.IsCompleted -ne $True}).count -gt 0) {
Start-Sleep -Milliseconds 1
}
$scriptReturnValues = @{}
foreach ($job in $jobs) {
$scriptReturnValues.Add($job.Name, $job.Thread.EndInvoke($job.Handle))
$job.Thread.Runspace.Close()
$job.Thread.Dispose()
}
if ($scriptReturnValues["dotnet"] -ne $null) {
Write-Host " " -NoNewLine
Write-Host " ◉" -NoNewLine -BackgroundColor Gray -ForegroundColor Blue
Write-Host " $($scriptReturnValues['dotnet']) " -NoNewLine -BackgroundColor Gray -ForegroundColor Black
}
if ($scriptReturnValues["kubectl"] -ne $null) {
Write-Host " " -NoNewLine
Write-Host " ▣" -NoNewLine -BackgroundColor DarkCyan -ForegroundColor Green
Write-Host " $($scriptReturnValues['kubectl']) " -NoNewLine -BackgroundColor DarkCyan -ForegroundColor White
}
if ($scriptReturnValues["azure"] -ne $null) {
Write-Host " " -NoNewLine
Write-Host " ☼" -NoNewLine -BackgroundColor DarkCyan -ForegroundColor Green
Write-Host " $($scriptReturnValues['azure']) " -NoNewLine -BackgroundColor DarkCyan -ForegroundColor White
}
I'm not using ConEmu so my glyphs aren't Nerd Font but you get the idea. I also can't guarantee I'm 100% handling all error conditions there so YMMV.
Thanks for all these suggestions!
Very nice! I had to add a small tweak to line 51 of vs.ps1
from $edition = $editions[0]
to $edition = $editions[0].Name
. From some contexts the value was the full path so it'd end up with C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\Tools\C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\Tools
and bail as the path would't exist.
# If edition wasn't specified, see what's there, and bail out if there is more than 1
if ($edition -eq "") {
$editions = (get-childitem $basePath | where-object { $_.PSIsContainer })
if ($editions.Count -eq 0) {
write-warning "Visual Studio $version is not installed."
exit 1
}
if ($editions.Count -gt 1) {
write-warning "Multiple editions of Visual Studio $version are installed. Please specify one of the editions ($($editions -join ', ')) with the -edition switch."
exit 1
}
$edition = $editions[0].Name
}
Thanks @thnk2wn, I also ran cross this recently, and I've updated the scripts!
First, thanks for this and the great blog article on it. I'm in the process of adopting some of this myself, though not using ConEmu - just plain PowerShell.
I noticed a couple of things that might help reduce the custom code you have to maintain, if you're interested.
~
- you can use the function fromposh-git
that does it for you:$currentPath = $GitPromptSettings.DefaultPromptPath.Expand().Text
VSSetup
PowerShell module that can be used to locate VS installs for 2017 (and, I think, 2019). It might be easier to use that than manually probe paths. Admittedly, I've only tried this on Windows.Import-VisualStudioVars
that makes use of theVSSetup
module and has support for the earlier versions of VS based on environment variables. That might also help.And something for the blog article, maybe: if you're not using ConEmu, it appears the Windows system hijacks
DarkMagenta
to mean "transparent" so the VS environment bit ends up showing with no background.