-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Automatically triggered Replace mode using vim in OpenSSH on cmd / powershell though Windows Terminal #1637
Comments
None of us can reproduce this. Is there anything else unusual about your machine, about your vim configuration, or about your keyboard layout? |
Also, does it still happen if you use wsl ssh? |
No, it would not happened when I use wsl ssh |
Keyboard Layout is simple Standard US Layout |
[Un]Fortunately I don't think this is a Windows Terminal issue. I see the same behavior using ConEmu on my work machine (not updated to W10 1903 so can't install Windows Terminal there), but not in either Windows Terminal or ConEmu on my home machine (W10 1903). Both machines have Standard US Layout and both English US and English US International input languages. I see no change in this behavior on either machine based on selected input langauge. |
If it doesn't happen in wsl ssh, but it does in win32-openssh, I'd go to their repository and complain there. Thanks! |
Seems to be an issue with utf-8 ambiguous characters and Windows cmd console. Flag t_u7 is set by default and so vim will request cursor position and get a bad reply from the ssh client. Workaround: Adding set t_u7= or set ambw=double to your vimrc should fix the problem. set t_u7= will disable requesting cursor position and ambw=double will set the ambiguous characters mode to double. For more info see vim reference manual: https://vimhelp.org/term.txt.html Credits: https://superuser.com/a/1525060 set ambw=double appears to have conflict with airline/powerline characters. I see extra spaces after the <| arrows. set t_u7= works though! – David Woods Jul 9 at 17:12 |
This bug happens in WSL for local sessions as well as remote SSH sessions when running the Terminal Preview build v1.2.2022.0. The latest non-preview release of Terminal v1.1.2021.0 does not inflict this bug on WSL sessions. A note on reproducibility - this happens at random, around 1 in 5 times I open vim it opens in Replace mode. This comment fixed the issue for me, but is needed in my local |
Windows 10. Windows Terminal Preview Remote SSH (using windows ssh) -> vim -> starting in Replace mode :( |
@FremdSprach #1637 (comment) This bug was only reopened a few days ago, after it was initially closed thanks to (what appeared to be) Win32-OpenSSH having a similar issue. Since then, it’s been a weekend followed by a US holiday, which has occupied most of our US-based team’s time 😄 (Edit: whoa, it has been a week since I reopened this.) |
Now, that might seem like a weird diagnosis. Until recently, win32-openssh implemented its own terminal emulator! It also implemented its own VT input generator. |
Ah, Labor Day, that makes it. It must be a sound and good break without labor~~ Suppose God the savior himself take a same holiday, people across the world would get nobody to pray to. You guys are Savior to the WT-addicted die-hard fans. Hope God's got no holidays and wish you be blessed Thor's hammer 🔨 and hammer it hard 😁 |
Just surprised this issue has reopened after a year ago. |
Historical bug awakening the first dragon-rider @SuzunaeHoumi 😀 |
Okay, here's what's happening. When we receive a terminal/src/terminal/adapter/adaptDispatch.cpp Lines 818 to 819 in 230b86c
terminal/src/terminal/adapter/adaptDispatch.cpp Lines 857 to 859 in 230b86c
Because of the design of the input queue and how it has to remain compatible with Now, this poses a problem for two CPRs being received back-to-back: the second CPR will cause the later position to be prepended to the input queue before the earlier position. If an application has read input between the two CPRs -- even a single keypress, it will certainly encounter this issue. In my testing, I saw that the input queue at the time of the second prepend contained...
indicating that only the first keypress (esc down) had been read and popped out of the queue. The resultant sequence was...
Because VT input events are usually read on the keydown event, the first I'll need to wait for my team to be back from vacation/leave to figure out why we went with a prepend, as that decision predates me. 😄 |
Reader's notes: Prepend seems like it was an intentional choice -- we do it in a number of places (every DSR, DA, DA2, DA3, VT52 Identify, DSR-OS, CPR) -- but I do not believe that it is ever correct. It was introduced on 2017-10-17 in a pull request (!997738) that introduced support for window manipulation sequences over the pty, which we've never documented and quickly replaced with the signal channel. (This will be of particular interest to the folks having the purity discussion about sending an ED down the input handle 😁).
This comment suggests that we had to add a separate prepend so that InteractDispatch could append. Because this pull request mainly dealt with InteractDispatch, the implication is that the "adapter" was already prepending and we needed to add Prepend...Buffer to disentangle the prepending behavior that "adapter" was using. However, the code change is fairly obvious in the "adapter". It explicitly goes from appending to prepending with this diff: diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp
index xxxxxxxxx..yyyyyyyyy 100644
--- a/src/terminal/adapter/adaptDispatch.cpp
+++ b/src/terminal/adapter/adaptDispatch.cpp
@@ -932,7 +932,7 @@ bool AdaptDispatch::_WriteResponse(_In_reads_(cReply) PCWSTR pwszReply, _In_ siz
if (cInputBuffer > 0)
{
DWORD dwWritten = 0;
- fSuccess = !!_pConApi->WriteConsoleInputW(rgInput, (DWORD)cInputBuffer, &dwWritten);
+ fSuccess = !!_pConApi->PrivatePrependConsoleInput(rgInput, (DWORD)cInputBuffer, &dwWritten);
} Mike's on paternity leave (yay!), so I can't exactly ask 😄 |
This fixes an issue where two CPRs could end up corrupted in the input buffer. An application that sent two CPRs back-to-back could accidentally read the first few characters of the first prepended CPR before handing us another CPR. We would dutifully prepend it to the buffer, causing them to overlap. ``` ^[^[2;2R[1;1R ^^ ^^^^^ First CPR ^^^^^^ Second CPR ``` Response prepending was implemented in !997738 without much comment. There's very little in the way of audit trail as to why we switched. Michael believes that we wanted to make sure that applications got DSR responses immediately. I discussed our options with him, and he suggested that we could implement a priority queue in InputBuffer and make sure that "response" input was dispatched to a client application before any application- or user-generated input. This was deemed to be too much work. We decided that DSR responses getting top billing was likely to be a stronger guarantee than most terminals are capable of giving, and that we should be fine if we just switch it back to append. Fixes #1637.
This fixes an issue where two CPRs could end up corrupted in the input buffer. An application that sent two CPRs back-to-back could end up reading the first few characters of the first prepended CPR before handing us another CPR. We would dutifully prepend it to the buffer, causing them to overlap. ``` ^[^[2;2R[1;1R ^^ ^^^^^ First CPR ^^^^^^ Second CPR ``` The end result of this corruption is that a requesting application would receive an unbidden `R` on stdin; for vim, this would trigger replace mode immediately on startup. Response prepending was implemented in !997738 without much comment. There's very little in the way of audit trail as to why we switched. Michael believes that we wanted to make sure that applications got DSR responses immediately. It had the unfortunate side effect of causing subsequence CPRs across cursor moves to come out in the wrong order. I discussed our options with him, and he suggested that we could implement a priority queue in InputBuffer and make sure that "response" input was dispatched to a client application before any application- or user-generated input. This was deemed to be too much work. We decided that DSR responses getting top billing was likely to be a stronger guarantee than most terminals are capable of giving, and that we should be fine if we just switch it back to append. Thanks to @k-takata, @Tekki and @brammool for the investigation on the vim side. Fixes #1637.
This fixes an issue where two CPRs could end up corrupted in the input buffer. An application that sent two CPRs back-to-back could end up reading the first few characters of the first prepended CPR before handing us another CPR. We would dutifully prepend it to the buffer, causing them to overlap. ``` ^[^[2;2R[1;1R ^^ ^^^^^ First CPR ^^^^^^ Second CPR ``` The end result of this corruption is that a requesting application would receive an unbidden `R` on stdin; for vim, this would trigger replace mode immediately on startup. Response prepending was implemented in !997738 without much comment. There's very little in the way of audit trail as to why we switched. Michael believes that we wanted to make sure that applications got DSR responses immediately. It had the unfortunate side effect of causing subsequence CPRs across cursor moves to come out in the wrong order. I discussed our options with him, and he suggested that we could implement a priority queue in InputBuffer and make sure that "response" input was dispatched to a client application before any application- or user-generated input. This was deemed to be too much work. We decided that DSR responses getting top billing was likely to be a stronger guarantee than most terminals are capable of giving, and that we should be fine if we just switch it back to append. Thanks to @k-takata, @Tekki and @brammool for the investigation on the vim side. Fixes #1637. (cherry picked from commit cb037f3)
🎉This issue was addressed in #7583, which has now been successfully released as Handy links: |
🎉This issue was addressed in #7583, which has now been successfully released as Handy links: |
This fix has also been ingested into Windows for a future release. |
The "Handy links" here takes you to the Preview app, not to the non-preview app. |
http://aka.ms/terminal enjoy |
(sorry, I flippantly gave you the preview link anyway ;P) |
@DHowett Great work! Finally, and Wonderfully! Thanks so much! |
Thanks! |
This still sometimes happens where VIM reports being in replace mode over SSH. Othertimes it correctly goes into Insert Mode in v1.4 |
@WSLUser please file a separate bug following the bug template and note the versions of all software involved. |
Replace input mode will triggered automatically when using vim though OpenSSH Client in cmd.
Environment
Steps to reproduce
Expected behavior
Not trigger any input mode, the status bar at the bottom displays the path of the file that vim opened.
Actual behavior
Triggered Replace input mode.
The text was updated successfully, but these errors were encountered: