Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

msys true in pipe to vim with termguicolors causes escape codes to be displayed in terminal #12289

Closed
kevinoid opened this issue Jan 30, 2022 · 9 comments
Labels
Resolution-Duplicate There's another issue on the tracker that's pretty much the same thing.

Comments

@kevinoid
Copy link

kevinoid commented Jan 30, 2022

Windows Terminal version

1.11.3471.0

Windows build number

10.0.19043.1466

Other Software

Git 2.35.0
Vim 8.4.4227

Steps to reproduce

To reproduce with cmd (in WT or Conhost), run:

"C:\Program Files\Git\usr\bin\perl.exe" -e "for (1..100) { `true` }" | vim --clean --cmd "set tgc" -

To reproduce with powershell or pwsh (in WT or Conhost), run:

& 'C:\Program Files\Git\usr\bin\perl.exe' -e 'for (1..100) { `true` }' | vim --clean --cmd 'set tgc' -

It can also be reproduced by running git show $commit if core.pager=vim, vimrc has set tgc, and $commit includes changes to a .docx file, which is how I initially encountered the issue: Git for Windows has *.docx diff=astextplain which invokes astextplain which invokes docx2txt.pl which invokes unzip twice. I found the reproduction to be more reliable if perl invokes another program more times. 100 invocations reliably reproduces the issue on my system.

Expected Behavior

Vim would show its default empty-input startup screen:
Screenshot of Vim default empty-input startup screen in Windows Terminal

Actual Behavior

The first and last row of the terminal shows what appear to be terminal escape codes. Keyboard input changes the escape codes, rather than appearing as expected:
Screenshot of Vim showing escape codes in Windows Terminal

@ghost ghost added Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Tag-Fix Doesn't match tag requirements labels Jan 30, 2022
@kevinoid kevinoid changed the title perl pipe to vim with termguicolors causes escape codes displayed in terminal perl pipe to vim with termguicolors causes escape codes to be displayed in terminal Jan 30, 2022
@kevinoid
Copy link
Author

For reference, I'm also able to reproduce the issue with Vim 8.2.0916, although the behavior is slightly different: The screen is initially blank, but pressing any keys (including Ctrl-L to redraw) causes the escape codes to appear as in 8.4.4227.

@elsaco
Copy link

elsaco commented Jan 30, 2022

@kevinoid git does some coloring of its own. color.ui = true is the default for Git for Windows. The output changes when this setting is false.

Git with nvim as pager:
git_nvim_pager

Git with color.ui = false and nvim as pager:
git_no_color

Git with color.ui = false and nvim with no tgc:
git_no_color_pager_no_tgc

I'm not sure who's doing the coloring, the application or the terminal.

@kevinoid
Copy link
Author

@elsaco That's a good observation. I think it's a related, but separate issue. (I'm not sure whether it's a bug since I'm not sure how the color escape sequences git produces should be interpreted once vim enablestermguicolors.) For reference, I usually configure git with color.ui=auto to avoid the issue.

Note that the reproduction I provided for this issue doesn't actually invoke git, just perl and vim (and true indirectly). In the reproduction, perl doesn't produce any output to stdout or stderr that I'm aware of, so the escape codes are almost certainly coming from vim.

@kevinoid
Copy link
Author

kevinoid commented Jan 30, 2022

I just realized that the issue can be reproduced without perl too. To reproduce with cmd (in WT or Conhost):

(@echo off & for /l %x in (1, 1, 100) do "C:\Program Files\Git\usr\bin\true.exe") | vim --clean --cmd "set tgc" -

To reproduce with powershell or pwsh (in WT or Conhost):

@(1..100) | ForEach-Object { & 'C:\Program Files\Git\usr\bin\true.exe' } | vim --clean --cmd 'set tgc' -

I am unable to reproduce the issue with non-msys programs. For example, the issue does not occur with:

(@echo off & for /l %x in (1, 1, 100) do findstr foo C:\Windows\system.ini) | vim --clean --cmd "set tgc" -

@kevinoid kevinoid changed the title perl pipe to vim with termguicolors causes escape codes to be displayed in terminal msys true in pipe to vim with termguicolors causes escape codes to be displayed in terminal Jan 30, 2022
@j4james
Copy link
Collaborator

j4james commented Jan 30, 2022

What you're seeing is usually the result an application resetting the ENABLE_VIRTUAL_TERMINAL_PROCESSING mode. See for example #6634, #6711, and #7091.

@zadjii-msft
Copy link
Member

Wait how did we never triage this one? This does look like the same thing as /dup #6634 to me. See #6634 (comment) specifically.

@zadjii-msft zadjii-msft closed this as not planned Won't fix, can't repro, duplicate, stale May 16, 2022
@ghost
Copy link

ghost commented May 16, 2022

Hi! We've identified this issue as a duplicate of another one that already exists on this Issue Tracker. This specific instance is being closed in favor of tracking the concern over on the referenced thread. Thanks for your report!

@ghost ghost added Resolution-Duplicate There's another issue on the tracker that's pretty much the same thing. and removed Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Tag-Fix Doesn't match tag requirements labels May 16, 2022
@kevinoid
Copy link
Author

This does look like the same thing as /dup #6634 to me.

@zadjii-msft Do I understand correctly that you think C:\Program Files\Git\usr\bin\true.exe disables ENABLE_VIRTUAL_TERMINAL_PROCESSING via SetConsoleMode()? Could you explain why true has to be run in a loop for the issue to occur?

@DHowett
Copy link
Member

DHowett commented May 16, 2022

Could you explain why true has to be run in a loop for the issue to occur?

It's a race condition, unfortunately. The console mode is global state, and spawning true repeatedly and letting it turn VT parsing on and off while vim is starting turns out to be a good way to trigger the race.

Part of this is due to how pipelines work: vim is starting up and configuring the console handle before any given instance of true exits, as it needs to service the reading end of the pipe.

It probably looks like this:

  1. true starts, enables VT parsing (old mode = off)
  2. vim starts
  3. true exits, disabling VT parsing (mode = old mode)
  4. true starts, enabling VT parsing (old mode = off)
  5. vim enables VT parsing (it is much slower to start up than true)
  6. true exits, disabling VT parsing (mode = old mode)
  7. vim tries to emit VT

The cached value from 4 reflects the console state at the time it was launched, and it cannot be aware of vim's changes in 5 when step 6 happens.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution-Duplicate There's another issue on the tracker that's pretty much the same thing.
Projects
None yet
Development

No branches or pull requests

5 participants