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

Make the terminal emulator escape codes configurable for F-keys, etc. #2005

Closed
vblazhkun opened this issue Jul 17, 2019 · 10 comments
Closed
Labels
Area-Input Related to input processing (key presses, mouse, etc.) Area-Settings Issues related to settings and customizability, for console or terminal Area-VT Virtual Terminal sequence support Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal. Resolution-Fix-Available It's available in an Insiders build or a release
Milestone

Comments

@vblazhkun
Copy link

Summary of the new feature/enhancement

@DHowett Make the terminal emulator escape codes, associated with functional keys, keypad, cursor keys, etc., configurable via profile.json. At the moment they are hardcoded within terminal/src/terminal/input/terminalInput.cpp. Such causes troubles while working with remote GNU/Linux shells from different terminal emulators, having the same TERM environment variable set.

For the reference: most popular terminal emulators, available on the market, have such an ability.

Proposed technical implementation details (optional)

Just add the configuration keywords for the described keys into the profile.json and make the ability to override the hardcoded escape sequences.

@vblazhkun vblazhkun added the Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. label Jul 17, 2019
@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 Jul 17, 2019
@egmontkob
Copy link

My 2 cents:

most popular terminal emulators, available on the market, have such an ability

The VTE terminal emulator widget, which I'm a developer of, has hardcoded escape sequences for the keys.

VTE is used by at least a dozen terminal emulator applications, including GNOME Terminal, Xfce4 Terminal, Terminator, Tilix, Guake, Roxterm just to name a few. According to various polls, I have the impression that VTE's market share (in terms of number of users) among graphical terminal emulators under Linux is in the ballpark of 50%, which is pretty significant.

I keep an eye on the issue trackers of most VTE-based emulators, plus several forums. Ever since we changed our sequences to xterm-compatible (around 5 years ago), or more precisely, I should say "compatible with whatever the terminfo definition matching our $TERM says", we no longer get complaints about wrong sequences and hardly ever get a request for making these user configurable.

Whenever it's a request, it's in the form of being able to differentiate two things that currently produce the same sequence, e.g. Enter from Shift+Enter; and not along the lines of let's say Home should generate \e[1~ instead of \e[H. This would be nice to have, but should work automatically without the user having to configure anything, e.g. the application enabling some extension which then modifies the emitted keys.

Let's be honest, having to configure technical details like which key generates what sequence should be a thing of the past, it's a sign of an absolutely user-unfriendly developer attitude (which we carry from the past).

I'm not against this feature request, but maybe your particular use case should be studied first, examined whether perhaps you do something wrong (e.g. have the wrong TERM set somewhere), see whether it's a common request. Maybe Windows Terminal could ship a few hardcoded keymaps, e.g. one for xterm and friends, one for the Linux console.

Allowing the user to configure the keys is probably complicated. E.g. in VTE, F1 generates \e[OP but F1 with any modifier generates \e[1;nP where n encodes the modifiers. There's an "application keypad" vs. "normal keypad" mode (switched by escape sequences) which modifies the sequence of some of the keys, and an "application cursor keys" vs. "normal cursor keys" mode to modify the sequences of some others. Xterm has about 5 different function key modes (PC, VT220, VT52, Sun, HP), VTE used to have these but then luckily we dropped them. Then there are the regular keyboard modifiers (Shift, Ctrl, Alt) and NumLock's state. Take a look at the files attached to VTE bug 600659 comment 75 and comment 76 to get an idea how many dimensions and how many values there are, it's truly scary (even just the fifth of it, without the function key modes that we dropped from VTE, is still scary). Even exposing the possibility of defining all of these by a user in a text config file (let alone in a way that allows the modifiers to be encoded dynamically and allows to have an exception when no modifier is pressed) is nontrivial for the developers and nontrivial for the users who wish to configure them, and might not be in the correct direction for solving keyboard related problems.

That being said, if Windows Terminal developers find your idea a great one and implement it, I'm by no means trying to stop them.

@vblazhkun
Copy link
Author

@egmontkob Many thanks for the comment, very useful.

Let me describe my use case in more details. I use different terminal emulators connecting to the remote GNU/Linux shell. Each terminal emulator supplies a correct TERM definition, e.g.:

  • TERM=linux-16color
  • TERM=xterm-256color
  • TERM=putty-256color

I use it to bind emitted escape sequence to correct F-keys, etc., using readline or similar software on the remote shell. So far, there no issues. They start when I run a terminal multiplexer like screen. Terminal multiplexers have their own terminal capabilities, thus different TERM names and settings:

  • TERM=screen.linux
  • TERM=screen.putty-256color
  • TERM=screen-256color-bce-s

As I detach screen from different terminal emulators, I need to:

  1. Build a terminfo file, combining, e.g., PuTTY and screen or xterm and screen.
  2. Set the TERM to the combined terminfo name based on the original terminal emulator name, I am detaching the screen from.
  3. Update the TERM for all opened terminal multiplexer windows, which may have totally different applications opened. They may not have such an ability. Also, dynamic TERM update for screen is not that trivial.
  4. Multi-user window sharing is impossible.

That is why, I would prefer consistent (configurable) escape codes bindings in each terminal emulator I use.

@oising
Copy link
Collaborator

oising commented Jul 17, 2019

@egmontkob Funnily enough, I've been looking at this at the moment and I'm evaluating using xterm's modifyOtherKeys - and related settings modifyKeyboard, modifyFunctionKeys etc - for a model in Windows Terminal. As a developer on the VTE team, have you looked at this yourself? How widely is it understood/accepted/used?

I prefer this approach of having a well-known scheme for emitting sequences for modifiers, and allow people to modify the bindings on the consuming applications instead of modifying the emitted sequences on the terminal itself.

@oising oising added Area-Input Related to input processing (key presses, mouse, etc.) Area-Output Related to output processing (inserting text into buffer, retrieving buffer text, etc.) Area-Settings Issues related to settings and customizability, for console or terminal Area-VT Virtual Terminal sequence support and removed Needs-Tag-Fix Doesn't match tag requirements Area-Output Related to output processing (inserting text into buffer, retrieving buffer text, etc.) labels Jul 17, 2019
@egmontkob
Copy link

I have to admit I'm not familiar with the details of screen.linux etc. definitions.

However, what definitely happens for me is that screen does the necessary transformation of keys and such. E.g. while Home generates a ^[[H in native gnome-terminal (or ^[OH in application cursor mode, but never ^[[1~), if I fire up a screen inside gnome-terminal I get a ^[[1~.

Now, having multiple variants of TERM=screen-foo is indeed bad and potentially a source of confusion, not just with keypresses, when you detach and reattach from a different terminal. E.g. you start screen from PuTTY, thus TERM=screen.putty-256color is set, detach, reattach from Linux console and you're still at TERM=screen.putty-256color instead of TERM=screen.linux. And, for example, an application incorrectly believes that your terminal emulator supports 256 colors while it doesn't.

I'm afraid that there's no real solution here. The TERM variable was designed with the idea that the actual capabilities of a terminal cannot change runtime, which is no longer true with screen/tmux detaching/attaching. (In fact, since a screen/tmux can be attached from multiple host terminals at once, even the concept of "capabilities" isn't that clear; what if only one of those two hosts support something?)

One possible solution could be if screen always set one fixed TERM inside, e.g. TERM=screen, no matter where you connected from, which would describe all the features that screen supports if the underlying terminal does, and for those terminals that don't screen would gracefully reduce them to the terminal's capabilities (e.g. rounding 256-colors to the nearest of the 8/16-color palette). This could also be confusing to apps, e.g. they'd always believe that 256 colors are supported.

I'm not sure whether this is only a problem with the output, or also with the input (keys) that this issue is about. E.g. I'm not sure what stops screen from correctly recognizing the F1 keypress from whichever host terminal it is attached to, and converting it to the F1 that it needs inside. Of course this can only work if TERM=screen.foobar inherits F1's behavior from TERM=screen rather than TERM=foobar, so that the keycode used inside screen doesn't change when you reattach from a different host. If it's not the case, it could be filed as a bug / improvement request against screen, or you could check if tmux does better here.

Back to your request of redefining keys: There's one more indirection to this story, since screen does modify the escape sequences they generate, and probably the way this rewriting happens depends on the host terminal, and probably (but this needs to be double checked) the rewriting rules are updated as you detach and reattach from a different host terminal. So you'd need to find the keycodes that screen happens to rewrite in a way that they end up whatever you need there. It's an even much scarier story than defining the keycodes to whatever you want to see in the first place, and another sign that trying to solve it in the terminal's keybindings is a hackish workaround rather than the nicely designed solution to the problem :)

@egmontkob
Copy link

@oising VTE doesn't support modifyOtherKeys and friends. I've looked at it, see VTE 730157, but xterm's behavior seemed to be inconsistent to me. See also Tilix 1183 and iTerm2 5377.

The current extension seems broken to me, designing a good one is extremely hard (as per my last comment in the Tilix thread), thus the gain:investment ratio looked pretty bad for me to work on this.

I don't know how much other terminals or apps support these.

@oising
Copy link
Collaborator

oising commented Jul 18, 2019

@egmontkob Great references, thank you. Windows Terminal has a rather unique mandate in that it tries to transparently handle console applications that may consume and/or emit VT or call win32 console APIs. With this in mind, there's a need to be able to encode anything that can come through the console API (which is pretty much anything) and pass it over the pseudo tty as a VT sequence, and optionally translate it back into API responses. Rather than invent something completely new, if we use this scheme, we can also allow it to pass through raw to clients, if they request VT.

@vblazhkun
Copy link
Author

vblazhkun commented Jul 19, 2019

@egmontkob I have not finished reviewing all the references you provided yet, but there is one more relevant suggestion which is important (to my opinion) and fairly trivial to implement.

As Windows Terminal is not 100% compatible with the xterm specification and, at the same time, the specification allows different escape codes to be emitted in different terminal emulation modes, there should be a configuration option, allowing modification of the default TERM, Windows Terminal provides (VtIoModes.hpp).

I have checked the terminfo database and there are about 100 different xterms defined, so, I assume, it is a normal practice to differentiate various xterm implementations (one could even think about setting the TERM to windows-terminal and arrange a corresponding terminfo entry).

UPD: They already have ms-terminal entry there, but I see nothing in the Windows Terminal repository, mentioning that.

What do you think?

@miniksa miniksa removed the Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting label Aug 1, 2019
@ghost ghost added the Needs-Tag-Fix Doesn't match tag requirements label Aug 1, 2019
@zadjii-msft zadjii-msft added the Product-Terminal The new Windows Terminal. label Aug 2, 2019
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Aug 2, 2019
@zadjii-msft
Copy link
Member

I will add that we definitely didn't publish that ms-terminal entry. I'm positive that we have no intention of having our own entry before we hit 1.0, as we're fairly buggy at the moment, and there's a lot of code delta occurring.

I certainly don't want to entertain this feature for 1.0, since it seems like a bit of a can of worms. At the very most I could see us supporting some sort of options like PuTTY, where you can configure the general behavior of categories of keys, but not override individual keys.
image

This is also a bit trickier of a problem than it might seem at first, since (in general) the Terminal isn't actually generating these keys to send them to the client application, conpty is. So even if we could configure these keys for connections that don't involve conpty (e.g. the Azure connector), we'd need some way for us to communicate down to the conpty to tell it to change which sequences to emit. It's certainly not going to be a small task.

@Kytech
Copy link

Kytech commented Mar 17, 2020

I second the idea of giving a menu similar to what Putty presents, just implemented in profiles.json. I use a serial connection to access a linux terminal on an embedded device. When I use plink and Windows Terminal, the function keys and arrow keys do not work. However, when I use Putty with the linux function character options, everything works perfectly. I know there was the mention of trying to make it auto-detectable, but this would likely be quite difficult with a serial connection since it could be anything. Would be even better if Windows Terminal supported serial connections natively, but that probably wouldn't even be a possibility until we're able to configure the function key codes to a common list of presets.

@zadjii-msft zadjii-msft modified the milestones: Terminal Backlog, Backlog Jan 4, 2022
@zadjii-msft
Copy link
Member

Huh. Coming across this feature request again, and I think this is absolutely doable with the sendInput action. You can use that to rebind keys to send whatever you'd like.

That shipped a few releases ago, so that should be in stable by now.

@ghost ghost added the Needs-Tag-Fix Doesn't match tag requirements label Jan 20, 2022
@zadjii-msft zadjii-msft added the Resolution-Fix-Available It's available in an Insiders build or a release label Jan 20, 2022
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Jan 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Input Related to input processing (key presses, mouse, etc.) Area-Settings Issues related to settings and customizability, for console or terminal Area-VT Virtual Terminal sequence support Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Terminal The new Windows Terminal. Resolution-Fix-Available It's available in an Insiders build or a release
Projects
None yet
Development

No branches or pull requests

6 participants