Ctrl+Keys that can't be encoded as VT should still fall through as the unmodified character #4869

Closed
opened 2026-01-30 23:58:36 +00:00 by claunia · 17 comments
Owner

Originally created by @mattaferreira on GitHub (Nov 8, 2019).

Environment

Windows build number: Microsoft Windows [Version 10.0.18362.418]
Windows Terminal version (if applicable): Version: 0.6.2951.0

Any other software?
WSL2

Steps to reproduce

It is very convenient to use emacs to reproduce this, since it can show received key sequences

  1. All shortcuts in Terminal need to be unbound, so open settings and set every command in keybindings to null.
  2. Open emacs
  3. Press C-h l (for non-emacs users, Control+h then L by itself). This shows the most recent key sequences at the bottom.
  4. Press C-, or C-. or C-; or C-'
  5. Press C-h l again. None of the above sequences are displayed.

It is possible to bind one of those keys to an actual emacs command, just to make sure emacs isn't dropping a sequence it doesn't care about, but the result should be the same.

Note that pressing the four above punctuation keys by themselves, or combined with Shift, works as expected.

Expected behavior

C-h l should display all of the entered sequences. If a command is bound, it should execute.

Actual behavior

No sequences are displayed, no commands execute.

Originally created by @mattaferreira on GitHub (Nov 8, 2019). <!-- 🚨🚨🚨🚨🚨🚨🚨🚨🚨🚨 I ACKNOWLEDGE THE FOLLOWING BEFORE PROCEEDING: 1. If I delete this entire template and go my own path, the core team may close my issue without further explanation or engagement. 2. If I list multiple bugs/concerns in this one issue, the core team may close my issue without further explanation or engagement. 3. If I write an issue that has many duplicates, the core team may close my issue without further explanation or engagement (and without necessarily spending time to find the exact duplicate ID number). 4. If I leave the title incomplete when filing the issue, the core team may close my issue without further explanation or engagement. 5. If I file something completely blank in the body, the core team may close my issue without further explanation or engagement. All good? Then proceed! --> <!-- This bug tracker is monitored by Windows Terminal development team and other technical folks. **Important: When reporting BSODs or security issues, DO NOT attach memory dumps, logs, or traces to Github issues**. Instead, send dumps/traces to secure@microsoft.com, referencing this GitHub issue. If this is an application crash, please also provide a Feedback Hub submission link so we can find your diagnostic data on the backend. Use the category "Apps > Windows Terminal (Preview)" and choose "Share My Feedback" after submission to get the link. Please use this form and describe your issue, concisely but precisely, with as much detail as possible. --> # Environment ```none Windows build number: Microsoft Windows [Version 10.0.18362.418] Windows Terminal version (if applicable): Version: 0.6.2951.0 Any other software? WSL2 ``` # Steps to reproduce <!-- A description of how to trigger this bug. --> It is very convenient to use emacs to reproduce this, since it can show received key sequences 1. All shortcuts in Terminal need to be unbound, so open settings and set every command in keybindings to null. 1. Open emacs 1. Press C-h l (for non-emacs users, Control+h then L by itself). This shows the most recent key sequences at the bottom. 1. Press C-, or C-. or C-; or C-' 1. Press C-h l again. None of the above sequences are displayed. It is possible to bind one of those keys to an actual emacs command, just to make sure emacs isn't dropping a sequence it doesn't care about, but the result should be the same. Note that pressing the four above punctuation keys by themselves, or combined with Shift, works as expected. # Expected behavior <!-- A description of what you're expecting, possibly containing screenshots or reference material. --> C-h l should display all of the entered sequences. If a command is bound, it should execute. # Actual behavior <!-- What's actually happening? --> No sequences are displayed, no commands execute.
Author
Owner

@zadjii-msft commented on GitHub (Nov 8, 2019):

Huh. Curiously, I don't think those keys are possible to bind even in gnome-terminal:
image

On the left, I have a gnome-terminal window running on WSL via vcxsrv. Even there, these keystrokes are only coming through as ,, ., ;, and '. I was under the impression that these keystrokes were not things that were possible to encode as VT sequences.

Maybe this is something that needs more support, something like the xterm extended keyboard modifiers (which was proposed earlier on the repo here).

For linking purposes, #879 is a related problem.

I'm curious what @egmontkob and @j4james's thoughts are on the subject

(edit: I'm marking this for conhost, not the Terminal, since it A: doesn't work in conhost and should, and B: fixing this for conhost should just fix it for the Terminal).

@zadjii-msft commented on GitHub (Nov 8, 2019): Huh. Curiously, I don't think those keys are possible to bind even in `gnome-terminal`: ![image](https://user-images.githubusercontent.com/18356694/68481052-cf074280-01fb-11ea-8120-a30741da7dce.png) On the left, I have a `gnome-terminal` window running on WSL via `vcxsrv`. Even there, these keystrokes are only coming through as `,`, `.`, `;`, and `'`. I was under the impression that these keystrokes were not things that were possible to encode as VT sequences. Maybe this is something that needs more support, something like the xterm extended keyboard modifiers (which was proposed earlier on the repo [here](https://github.com/microsoft/terminal/issues/879#issuecomment-501001017)). For linking purposes, #879 is a related problem. I'm curious what @egmontkob and @j4james's thoughts are on the subject (edit: I'm marking this for _conhost_, not the Terminal, since it A: doesn't work in conhost and should, and B: fixing this for conhost _should_ just fix it for the Terminal).
Author
Owner

@egmontkob commented on GitHub (Nov 8, 2019):

C-h

This is already problematic, since depending on the erase character (see e.g. gnome-terminal's Compatibility prefs for one side of the story, and stty erase for the other side) this might be the same as Backspace.

these keystrokes are only coming through as ,, ., ;, and '

Yup, just as there's no Ctrl + accented letters, and such. The 0x00..0x1F chars are traditionally denoted as Ctrl+letter and such, as you know, and this is exactly what the Ctrl modifier does in terminals by default. (It's a computer-friendly and not a user-friendly behavior.)

xterm extended keyboard modifiers

That's the next thing that occurred to me. I really don't like this protocol, see here.

Kitty has an extension, maybe iTerm2 too, and some folks on Terminal WG began to design a new one. Alas I'm really not convinced that they have enough experience with keyboard handling (including int'l layouts and whatnot) to do it properly. This looks like a task to me that would require way more studying of the state of the art than they did.

So, I don't know what could be a proper solution here. Mind you, we don't support any extension like this in g-t, and people hardly ever complain. So maybe you can wait with it for a year or two :)

@egmontkob commented on GitHub (Nov 8, 2019): > C-h This is already problematic, since depending on the erase character (see e.g. gnome-terminal's Compatibility prefs for one side of the story, and `stty erase` for the other side) this might be the same as Backspace. > these keystrokes are only coming through as ,, ., ;, and ' Yup, just as there's no Ctrl + accented letters, and such. The 0x00..0x1F chars are traditionally denoted as Ctrl+letter and such, as you know, and this is exactly what the Ctrl modifier does in terminals by default. (It's a computer-friendly and not a user-friendly behavior.) > xterm extended keyboard modifiers That's the next thing that occurred to me. I really don't like this protocol, see [here](https://bugzilla.gnome.org/show_bug.cgi?id=730157). Kitty has an extension, maybe iTerm2 too, and some folks on Terminal WG began to design a new one. Alas I'm really not convinced that they have enough experience with keyboard handling (including int'l layouts and whatnot) to do it properly. This looks like a task to me that would require way more studying of the state of the art than they did. So, I don't know what could be a proper solution here. Mind you, we don't support any extension like this in g-t, and people hardly ever complain. So maybe you can wait with it for a year or two :)
Author
Owner

@j4james commented on GitHub (Nov 9, 2019):

I don't think our handling of these keys is quite correct. Technically something like Ctrl-. should produce a . rather than nothing (assuming we're following XTerm's behaviour), but I don't suppose that's going to make a whole lot of difference to someone wanting it to map to a unique sequence.

Also, it's worth noting that we can behave differently with an international keyboard. For example, Ctrl-' produces NUL on a UK keyboard, I'm guessing that's because Shift-' is @, but that's not the way XTerm works.

As for the XTerm extended keyboard modifiers, I haven't look at those before, so I don't know how useful they'd be, but I'd personally like to get the basics sorted out first before starting on anything like that.

Keyboard handling is quite a large area of work, so I wonder if it's worth putting together a spec documenting exactly what we expect the behaviour to be, even if we don't have it all implemented yet. That way users can more easily see if a particular behaviour is deliberate, or a bug, or just not yet done.

@j4james commented on GitHub (Nov 9, 2019): I don't think our handling of these keys is quite correct. Technically something like `Ctrl-.` should produce a `.` rather than nothing (assuming we're following XTerm's behaviour), but I don't suppose that's going to make a whole lot of difference to someone wanting it to map to a unique sequence. Also, it's worth noting that we can behave differently with an international keyboard. For example, `Ctrl-'` produces `NUL` on a UK keyboard, I'm guessing that's because `Shift-'` is `@`, but that's not the way XTerm works. As for the XTerm extended keyboard modifiers, I haven't look at those before, so I don't know how useful they'd be, but I'd personally like to get the basics sorted out first before starting on anything like that. Keyboard handling is quite a large area of work, so I wonder if it's worth putting together a spec documenting exactly what we expect the behaviour to be, even if we don't have it all implemented yet. That way users can more easily see if a particular behaviour is deliberate, or a bug, or just not yet done.
Author
Owner

@herolover commented on GitHub (Jan 9, 2020):

ctrl + backspace also doesn't work.

@herolover commented on GitHub (Jan 9, 2020): ctrl + backspace also doesn't work.
Author
Owner

@zadjii-msft commented on GitHub (Jan 9, 2020):

@herolover That particular keystroke is actually unrelated to this problem - ctrl+bksp actually has a fix in PR over in #3935

@zadjii-msft commented on GitHub (Jan 9, 2020): @herolover That particular keystroke is actually unrelated to this problem - <kbd>ctrl+bksp</kbd> actually has a fix in PR over in #3935
Author
Owner

@tai commented on GitHub (Feb 17, 2020):

Ctrl+SPACE also does not seem to go through.
I have { "command": "unbound", "keys": ["ctrl+space"]} in my profiles.json but emacs still does not receive it. Ctrl+space is needed to set mark in editing buffer as a starting point of all kinds of range operations (cut, copy, etc), so it's making emacs (and all tools with emacs-like binding) impossible to use.

In emacs, you can do "C-q " to show raw input emacs is seeing for a input. Compared with cmder terminal (terminal I'm now using), doing "C-q C-space" yielded "^@" on emacs-on-cmder, whereas emacs-on-WIndowsTerminal yielded nothing.

@tai commented on GitHub (Feb 17, 2020): Ctrl+SPACE also does not seem to go through. I have ``` { "command": "unbound", "keys": ["ctrl+space"]}``` in my profiles.json but emacs still does not receive it. Ctrl+space is needed to set mark in editing buffer as a starting point of all kinds of range operations (cut, copy, etc), so it's making emacs (and all tools with emacs-like binding) impossible to use. In emacs, you can do "C-q <key>" to show raw input emacs is seeing for a <key> input. Compared with cmder terminal (terminal I'm now using), doing "C-q C-space" yielded "^@" on emacs-on-cmder, whereas emacs-on-WIndowsTerminal yielded nothing.
Author
Owner

@smonff commented on GitHub (Mar 31, 2020):

Ctrl+SPACE also does not seem to go through.
Ctrl+space is needed to set mark in editing buffer as a starting point of all kinds of range operations (cut, copy, etc), so it's making emacs (and all tools with emacs-like binding) impossible to use.

As a workaround, you can use M-x set-mark-command.

@smonff commented on GitHub (Mar 31, 2020): > Ctrl+SPACE also does not seem to go through. > Ctrl+space is needed to set mark in editing buffer as a starting point of all kinds of range operations (cut, copy, etc), so it's making emacs (and all tools with emacs-like binding) impossible to use. As a workaround, you can use `M-x set-mark-command`.
Author
Owner

@tai commented on GitHub (Mar 31, 2020):

Okay, it might not be "impossible", but requiring M-x function for every range operation makes Emacs almost useless - that's not a realistic alternative. Breaking CTRL+key combination here and there is a dealbreaker for apps with Emacs and Emacs-like key binding which heavily uses such key combination.

@tai commented on GitHub (Mar 31, 2020): Okay, it might not be "impossible", but requiring M-x function for every range operation makes Emacs almost useless - that's not a realistic alternative. Breaking CTRL+key combination here and there is a dealbreaker for apps with Emacs and Emacs-like key binding which heavily uses such key combination.
Author
Owner

@etern commented on GitHub (May 9, 2021):

Use WSL1 outside of terminal, C-, or C-. or C-; or C-' just not work.

Use WSL1 inside Terminal 1.7.1033.0, those keys automatically translate to other keys:
C-, ==> C-l
C-. ==> C-n
C-; ==> ESC
C-' ==> C-g

@etern commented on GitHub (May 9, 2021): Use WSL1 outside of terminal, C-, or C-. or C-; or C-' just not work. Use WSL1 inside Terminal 1.7.1033.0, those keys automatically translate to other keys: C-, ==> C-l C-. ==> C-n C-; ==> ESC C-' ==> C-g
Author
Owner

@KalleOlaviNiemitalo commented on GitHub (May 9, 2021):

I'm not sure about modern Emacs versions, but Emacs 19 binds e.g. C-x @ c to event-apply-control-modifier, which reads a key and adds Control to it. So if you bind e.g. { "command": { "action": "sendInput", "input": "\u0018@c," }, "keys": "ctrl+," } in Windows Terminal, then Emacs should recognise this sequence as Ctrl+, and run whatever command you bind to that. That seems unlikely to work in applications other than Emacs, though.

@KalleOlaviNiemitalo commented on GitHub (May 9, 2021): I'm not sure about modern Emacs versions, but Emacs 19 binds e.g. C-x @ c to event-apply-control-modifier, which reads a key and adds Control to it. So if you bind e.g. `{ "command": { "action": "sendInput", "input": "\u0018@c," }, "keys": "ctrl+," }` in Windows Terminal, then Emacs should recognise this sequence as Ctrl+, and run whatever command you bind to that. That seems unlikely to work in applications other than Emacs, though.
Author
Owner

@cpbotha commented on GitHub (May 25, 2021):

I'm not sure about modern Emacs versions, but Emacs 19 binds e.g. C-x @ c to event-apply-control-modifier, which reads a key and adds Control to it. So if you bind e.g. { "command": { "action": "sendInput", "input": "\u0018@c," }, "keys": "ctrl+," } in Windows Terminal, then Emacs should recognise this sequence as Ctrl+, and run whatever command you bind to that. That seems unlikely to work in applications other than Emacs, though.

Thank you very much for this! I can confirm that it still works with Emacs 28.0.50, built from the current master branch on 2021-05-21. Now I can org-insert-structure-template again!

@cpbotha commented on GitHub (May 25, 2021): > I'm not sure about modern Emacs versions, but Emacs 19 binds e.g. C-x @ c to event-apply-control-modifier, which reads a key and adds Control to it. So if you bind e.g. `{ "command": { "action": "sendInput", "input": "\u0018@c," }, "keys": "ctrl+," }` in Windows Terminal, then Emacs should recognise this sequence as Ctrl+, and run whatever command you bind to that. That seems unlikely to work in applications other than Emacs, though. Thank you very much for this! I can confirm that it still works with Emacs 28.0.50, built from the current master branch on 2021-05-21. Now I can `org-insert-structure-template` again!
Author
Owner

@KMPrg commented on GitHub (May 3, 2023):

windows terminal
version: 1.16.10261.0

emacs 27.2
C-, ==> Execute the clear command
C-. ==> Next line
C-; ==> ESC
C-' ==> Execute the quit command
C-- ==> ENTER

vim 9.0
C-, ==> Execute the clear command
C-. ==> Next line
C-; ==> ESC
C-- ==> ENTER
Command mode:
ctrl+' ==> ^G
ctrl+/ ==> ^_

@KMPrg commented on GitHub (May 3, 2023): windows terminal version: 1.16.10261.0 emacs 27.2 C-, ==> Execute the clear command C-. ==> Next line C-; ==> ESC C-' ==> Execute the quit command C-- ==> ENTER vim 9.0 C-, ==> Execute the clear command C-. ==> Next line C-; ==> ESC C-- ==> ENTER Command mode: ctrl+' ==> ^G ctrl+/ ==> ^_
Author
Owner

@Thfvdb commented on GitHub (Feb 6, 2024):

I've tried this in prerelease 1.20.10293.0 and see a change, but I don't think the original issue is resolved. What I get in Emacs is the following:
C-, ==> ,
C-. ==> .
C-; ==> ;
C-' ==> ostensibly nothing
C-- ==> -
So the Ctrl seems to get dropped for most keys, and C-' doesn't seem to do anything at all.

@Thfvdb commented on GitHub (Feb 6, 2024): I've tried this in prerelease 1.20.10293.0 and see a change, but I don't think the original issue is resolved. What I get in Emacs is the following: C-, ==> , C-. ==> . C-; ==> ; C-' ==> ostensibly nothing C-- ==> - So the Ctrl seems to get dropped for most keys, and C-' doesn't seem to do anything at all.
Author
Owner

@j4james commented on GitHub (Feb 6, 2024):

@Thfvdb None of those keys have Ctrl mappings in the VT standard, so they are supposed to generate the base key. From the issue title:

Ctrl+Keys that can't be encoded as VT should still fall through as the unmodified character

Ctrl+' should also just generate a ' character, but it's possible that in some cases it might do something different depending on your keyboard layout.

If you're looking for a way to bind keys in Emacs that don't have unique mappings in the VT standard, that would require a new keyboard protocol, of which there have been a number of different proposals (see for example #8719 and #11509). I don't know if Emacs supports any of them though.

@j4james commented on GitHub (Feb 6, 2024): @Thfvdb None of those keys have Ctrl mappings in the VT standard, so they are supposed to generate the base key. From the issue title: > Ctrl+Keys that can't be encoded as VT should still fall through as the unmodified character <kbd>Ctrl</kbd>+<kbd>'</kbd> should also just generate a `'` character, but it's possible that in some cases it might do something different depending on your keyboard layout. If you're looking for a way to bind keys in Emacs that don't have unique mappings in the VT standard, that would require a new keyboard protocol, of which there have been a number of different proposals (see for example #8719 and #11509). I don't know if Emacs supports any of them though.
Author
Owner

@EgorDuplensky commented on GitHub (May 12, 2024):

In case people face the same problem and find this issue, there is a full (or almost full) list of config entries to WA the issue at least for emacs:

Click to expand
    {
      "command": {
        "action": "sendInput",
        "input": "\u0018@c;"
      },
      "keys": "ctrl+;"
    },
    {
      "command": {
        "action": "sendInput",
        "input": "\u0018@c<"
      },
      "keys": "ctrl+shift+comma"
    },
    {
      "command": {
        "action": "sendInput",
        "input": "\u0018@c,"
      },
      "keys": "ctrl+comma"
    },
    {
      "command": {
        "action": "sendInput",
        "input": "\u0018@c:"
      },
      "keys": "ctrl+shift+;"
    },
    {
      "command": {
        "action": "sendInput",
        "input": "\u0018@c>"
      },
      "keys": "ctrl+shift+period"
    },
    {
      "command": {
        "action": "sendInput",
        "input": "\u0018@c'"
      },
      "keys": "ctrl+'"
    },
    {
      "command": {
        "action": "sendInput",
        "input": "\u0018@c\""
      },
      "keys": "ctrl+shift+'"
    },
    {
      "command": {
        "action": "sendInput",
        "input": "\u0018@c-"
      },
      "keys": "ctrl+minus"
    },
    {
      "command": {
        "action": "sendInput",
        "input": "\u0018@c+"
      },
      "keys": "ctrl+plus"
    },
    {
      "command": {
        "action": "sendInput",
        "input": "\u0018@c="
      },
      "keys": "ctrl+shift+plus"
    }
@EgorDuplensky commented on GitHub (May 12, 2024): In case people face the same problem and find this issue, there is a full (or almost full) list of config entries to WA the issue at least for emacs: <details> <summary> Click to expand </summary> ``` json { "command": { "action": "sendInput", "input": "\u0018@c;" }, "keys": "ctrl+;" }, { "command": { "action": "sendInput", "input": "\u0018@c<" }, "keys": "ctrl+shift+comma" }, { "command": { "action": "sendInput", "input": "\u0018@c," }, "keys": "ctrl+comma" }, { "command": { "action": "sendInput", "input": "\u0018@c:" }, "keys": "ctrl+shift+;" }, { "command": { "action": "sendInput", "input": "\u0018@c>" }, "keys": "ctrl+shift+period" }, { "command": { "action": "sendInput", "input": "\u0018@c'" }, "keys": "ctrl+'" }, { "command": { "action": "sendInput", "input": "\u0018@c\"" }, "keys": "ctrl+shift+'" }, { "command": { "action": "sendInput", "input": "\u0018@c-" }, "keys": "ctrl+minus" }, { "command": { "action": "sendInput", "input": "\u0018@c+" }, "keys": "ctrl+plus" }, { "command": { "action": "sendInput", "input": "\u0018@c=" }, "keys": "ctrl+shift+plus" } ``` </details>
Author
Owner

@axbycc-mark commented on GitHub (Jan 21, 2025):

@EgorDuplensky Life saver! Took me a little to find where to paste that little snippet. In the settings menu of the terminal app, there is an Open JSON button, and inside that JSON there is already a list of "actions" and you paste it at the end of that list.

@axbycc-mark commented on GitHub (Jan 21, 2025): @EgorDuplensky Life saver! Took me a little to find where to paste that little snippet. In the settings menu of the terminal app, there is an Open JSON button, and inside that JSON there is already a list of "actions" and you paste it at the end of that list.
Author
Owner

@EgorDuplensky commented on GitHub (Jan 22, 2025):

Have created a gist to maintain the full list
https://gist.github.com/EgorDuplensky/58d1d9af9b29f98ddf19312f7819c3f1

@EgorDuplensky commented on GitHub (Jan 22, 2025): Have created a gist to maintain the full list https://gist.github.com/EgorDuplensky/58d1d9af9b29f98ddf19312f7819c3f1
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#4869