Skip to content

Instantly share code, notes, and snippets.

@VojtechStep
Last active October 5, 2022 05:27
Show Gist options
  • Save VojtechStep/9d2478a63c2c626c0173527b2f86f370 to your computer and use it in GitHub Desktop.
Save VojtechStep/9d2478a63c2c626c0173527b2f86f370 to your computer and use it in GitHub Desktop.
Powerline-style PowerShell prompt (git support and extensible)

About

Custom prompt for Windows PowerShell that implements the Powerline theme This prompt is inspired by the agnoster theme for oh-my-zsh

How to install

  • Install the Powerline-patched fonts for the icons to render correctly.
  • Download the gist files
  • Extract the archive to one of your PowerShell Profile folders (ex. %UserProfile%\Documents\WindowsPowerShell )
  • Open PowerShell
    The first time, it will ask you whether you want to run the scripts. The install.ps1 script will get called on the first run and it will make the files look like you created them, so this warning won't appear again. The script also cleans the directory so you'll be left off with just what you need.

How to modify

To modify colors and variables, edit the Config.ps1 script. Here, you can change the colors, glyphs and some switches for git and the theme. To add/remove segments, comment/uncomment the "print_*" function calls.

How to extend

To add your own segment, add a function, preferably, but not necessairly, to the PromptUtils.ps1 script and then call it from the "prompt" function in profile.ps1. To render the segment, call the "print_segment" function, which accepts 3 parameters: background color, foreground color and the text

#If this isn't the user using the shell, username@host will be displayed (if enabled)
$DEFAULT_USER='Adalbert'
#True to print username@host event if it's the default user
$PRINT_DEFAULT_USER=$FALSE
#Glyphs
$SEGMENT_DELIMETER_GLYPH=[char]0xE0B0 # î‚°
$PREV_CMD_FAIL_GLYPH=[char]0x2718 # ✘
$BGTASK_GLYPH=[char]0x2699 # âš™
$ELEVATED_GLYPH=[char]0x26A1 # âš¡
$GIT_BRANCH_GLYPH=[char]0xE0A0 # î‚ 
$GIT_DIRTY_GLYPH=[char]0x25CF # ●
$GIT_UNTRACKED_GLYPH=[char]0x271A # ✚
#True to collapse folder names between drive letter and current folder name
$COLLAPSE_DIR=$FALSE
#True to mark git repos with untracked files clean
$DISABLE_UNTRACKED_FILES_DIRTY=$FALSE
#True to only show the npm version if the current folder contains package.json
$NPM_HIDE_NO_PACKAGE=$TRUE
#Segment colors
$PRMT_NUM_BG='Black'
$PRMT_NUM_FG='Blue'
$CONTEXT_BG='Yellow'
$CONTEXT_FG='Black'
$DIR_BG='Blue'
$DIR_FG='Black'
$GIT_CLEAN_BG='Green'
$GIT_CLEAN_FG='Black'
$GIT_DIRTY_BG='Yellow'
$GIT_DIRTY_FG='Black'
$NPM_BG='Magenta'
$NPM_FG='Black'
Get-Content $PSScriptRoot\profile.ps1 > $PSScriptRoot\profile_.ps1
Get-Content $PSScriptRoot\Config.ps1 > $PSScriptRoot\Config_.ps1
Get-Content $PSScriptRoot\PromptUtils.ps1 > $PSScriptRoot\PromptUtils_.ps1
Move-Item $PSScriptRoot\profile_.ps1 $PSScriptRoot\profile.ps1 -Force
Move-Item $PSScriptRoot\Config_.ps1 $PSScriptRoot\Config.ps1 -Force
Move-Item $PSScriptRoot\PromptUtils_.ps1 $PSScriptRoot\PromptUtils.ps1 -Force
Remove-Item $PSScriptRoot\install.ps1
Remove-Item $PSScriptRoot\README.md
. $PSScriptRoot\PromptUtils.ps1
Function elevate_process() {
$file, [string]$arguments = $args
$psi = new-object System.Diagnostics.ProcessStartInfo $file;
$psi.Arguments = $arguments;
$psi.Verb = "runas";
$psi.WorkingDirectory = Get-Location;
[System.Diagnostics.Process]::Start($psi);
}
Function prompt {
print_status
# print_prompt_number
print_context
print_dir
print_npm
print_git
end_segment
return [char]0x200A
}
Set-Alias sudo elevate_process
$CURRENT_BG=$null
$NPM_VERSION=$null
. $PSScriptRoot\Config.ps1
if (Get-Command npm -ErrorAction SilentlyContinue) {
$Global:NPM_VERSION = $(npm --version)
}
if (Test-Path $PSScriptRoot\install.ps1) {
. $PSScriptRoot\install.ps1
}
Function print_segment($bg = 'Black', $fg = 'Blue', $str) {
if($CURRENT_BG -and $CURRENT_BG -ne $bg) {
Write-Host "$SEGMENT_DELIMETER_GLYPH" -ForegroundColor $CURRENT_BG -BackgroundColor $bg -NoNewline
}
$Global:CURRENT_BG = $bg
Write-Host $str -ForegroundColor $fg -BackgroundColor $bg -NoNewline
}
Function end_segment() {
Write-Host "$SEGMENT_DELIMETER_GLYPH" -ForegroundColor $CURRENT_BG -BackgroundColor Black -NoNewline
$Global:CURRENT_BG=$null
$Host.UI.RawUI.WindowTitle="Windows PowerShell v$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor)"
}
Function print_status() {
if (-Not $?) {
Write-Host "$PREV_CMD_FAIL_GLYPH " -ForegroundColor Red -NoNewline
$flag=$TRUE
}
Get-Job | % {
if ($_.State -eq "Running") {
Write-Host "$BGTASK_GLYPH " -ForegroundColor Cyan -NoNewline
$flag=$TRUE
}
}
if ((whoami /all | select-string S-1-16-12288) -ne $null) {
Write-Host "$ELEVATED_GLYPH " -ForegroundColor Yellow -NoNewline
$flag=$TRUE
}
if ($flag) {$Global:CURRENT_BG='Black'}
}
Function print_prompt_number() {
${Global:CNT_OF_PRMT}++
Write-Host '#' -NoNewline
print_segment $PRMT_NUM_BG $PRMT_NUM_FG $("000000000${GLOBAL:CNT_OF_PRMT}").ToString().Substring($("000000000${GLOBAL:CNT_OF_PRMT}").length-4 , 4)
}
Function print_context() {
if($PRINT_DEFAULT_USER -or ($DEFAULT_USER -ne ${env:UserName})) {
print_segment $CONTEXT_BG $CONTEXT_FG "${env:UserName}@${env:ComputerName}"
}
}
Function print_dir() {
if ($COLLAPSE_DIR -and ((($pwd).ToString().ToCharArray() | Where-Object {$_ -eq '\'} | Measure-Object).Count) -gt 1) {
print_segment $DIR_BG $DIR_FG " $($pwd.Drive.Root)..\$($pwd | Split-Path -Leaf)"
}
else {
print_segment $DIR_BG $DIR_FG " $pwd"
}
}
Function print_git() {
if(Get-Command git -ErrorAction SilentlyContinue) {
if ($(git rev-parse --is-inside-work-tree 2>$null)) {
$branch = $(git symbolic-ref HEAD 2>$null).ToString().Substring(11)
$gitStatus=$(git status | select -last 1)
if (($gitStatus -eq "nothing to commit, working directory clean") -or
(($gitStatus -eq "nothing added to commit but untracked files present (use `"git add`" to track)") -and $DISABLE_UNTRACKED_FILES_DIRTY)) {
print_segment $GIT_CLEAN_BG $GIT_CLEAN_FG "$GIT_BRANCH_GLYPH $branch"
}
elseif ($gitStatus -eq "nothing added to commit but untracked files present (use `"git add`" to track)") {
print_segment $GIT_DIRTY_BG $GIT_DIRTY_FG "$GIT_BRANCH_GLYPH $branch $GIT_UNTRACKED_GLYPH"
}
elseif ($gitStatus -eq "no changes added to commit (use `"git add`" and/or `"git commit -a`")") {
print_segment $GIT_DIRTY_BG $GIT_DIRTY_FG "$GIT_BRANCH_GLYPH $branch $GIT_DIRTY_GLYPH"
}
}
}
}
Function print_npm() {
if ((Get-Command npm -ErrorAction SilentlyContinue) -and (!$NPM_HIDE_NO_PACKAGE -or (Test-Path .\package.json))) {
print_segment $NPM_BG $NPM_FG "npm $NPM_VERSION"
}
}
@thistlillo
Copy link

Yes, I noticed that it has been a while since the last updates. So, thank you twice for your answer and your kindness. And thanks also for the link, I will evaluate it.

At the end (I do not know how) I was able to have the PowerLine prompt, but with an important (to me) missing piece: the active conda environment. I tried also another powerline, but it was missing conda as well.

Thanks again.

@VojtechStep
Copy link
Author

If you need the conda environment in the prompt, I think starship has you covered https://starship.rs/config/#conda

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment