Oh-my-posh3: Corrupted prompt after certain commands

Created on 17 Jan 2021  路  11Comments  路  Source: JanDeDobbeleer/oh-my-posh3

Prerequisites

  • [x] I have read and understand the CONTRIBUTING guide
  • [x] I looked for duplicate issues before submitting this one

Description

When running grep, the prompt immediately afterwards is corrupted - not sure if there's other commands with similar issues yet.

Environment

  • Oh my Posh version: v3.75.0
  • Theme: custom - see below
  • Operating System: Win10 19042.746
  • Shell: Powershell 7.1.0
  • Terminal: Console Host , Windows Terminal 1.4.3243.0
  • Grep: GNU grep 3.1 (bundled with git 2.29.2.windows.2)

Steps to Reproduce

  1. Run echo hi | grep hi
  2. Hear audible bell, and observe corrupted prompt

Expected behavior: [What you expected to happen]

  1. Uncorrupted prompt

Actual behavior: [What actually happened]

image

Notes

  • I also tested without the special characters in my config file (as they only work in Windows Terminal) - same issue

Theme

{
    "final_space": false,
    "console_title": true,
    "console_title_style": "template",
    "console_title_template": "[{{.Env.Host}}] {{.Path}}",
    "blocks": [
        {
            "type": "prompt",
            "alignment": "left",
            "horizontal_offset": 0,
            "vertical_offset": 0,
            "segments": [


                {
                    "type": "exit",
                    "style": "plain",
                    "foreground": "#16c50c",

                    "properties": {
                        "display_exit_code": false,
                        "always_enabled": true,
                        "error_color": "#e74856",
                        "prefix": "\u279C"
                    }
                },

                {
                    "type": "path",
                    "style": "plain",
                    "foreground": "#61d6d6",
                    "properties": {
                        "style": "folder"
                    }
                },

                {
                  "type": "git",
                  "style": "plain",
                  "foreground": "#e74856",

                  "properties": {

                  "prefix": "<#3b78ff>git:(</>",
                  "postfix": "<#3b78ff>) </>",
                    "local_changes_icon": "\u2717",
                    "display_status": false,
                    "display_status_detail": false,
                    "display_stash_count": false,
                    "display_upstream_icon": false,
                    "working_color": "#e74856",
                    "branch_icon": ""
                  }
                }
            ]
        }
    ]
}
bug powershell

Most helpful comment

I think I tested everything, also simplified the module in the meantime. Hope I didn't break anything for someone else 馃馃徎

All 11 comments

It is known that the git tooling in Windows can cause the entire terminal rendering to act weird due to overriding certain variables. I'll check, but can't promise this is something that can be fixed within oh-my-posh.

I did the same test with starship and it works. Maybe we can check what they do on their side with the powershell prompt.

I did the same test with starship

@lnu could you also reproduce the issue for OMP?

And..... if I take the powershell bootstrap from starship and sets omp it works

image

With all due respect, this works with the out of the box version of OMP on my Windows machine as well, albeit PowerShell 5:

image

powershell core 7.1.1 here in windows terminal

Only added $omp and $config and changed the starship calls.

```
function global:prompt {
$omp="D:\dev\temp\oh-my-posh3\src\oh-my-posh3.exe"
$config="D:\tools\ohmyposh\jandedobbeleer_custom.omp.json"
$origDollarQuestion = $global:?
$origLastExitCode = $global:LASTEXITCODE

$out = $null
# @ makes sure the result is an array even if single or no values are returned
$jobs = @(Get-Job | Where-Object { $_.State -eq 'Running' }).Count

$env:PWD = $PWD
$current_directory = (Convert-Path -LiteralPath $PWD)

# Whe start from the premise that the command executed correctly, which covers also the fresh console.
$lastExitCodeForPrompt = 0

# Save old output encoding and set it to UTF-8
$origOutputEncoding = [Console]::OutputEncoding
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
if ($lastCmd = Get-History -Count 1) {
    # In case we have a False on the Dollar hook, we know there's an error.
    if (-not $origDollarQuestion) {
        # We retrieve the InvocationInfo from the most recent error.
        $lastCmdletError = try { Get-Error |  Where-Object { $_ -ne $null } | Select-Object -expand InvocationInfo } catch { $null }
        # We check if the las command executed matches the line that caused the last error , in which case we know
        # it was an internal Powershell command, otherwise, there MUST be an error code.
        $lastExitCodeForPrompt = if ($null -ne $lastCmdletError -and $lastCmd.CommandLine -eq $lastCmdletError.Line) { 1 } else { $origLastExitCode }
    }

    $duration = [math]::Round(($lastCmd.EndExecutionTime - $lastCmd.StartExecutionTime).TotalMilliseconds)
    # & ensures the path is interpreted as something to execute
    $out = @(&starship prompt "--path=$current_directory" --status=$lastExitCodeForPrompt --jobs=$jobs --cmd-duration=$duration)
    $out = @(&$omp "--config=$config" --error=$lastExitCodeForPrompt "--pwd=$current_directory" "--pswd=$current_directory" --execution-time=$duration)
} else {
    #$out = @(&starship prompt "--path=$current_directory" --status=$lastExitCodeForPrompt --jobs=$jobs)
    $out = @(&$omp "--config=$config" --error=$lastExitCodeForPrompt "--pwd=$current_directory" "--pswd=$current_directory")
}
# Restore old output encoding
[Console]::OutputEncoding = $origOutputEncoding

# Convert stdout (array of lines) to expected return type string
# `n is an escaped newline
$out -join "`n"

# Propagate the original $LASTEXITCODE from before the prompt function was invoked.
$global:LASTEXITCODE = $origLastExitCode

# Propagate the original $? automatic variable value from before the prompt function was invoked.
#
# $? is a read-only or constant variable so we can't directly override it.
# In order to propagate up its original boolean value we will take an action
# which will produce the desired value.
#
# This has to be the very last thing that happens in the prompt function
# since every PowerShell command sets the $? variable.
if ($global:? -ne $origDollarQuestion) {
    if ($origDollarQuestion) {
         # Simple command which will execute successfully and set $? = True without any other side affects.
        1+1
    } else {
        # Write-Error will set $? to False.
        # ErrorAction Ignore will prevent the error from being added to the $Error collection.
        Write-Error '' -ErrorAction 'Ignore'
    }
}

}
```

@lnu @peter-dolkens so this is confirmed to only break in PSCore, for me that's 7.2:

image

There's a reason I went with the current invocation technique as I did use a starship like invocation which ruined the rendering on certain machines. This solution made it work everywhere. There's something in the output of that command which ruins the rendering, and the next ENTER fixes that once again. I'm in favor of figuring out what exactly is the difference and adding a one-liner fix to the current invocation rather than opening that can of worms again (I was happy I was able to close it 5 months ago).

@lnu @peter-dolkens fixed it. I believe, at the time, I was battling combination of issues which led me down this path. I was able to directly invoke OMP now without the entire process bootstrap leading to a correctly displayed prompt in all circumstances. I'm going to test a little bit more but you should see a fix ASAP.

Great work - @JanDeDobbeleer!

Was a low-priority bug for me, but thought I had an easy enough repro for it to be worthwhile logging =D

I think I tested everything, also simplified the module in the meantime. Hope I didn't break anything for someone else 馃馃徎

Was this page helpful?
0 / 5 - 0 ratings

Related issues

slurmpit picture slurmpit  路  3Comments

meakbiyik picture meakbiyik  路  9Comments

catthehacker picture catthehacker  路  4Comments

ozerty picture ozerty  路  7Comments

tillig picture tillig  路  8Comments