xtermjs / xterm.js

A terminal for the web
https://xtermjs.org/
MIT License
17.78k stars 1.64k forks source link

Support win32-input-mode for more complete key support on Windows #2357

Open Tyriar opened 5 years ago

Tyriar commented 5 years ago

If/when conpty supports this then it could get PSReadline keybindings working, see https://github.com/microsoft/terminal/issues/879

Tyriar commented 3 years ago

@zadjii-msft am I reading https://github.com/microsoft/terminal/pull/6309 right in that you just have a separate mode that when enabled passes all input over the Windows Console API instead of via VT text (and using CSI > Ps ; Ps m to infer the modifiers)?

zadjii-msft commented 3 years ago

Sort of. If you enable that mode, then we'll accept input to conpty in win32-input-mode format, and then console apps can read that back out as a INPUT_RECORD (if they're using the Win32 API), or we'll still translate it to VT (if they're using VT input). So xterm.js could theoretically encode whole KEY_EVENT_RECORDs as text, write that to conpty, and the client app on the other side will do the right thing (whatever it wanted to do originally). This gets rid of the ambiguity of sending VT input to ConPTY and having it try to translate it to a higher-fidelity INPUT_RECORD, at the cost of the implementing terminal needing to know how to do this encoding.

I never really got around to documenting this super well. The best example is at https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md. IIRC we also did hide this behind a conpty flag so a Terminal that wanted to do this would have to explicitly opt-in. If you're interested at taking a swing at doing this on the xterm.js side, I can help as best I can ☺️ We may need to bump the priority of shipping a package for updated conpty versions, since this is code that would only be present on... Windows 11? Heck I don't even know what OS build that got into.

Tyriar commented 3 years ago

Ah I see thanks, so when CSI ? 9001 h is received we would switch to a different way of encoding the keystrokes. The fact that this feature could be encapsulated entirely within xterm.js is nice.

akbyrd commented 1 year ago

I ran into this recently. It's actually really hard to create PowerShell bindings that also work in xterm. Here are the results from trying to bind the period key on a US keyboard:

Modifiers Key pwsh win-term xterm vscode
Ctrl . :heavy_check_mark: :heavy_check_mark: :x: :x:
Ctrl OemPeriod :heavy_check_mark: :heavy_check_mark: :x: :x:
Alt . :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: :x:
Ctrl Shift > :heavy_check_mark: :heavy_check_mark: :x: :x:
Ctrl Shift OemPeriod :heavy_check_mark: :heavy_check_mark: :x: :x:
Ctrl Alt OemPeriod :heavy_check_mark: :heavy_check_mark: :x: :x:
Shift Alt > :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: :x:
Ctrl Shift Alt OemPeriod :heavy_check_mark: :heavy_check_mark: :x: :x:

In the case of the vscode if you want to retain mnemonics in terminal editors there are literally no valid bindings with the period key.

Tyriar commented 1 year ago

@akbyrd fyi vscode actually has special logic in shell integration to enable these keybindings in pwsh:

alt+., shift+alt+>

We should be able to support these if we know what xterm sends

In the case of the vscode if you want to retain mnemonics in terminal editors there are literally no valid bindings with the period key.

terminal.integrated.allowMnemonics defaults to false so alt+. should be able to work by default

akbyrd commented 1 year ago

vscode actually has special logic in shell integration to enable these keybindings in pwsh

That makes sense. I just encountered the Ctrl+Backspace weirdness. vscode sends Ctrl+W instead, and if you have that bound to something else, say Exit-Shell, you get a surprise.

terminal.integrated.allowMnemonics defaults to false so alt+. should be able to work by default

Well yea, but I want mnemonics to work. I use terminal editors and it feels weird to have to switch to another editor to be able to open a folder.

Side note, the implementation for that is unnecessarily conservative. I can bind e.g. Alt+. in vscode and not lose the ability to open the file menu with Alt+F. But in the terminal once that setting is on every Alt and Ctrl+Alt combo skips the terminal, regardless of whether it's actually a mnemonic.

Tyriar commented 1 year ago

Side note, the implementation for that is unnecessarily conservative. I can bind e.g. Alt+. in vscode and not lose the ability to open the file menu with Alt+F. But in the terminal once that setting is on every Alt and Ctrl+Alt combo skips the terminal, regardless of whether it's actually a mnemonic.

If you have a keybinding setup for alt+. it should work:

https://github.com/microsoft/vscode/blob/badc45c0fba9c9a58fa407e78722a2ae982e9ee7/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts#L998-L1026

So you could use this to get the behavior you're after before alt+. is supported properly in xterm.js:

{ "key": "alt+.", "command": "workbench.action.terminal.sendSequence", "args": { "text": "whatever alt+. sends" } }