Console filters out bracketed paste input codes when virtual terminal input is disabled #22437

Open
opened 2026-01-31 08:13:12 +00:00 by claunia · 0 comments
Owner

Originally created by @jart on GitHub (Oct 22, 2024).

Originally assigned to: @DHowett on GitHub.

Windows Terminal version

1.22.2702.0

Windows build number

10

Other Software

This issue applies broadly to all WIN32 software. In my case, I happen to be working on Cosmopolitan Libc.

Steps to reproduce

  1. Use SetConsoleMode() to disable the ENABLE_VIRTUAL_TERMINAL_INPUT flag on GetStdHandle(STD_INPUT_HANDLE).
  2. Use SetConsoleMode() to enable the ENABLE_VIRTUAL_TERMINAL_PROCESSING flag on GetStdHandle(STD_OUTPUT_HANDLE).
  3. Write the string "\033[?2004h" to standard output, to enable bracketed paste mode.
  4. Press ctrl-shift-v or shift-ins to paste text with multiple lines into the terminal.
  5. Reading from standard input will give you the pasted text (but it's supposed to surround the paste with "\033[200~" and "\033[201~")

If you're a Cosmopolitan Libc fan and have cosmocc installed from our GitHub releases page, then here's a simple program that can reproduce this without needing to write any WIN32 code.

void Write(const char *s) {
  write(1, s, strlen(s));
}

int main(int argc, char *argv[]) {
  Write("\033[?2004h");
  char buf[512];
  int rc = read(0, buf, 512);
  Write("\033[?2004l");
  printf("got %`'.*s\n", rc, buf);
}

See also https://github.com/jart/cosmopolitan/blob/master/libc/calls/read-nt.c if you're curious about our termios driver.

Expected Behavior

If I enable bracketed paste mode on the terminal, then I believe it should insert the "\033[200~" and "\033[201~" ANSI codes into the paste, even if ENABLE_VIRTUAL_TERMINAL_INPUT is disabled. Cosmopolitan Libc needs this. Cosmo is similar to Cygwin in that it implements POSIX on Windows. For example, common utilities like bash and emacs can be compiled with cosmo libc and then run in the command prompt. I've been very successful making this work well. This bug is the one problem I can't solve unless Microsoft fixes things. It is impossible to work around this issue.

Why is that? Cosmopolitan Libc always wants a virtual ANSI style Linux-like terminal. To do that, we always enable ENABLE_VIRTUAL_TERMINAL_PROCESSING on standard output. Virtual terminal output works fantastically with your tools. However Cosmo never uses ENABLE_VIRTUAL_TERMINAL_INPUT because it isn't very good. Virtual terminal input is a toy feature that makes important use cases impossible, such as polling console input. Cosmopolitan Libc always uses ReadConsoleInput() and GetNumberOfConsoleInputEvents() to read console input and then manually translates INPUT_RECORD to ANSI codes and implements things like canonical mode line editing because there's no other way.

However there's one and only one occasion where I actually DO want WIN32 to inject \033[200~ and \033[201~ ANSI codes into my input, and that's for bracketed paste mode. Windows should either do this, or it should generate INPUT_RECORD events that tell me where the paste begins and ends. But Windows does neither and that's a huge painful issue for me.

Actual Behavior

Windows makes it impossible to obtain the the \033[200~ and \033[201~ ANSI codes that tell me where pasted text begins and ends, unless ENABLE_VIRTUAL_TERMINAL_INPUT is enabled. It's not possible for me to enable this flag, because that flag is problematic and removes win32 capabilities when it's enabled, such as the ability to poll console input. If I've put the terminal into bracketed paste mode by writing the virtual ANSI sequences to the output handle, which does have virtual mode enabled, then the console should not filter out and remove those ANSI codes when they get sent to my input. The ENABLE_VIRTUAL_TERMINAL_INPUT flag presence should be ignored in this specific case.

Originally created by @jart on GitHub (Oct 22, 2024). Originally assigned to: @DHowett on GitHub. ### Windows Terminal version 1.22.2702.0 ### Windows build number 10 ### Other Software This issue applies broadly to all WIN32 software. In my case, I happen to be working on Cosmopolitan Libc. ### Steps to reproduce 1. Use SetConsoleMode() to *disable* the `ENABLE_VIRTUAL_TERMINAL_INPUT` flag on `GetStdHandle(STD_INPUT_HANDLE)`. 2. Use SetConsoleMode() to *enable* the `ENABLE_VIRTUAL_TERMINAL_PROCESSING` flag on `GetStdHandle(STD_OUTPUT_HANDLE)`. 3. Write the string `"\033[?2004h"` to standard output, to enable bracketed paste mode. 4. Press ctrl-shift-v or shift-ins to paste text with multiple lines into the terminal. 5. Reading from standard input will give you the pasted text (but it's supposed to surround the paste with `"\033[200~"` and `"\033[201~"`) If you're a Cosmopolitan Libc fan and have `cosmocc` installed from our GitHub releases page, then here's a simple program that can reproduce this without needing to write any WIN32 code. ```c void Write(const char *s) { write(1, s, strlen(s)); } int main(int argc, char *argv[]) { Write("\033[?2004h"); char buf[512]; int rc = read(0, buf, 512); Write("\033[?2004l"); printf("got %`'.*s\n", rc, buf); } ``` See also https://github.com/jart/cosmopolitan/blob/master/libc/calls/read-nt.c if you're curious about our termios driver. ### Expected Behavior If I enable bracketed paste mode on the terminal, then I believe it should insert the `"\033[200~"` and `"\033[201~"` ANSI codes into the paste, even if `ENABLE_VIRTUAL_TERMINAL_INPUT` is disabled. Cosmopolitan Libc needs this. Cosmo is similar to Cygwin in that it implements POSIX on Windows. For example, common utilities like bash and emacs can be compiled with cosmo libc and then run in the command prompt. I've been very successful making this work well. This bug is the one problem I can't solve unless Microsoft fixes things. It is impossible to work around this issue. Why is that? Cosmopolitan Libc always wants a virtual ANSI style Linux-like terminal. To do that, we always enable `ENABLE_VIRTUAL_TERMINAL_PROCESSING` on standard output. Virtual terminal output works fantastically with your tools. However Cosmo *never* uses `ENABLE_VIRTUAL_TERMINAL_INPUT` because it isn't very good. Virtual terminal input is a toy feature that makes important use cases impossible, such as polling console input. Cosmopolitan Libc *always* uses ReadConsoleInput() and GetNumberOfConsoleInputEvents() to read console input and then manually translates `INPUT_RECORD` to ANSI codes and implements things like canonical mode line editing because there's no other way. However there's one and only one occasion where I actually DO want WIN32 to inject `\033[200~` and `\033[201~` ANSI codes into my input, and that's for bracketed paste mode. Windows should either do this, or it should generate `INPUT_RECORD` events that tell me where the paste begins and ends. But Windows does neither and that's a huge painful issue for me. ### Actual Behavior Windows makes it impossible to obtain the the `\033[200~` and `\033[201~` ANSI codes that tell me where pasted text begins and ends, unless `ENABLE_VIRTUAL_TERMINAL_INPUT` is enabled. It's not possible for me to enable this flag, because that flag is problematic and removes win32 capabilities when it's enabled, such as the ability to poll console input. If I've put the terminal into bracketed paste mode by writing the virtual ANSI sequences to the output handle, which _does_ have virtual mode enabled, then the console should not filter out and remove those ANSI codes when they get sent to my input. The `ENABLE_VIRTUAL_TERMINAL_INPUT` flag presence should be ignored in this specific case.
claunia added the Issue-QuestionIssue-BugNeeds-Tag-FixResolution-Answered labels 2026-01-31 08:13:13 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#22437