The Powershell and the Glory

In which I add a custom prompt by making a hack in the PowerShell profile.

As I have mentioned in previous posts, I use Oh My Posh to set the theme in Powershell. While working with Pulumi to create deployment stacks, I thought I could use a way to see which stack is the current one, i.e. to effectively have the output of pulumi stack --show-name appear in the prompt automatically.

Back in the old world, the agnoster theme was the prettiest. In my terminal at least, it looked quite a lot worse after upgrading to Oh-My-Posh 3, so I did exactly what they say in the documentation, I used Get-PoshThemes to look at all of them, exported the one I liked best into a json file and went to work.

Command

The naïve implementation would be to add a new segment in the prompt, using the segment type seemed to be “command”, which does what it says on the tin, it allows you to call a command and display the output, like it works in Bash.

        {
          "type": "command",
          "style": "powerline",
          "foreground": "#000000",
          "background": "#ffff00",
          "properties": {
            "shell": "powershell",
            "command": "pulumi stack --show-name"
          }
        },  

They do warn you that there will be performance implications, and – yes- on my 16 core desktop it still takes forever to start a process in PowerShell, so that didn’t seem to be a workable way forward. The suggested approach is to “abuse environment variables”, so… let’s?

Environment variable

I have previously made hacks to set window titles in cmder to work around iffy built-in support for showing the path as the tab name. The idea was to replace the built-in “cd” alias with a PowerShell function that also does dodgy stuff on the side apart from changing directory. In this case I would test if a pulumi.yaml file exists in the new directory, and in that case set the variable PULUMI_STACK to the output of pulumi stack --show-name, or set the variable to empty.

# --- other stuff
function Change-Directory() {
    param(
        [string]
        $directory
    )
    Set-Location $directory
    $env:PULUMI_STACK = ""
    if (Test-Path "pulumi.yaml") {
        $env:PULUMI_STACK = & pulumi stack --show-name
    }
}
# --- other stuff
Set-Alias -name cd -Value Change-Directory -Option AllScope

I of course don’t want to globally change this variable, I explicitly only care about the current terminal session, so hence I’m not trying to update the registry or anything like that. To read this variable and show a prompt, we then modify the theme json file to leverage the envvar block and to contain the following:

{
    "type": "envvar",
    "style": "powerline",
    "foreground": "#000000",
    "background": "#ffff00",
    "properties": {
       "var_name": "PULUMI_STACK"
    }
},  

After this work, the prompt is much faster, beyond acceptable, maybe even pleasant.