JanDeDobbeleer / oh-my-posh

The most customisable and low-latency cross platform/shell prompt renderer
https://ohmyposh.dev
MIT License
17.38k stars 2.39k forks source link

Corrupted prompt after certain commands #352

Closed peter-dolkens closed 3 years ago

peter-dolkens commented 3 years ago

Prerequisites

Description

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

Environment

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

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": ""
                  }
                }
            ]
        }
    ]
}
JanDeDobbeleer commented 3 years ago

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.

lnu commented 3 years ago

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

JanDeDobbeleer commented 3 years ago

I did the same test with starship

@lnu could you also reproduce the issue for OMP?

lnu commented 3 years ago

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

image

JanDeDobbeleer commented 3 years ago

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
lnu commented 3 years ago

powershell core 7.1.1 here in windows terminal

lnu commented 3 years ago

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'
        }
    }
}
JanDeDobbeleer commented 3 years ago

@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).

JanDeDobbeleer commented 3 years 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.

peter-dolkens commented 3 years ago

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

JanDeDobbeleer commented 3 years ago

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

kidchenko-jq-tw commented 3 years ago

After run any git command it also breaks for me :/

Terminal: Hyper

image

JanDeDobbeleer commented 3 years ago

@kidchenko-tw That's likely going to be a Hyper issue, allow me to check. Is everything up to date?

JanDeDobbeleer commented 3 years ago

@kidchenko-tw I can't reproduce this

kidchenko-jq-tw commented 3 years ago

Yes, everything is up to date, I will double check, I remember I already had this problem in the past... But can't remember the fix,

JanDeDobbeleer commented 3 years ago

@kidchenko-tw can you copy the prompt here? If you pipe the out of oh-my-posh with your config I can have a look. Maybe there's a character the ruins the ANSI sequences?

kidchenko-jq-tw commented 3 years ago

Oh my Posh version: 3.131.0 Operating System: Windows Server 2016 DataCenter Shell: Powershell 5.1.14393.3866 Terminal: Hyper 3.0.2

kidchenko-jq-tw commented 3 years ago

Sorry, but I didn't understand, how can I pipe the out? Is this what you want?

My prompt before: image

Copy: ~  

My after: image

?[38;2;255;255;255mD:\thoughtworks\test ?[0m?[38;2;194;194;6m  ≢ ?[0m?[38;2;181;181;13m  ?[0m?[K ?[K?[38;2;0;122;204m ?[0m?[K?[0m ?[K

JanDeDobbeleer commented 3 years ago

Aha git diff. That's going to be the culprit. Did you update git as well?

kidchenko-jq-tw commented 3 years ago

Just updated my git

git version 2.31.1.windows.1

Still same problem :/

JanDeDobbeleer commented 3 years ago

I'll try to reproduce this.

JanDeDobbeleer commented 3 years ago

@kidchenko-tw I just tried to reproduce this again, doesn't happen. Did you add a specific pager or something else in your git config that influences git diff?

github-actions[bot] commented 6 months ago

This issue has been automatically locked since there has not been any recent activity (i.e. last half year) after it was closed. It helps our maintainers focus on the active issues. If you have found a problem that seems similar, please open a discussion first, complete the body with all the details necessary to reproduce, and mention this issue as reference.