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

Arrow Keys in vim within Git-bash stopped working. #6737

Closed
camckee opened this issue Jun 30, 2020 · 11 comments
Closed

Arrow Keys in vim within Git-bash stopped working. #6737

camckee opened this issue Jun 30, 2020 · 11 comments
Labels
Resolution-Duplicate There's another issue on the tracker that's pretty much the same thing.

Comments

@camckee
Copy link

camckee commented Jun 30, 2020

Issue

The arrow keys stopped working in vim with the latest version of the Windows Terminal. Whenever I press an arrow key, the screen flickers a blue, and nothing happens. I have to hold the control key down before the arrow keys work. Vim in git-bash worked just fine until the latest update. Vim still works in PowerShell.

Environment

Windows build number: 10.0.18363.0 Microsoft Windows NT 10.0.18363.0
Windows Terminal version (if applicable):  1.0.1811.0
Git for Windows: git version 2.27.0.windows.1 - Default Configuration.

Steps to reproduce

Here is my configuration for Git-Bash.

    {
      "guid": "{D1F7F53F-EC3D-4511-A67E-EF4F97E36AC6}",
      "acrylicOpacity": 0.90,
      "closeOnExit": true,
      "colorScheme": "Campbell",
      "commandline": "\"%PROGRAMFILES%\\git\\usr\\bin\\bash.exe\" -l -i",
      "cursorColor": "#FFFFFF",
      "cursorShape": "bar",
      "fontFace": "Consolas",
      "historySize": 9001,
      "icon": "%SystemDrive%\\Program Files\\Git\\mingw64\\share\\git\\git-for-windows.ico",
      "name": "Git Bash",
      "padding": "0, 0, 0, 0",
      "snapOnInput": true,
      "startingDirectory": "%USERPROFILE%",
      "useAcrylic": true
    }
  1. Open a new terminal window.
  2. Execute "vim ."
  3. Push the down arrow to select a file. Notice the cursor does not move.

Expected behavior

The cursor should move based on the arrow key pressed.

Actual behavior

The screen flickers blue and the cursor remains in the same position.

@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 Jun 30, 2020
@KalleOlaviNiemitalo
Copy link

Reproduced with Windows Terminal 1.0.1811.0.
However, Windows Terminal Preview 1.1.1812.0 does not have this problem.

@KalleOlaviNiemitalo
Copy link

The problem also affects less. There, it seems less is getting ESC [ B rather than the expected ESC O B. #6626 had similar symptoms but I have not checked whether ENABLE_VIRTUAL_TERMINAL_INPUT is being lost in Windows Terminal 1.0.1811.0.

@KalleOlaviNiemitalo
Copy link

less gets ESC [ B as characters from ReadConsoleInputW. The console input handle has mode 0x209 = ENABLE_PROCESSED_INPUT | ENABLE_WINDOW_INPUT | ENABLE_VIRTUAL_TERMINAL_INPUT during this call.

It seems DECCKM does not always take effect, but I can't make sense of why.


I made a test program that

  1. Displays the current console modes.
  2. Disables the console input modes ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT.
  3. Enables the console input mode ENABLE_VIRTUAL_TERMINAL_INPUT.
  4. Enables the console output mode ENABLE_VIRTUAL_TERMINAL_PROCESSING.
  5. Loops calling ReadConsoleInputW and displaying the results until Ctrl+C is pressed.
  6. Restores the console modes.

Windows Terminal Preview 1.1.1812.0

When I start a Git Bash profile in Windows Terminal Preview 1.1.1812.0, run the program there, and press the Down arrow key, it outputs:

Old console input mode: 0xf
Old console output mode: 0x3
New console input mode: 0x200
New console output mode: 0x7
Press Ctrl+C to exit.
ReadConsoleInput returned 3 input records:
[0] = KEY_EVENT: kd=1, rc=1, vkc=0, vsk=0, uc=0x1b, cks=0
[1] = KEY_EVENT: kd=1, rc=1, vkc=0, vsk=0, uc=0x5b, cks=0
[2] = KEY_EVENT: kd=1, rc=1, vkc=0, vsk=0, uc=0x42, cks=0
ReadConsoleInput returned 1 input records:
[0] = KEY_EVENT: kd=0, rc=1, vkc=0x28, vsk=0x50, uc=0, cks=0
ReadConsoleInput returned 1 input records:
[0] = KEY_EVENT: kd=1, rc=1, vkc=0x11, vsk=0x1d, uc=0, cks=0x4
ReadConsoleInput returned 1 input records:
[0] = KEY_EVENT: kd=1, rc=1, vkc=0, vsk=0, uc=0x3, cks=0
Restoring console modes.
Exiting.

That is, the ENABLE_VIRTUAL_TERMINAL_PROCESSING mode was originally disabled, and the Down arrow key was translated to ESC [ B.

I run printf "\033[?1h" in Bash and run the test program again and press Down. The output is the same except now Down is translated to ESC O B, as expected.

I run less /etc/package-versions.txt and press q to exit, then run the test program again. The Down arrow key is translated to ESC [ B again, indicating that less disabled Cursor Keys Application Mode when exiting.

Windows Terminal 1.0.1811.0

When trying the same steps in Windows Terminal 1.0.1811.0, the first difference is that the Ctrl key does not generate any INPUT_RECORD even though the console modes are the same as in Windows Terminal Preview. That can't be the cause of the problem, though. The Down arrow key is translated to ESC [ B, like in Windows Terminal Preview.

After printf "\033[?1h", the test program shows that the Down arrow key is still translated to ESC [ B, even though it should now be ESC O B.

I debug bash.exe and see that printf "\033[?1h" outputs the control sequence by calling WriteConsoleW and enables the ENABLE_VIRTUAL_TERMINAL_PROCESSING console output mode before that call. I add a similar WriteConsoleW(hConsoleOutput, L"\033[?1h", 5, &numberOfCharsWritten, NULL) call to the test program, after the SetConsoleMode calls. There, the control sequence enables Cursor Keys Application Mode just fine.

After Cursor Keys Application Mode has been enabled by the test program, less /etc/package-versions.txt also gets the application-mode sequences that it expects. Strangely, Cursor Keys Application Mode remains enabled after less exits, or after I run tput rmkx.

@DHowett
Copy link
Member

DHowett commented Jul 2, 2020

From the Terminal's perspective, ENABLE_VIRTUAL_TERMINAL_INPUT is always on. It can't be lost/forgotten, because the terminal only generates VT. In general, it always has conhost sitting between it and the application to do translation from VT input. There are cases when the conhost sitting in the middle enters passthrough mode and dumps input straight out of terminal into the application.
Therefore, Terminal needs to be aware of DECCKM. Whether it receives DECCKM and therefore whether it generates the right cursor keys, however, is based on whether the application has requested ENABLE_VIRTUAL_TERMINAL_INPUT.
(There are applications that ask for DECCKM or other VT input format changes but are not in VT input mode, and sending them that data will freak them out.)

For WT 1.0, here's the matrix of behaviors.

ActionVT Output ModeVT Input ModeNotes
Application prints \e[?1h VT output is off, request ignored
conhost (PTY) (only) enables DECCKM
conhost (PTY) _and Terminal_ enable DECCKM
ActionVT Output ModeVT Input ModePTY in DECCKM modeTerminal in DECCKM modeNotes
User presses arrow key Terminal emits \e[A or \eOA
conhost (PTY) translates it into KEY_EVENT_RECORD
Terminal emits \e[A
conhost (PTY) translates it into KEY_EVENT_RECORD
Terminal emits \eOA
conhost (PTY) translates it into KEY_EVENT_RECORD
passthrough mode Terminal emits \e[A
conhost (PTY) passes it through unmodified
Terminal emits \eOA
conhost (PTY) passes it through unmodified
BEHAVIORS BEFORE TERMINAL 1.0
ActionVT Output ModeVT Input ModeNotes
Application prints \e[?1h VT output is off, request ignored
conhost (PTY) (only) enables DECCKM
ActionVT Output ModeVT Input ModePTY in DECCKM modeNotes
User presses arrow key ignored Terminal emits \e[A
conhost (PTY) translates it into KEY_EVENT_RECORD
Terminal emits \e[A
conhost (PTY) translates it into \e[A
Terminal emits \e[A
conhost (PTY) translates it into \e[OA

@DHowett
Copy link
Member

DHowett commented Jul 2, 2020

Okay, I'm literally seeing this behavior at the PTY:

  • Input Mode = 0x9
  • Input Mode = 0x209
  • Input Mode = 0x9
  • Print out DECCKM
  • Input Mode = 0x209
  • Input Mode = 0x9

This happens with printf, this happens with less's startup (though it prints more than just DECCKM)`, this happens pretty much every time I launch a process.

It's quite literally disabling VT input mode only while it is changing the input configuration. If we'd ever made the console more strict ("VT input mode changes only apply when VT input mode is on"), this would break horribly. I wonder why they'd do this?

@DHowett
Copy link
Member

DHowett commented Jul 2, 2020

This regressed with #6485, which was done explicitly because OpenSSH requests mouse mode when it cannot possibly receive mouse input. We cannot live in a world where we support both of these insane uses of the console API 😄

@KalleOlaviNiemitalo
Copy link

KalleOlaviNiemitalo commented Jul 3, 2020

Whether it receives DECCKM and therefore whether it generates the right cursor keys, however, is based on whether the application has requested ENABLE_VIRTUAL_TERMINAL_INPUT.

I totally did not expect that. If ENABLE_VIRTUAL_TERMINAL_INPUT is designed to affect which control sequences a pseudoconsole forwards from WriteConsole to the terminal, it is worth documenting.

This regressed with #6485

Why doesn't Windows Terminal Preview 1.1.1812.0 have the same problem, then? 6ff8ba7 was cherry-picked from 5e2c4c6, which is included in that version.

@DHowett
Copy link
Member

DHowett commented Jul 8, 2020

So, this is where it gets interesting. Windows Terminal 1.1+ was cut after #4999 landed. When that mode is engaged, it actually doesn't matter what mode terminal thinks is on at all. It just funnels raw keyboard events into the conhost backing the tab and the conhost's decision on how to encode them is "final."

Instead of \e[C or \eOC, we get... ␛[39;77;0;1;0;1_ ␛[39;77;0;0;0;1_.

@DHowett
Copy link
Member

DHowett commented Jul 10, 2020

So, this is going to resolve itself for terminal when 1.1 goes stable (which is soon). It's going to become more of a problem for other terminals (alacritty, hyper, vscode, etc., even wsl-in-wsl) once this change flows up and out through Windows. Because of that, I'm going to transform this issue to match what I believe needs to be done to fix it.

@DHowett
Copy link
Member

DHowett commented Jul 10, 2020

/dup #6859

@ghost
Copy link

ghost commented Jul 10, 2020

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 closed this as completed Jul 10, 2020
@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 Jul 10, 2020
This issue was closed.
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

3 participants