Customising PowerShell Prompt

...
  • By Ivan Gavryliuk
  • In PowerShell
  • Posted 18/12/2019

PowerShell is extremely customisable. One of the things you can customise is the prompt (the place where you type commands to execute).

The Prompt function determines the appearance of the PowerShell prompt. PowerShell comes with a built-in Prompt function, but you can override it by defining your own Prompt function.

The Prompt function has the following syntax:

function Prompt { <function-body> }

The reponsibility of this function is to basically draw the prompt to the user. If you use PowerShell daily, you might want to change how the prompt looks. I'll just go over things I've personally customised.

"Shout"

First, I find the standard prompt too busy - I just want to display the "shout" symbol, like that

This is the only piece of code I need to add to override the built-in behavior:

function Prompt
{
    Write-Host "🔊"

    return " "
}

The sumbol is an Emoji, but that's OK to use it as I use Windows Terminal which supports Emoji everywhere, including tab headers!

Long Path

I'd also like to see as less as possible in my terminal, as long as I don't need this information. For this reason I'm putting current directory path in the tab name. However, when path is long, it will make tab as wide as my window, which is unnacceptable, as it will hide other tabs. The way I fixed it is the following:

  • if current path is shorter than 20 characters, i'll put the title in the tab name
  • otherwise, display only the last 20 chars in tab path, and display full path in the termianl window itself.

Here is how it looks like. Short title:

Long title:

And here is the snippet that programs this behavior:

function Prompt
{
    $maxTitleLength = 20

    $path = $pwd.ProviderPath
    $path = $path.Replace($env:HOME, "~")

    $title = $path
    if($title.Length -gt 2) {
        $title = $title.Substring(2)
    }
    $title = $title.Replace("\", "/")

    $shortTitle = $title
    if($shortTitle.Length -gt $maxTitleLength) {
        $shortTitle = "💨 $($shortTitle.Substring($shortTitle.Length - $maxTitleLength))"
    }

    $Host.UI.RawUI.WindowTitle = $shortTitle

    if($shortTitle -ne $title) {
        Write-Host "🌟 $path" -ForegroundColor Gray
    }

    Write-Host "🔊" -ForegroundColor Green -NoNewline

    return " "
}

Git Status

In addition to this, I'm using posh-git for displaying the git status if I'm located inside a git repo. Unfortunately, I don't like the standard prompt that posh-git enforces you to use, and it also cuts off quite a bit of screen space. What I'd like is to print out Git status on a separate line, and only if I'm in the git directory.

I'd like it to look like the following:

I'm not going to go into internals how posh-git works and just present the final solution.

First, in my powershell profile, in the beginning of the file:

Import-Module -Name posh-git -ErrorAction SilentlyContinue
$global:GitPromptSettings.BeforeStatus = ""
$global:GitPromptSettings.AfterStatus = ""
$global:GitPromptSettings.PathStatusSeparator = ""

This turns off some extra formatting I don't want to see.

And the final Prompt function enabling all 3 features described here:

function Prompt
{
    $realLASTEXITCODE = $LASTEXITCODE
    $maxTitleLength = 20

    $path = $pwd.ProviderPath
    $path = $path.Replace($env:HOME, "~")

    $poshGit = Write-VcsStatus

    $global:LASTEXITCODE = $realLASTEXITCODE

    $title = $path
    if($title.Length -gt 2) {
        $title = $title.Substring(2)
    }
    $title = $title.Replace("\", "/")

    $shortTitle = $title
    if($shortTitle.Length -gt $maxTitleLength) {
        $shortTitle = "💨 $($shortTitle.Substring($shortTitle.Length - $maxTitleLength))"
    }

    $Host.UI.RawUI.WindowTitle = $shortTitle

    if($shortTitle -ne $title) {
        Write-Host "🌟 $path" -ForegroundColor Gray
    }

    if($null -ne $poshGit) {
        Write-Host "🌴 " -NoNewline
        Write-Host $poshGit
    }

    if($IsAdmin) {
        Write-Host "[admin]" -ForegroundColor Red -NoNewline
    }

    Write-Host "🔊" -ForegroundColor Green -NoNewline

    return " "
}

Thanks for reading. If you would like to follow up with future posts please subscribe to my rss feed and/or follow me on twitter.