We currently support things like alt+arrow to jump words which is done by overriding what escape sequence we send to the pty. We should look at making this configurable with safe defaults so that consumer(s) can turn it off/configure if they desire.
This could be a keyMap like option, where we can map either key bindings or escape codes to terminal actions.
How does that sound?
Something like that is what I was thinking, however it gets tricky in the case like ctrl+v where I think the escape sequence we generate is the same as v
This is also the reason we can't use an ~/.inputrc file to get option+backspace to delete a word on Mac.
I've been thinking a lot about this recently, here is my idea (considering the many issues open on hyper related on this topic):
The main problem is, that accelerators of the app (e.g. hyper) collide with accelerators that the app running in the terminal wants to consume. To get around this problem, most apps introduce a meta key that helps to escape from the terminal. While this works in most cases, it is uncomfortable to use, because you need three fingers. So why don't we...
Use a keyboard gesture to escape the terminal
The idea is that if you double-tap a modifier key (ctrl, alt, shift, meta?), then the key will not be sent to the terminal, but will be forwarded to user, so his app can consume it. Without the double-tap, the key(s) will be consumed by the terminal.
Example: ctrl...ctrl+x or alt...alt+left will not be consumed by the terminal but forwarded as ctrl+x and alt+left to the user.
There are some edge cases that we have to consider:
Say you want to switch between tabs of an application, using ctrl+alt+left and ctrl+alt+right. Now, to jump to the left pane, you would press ctrl...ctrl+alt+left. But if you want to jump two panes to the left in a row, you don't want to press ctrl...ctrl+alt+left ctrl...ctrl+alt+left, you want to press ctrl...ctrl+alt+left left. This should be fairly easy to implement, but has to be considered.
In addition, for the very commonly used ctrl+c we should let it copy if text is selected, otherwise we should write the control sequence to the terminal.
Pasting can be done with ctrl...ctrl+v, middle or right mouse button.
@mofux for VS Code I introduced a commandsToSkipShell setting which lists off a bunch of commands whose keybindings will not be processed by xterm.js. So you should be able to intercept cases like this using Terminal.attachCustomKeydownHandler and handle it however you want at a higher level (ctrl+c + text selected -> copy, ctrl+c + no text selected -> send to xterm.js).
My personal thinking is this is more about having xterm.js handle the common keybindings that are not standard but generally desirable, but allowing consumers to opt out and/or handle it themselves.
Oh i see, having a map of actions (e.g. 'JUMP_WORD_LEFT') and a default but customisable keybinding for it would certainly make sense. Might be worth to have a mapping that looks like this:
{
"COPY": { "mac": "cmd+c", "win": "ctrl+c", "default": "ctrl+c" },
"JUMP_WORD_LEFT": { "default": "alt+left" }
}
default is the fallback if the binding for the current platform is not specified.
Hyper uses a lib called mousetrap to allow key strings like above to be interpreted.
Yeah something like that, I think this is the sort of information we need to encode:
"mac": {
"alt+delete": "\x17"
}
Pressing alt+delete will send \x17 (^W) to the pty.
Which is similar to the format of an .inputrc file, but allows the actual key presses to be overridden in cases such as alt+delete where the where delete and alt+delete return the same escape sequences.
See https://github.com/sourcelair/xterm.js/issues/486 and http://stackoverflow.com/a/29773694/1156119
So, should we settle in an option named keyMap?
Would the following format also work?
{
"all": {
"ctrl+space": "\x00"
},
"mac": {
"alt+delete": "\x17"
},
"win": {
"ctrl-v": null
}
}
Looks good, shall we construct the default keyMap first before going ahead and implementing to ensure it covers all the cases? Here's a start:
{
"all": {
"alt+left": "\x1b[1;5D",
"alt+right": "\x1b[1;5C",
"alt+up": "\x1b[1;5A",
"alt+down": "\x1b[1;5B",
"ctrl+backspace": "\x17"
},
"mac": {
"alt+left": "\x1bb", // Mac use different escape sequences to Linux for jumping word
"alt+right": "\x1bf",
"alt+delete": "\x17"
}
}
Writing this up there is the ctrl/shift+insert case which skips the terminal, should consumers now handle that if they want it via attachCustomKeydownHandler?
OK, I created this Git as my take on mac only key bindings, based on Terminal.app's configuration (which I have left to default):
https://gist.github.com/parisk/f2d7eb8bd5584d9969c2449eee9d052c
The two questions I have in mind right now are:
.js file(s) in order to be able to add comments next to each line?We could have a KeyMap.ts/Options.ts which exported the default one so it's nicely separated.
I think sending strings is the best option. Apps built on top could be clever if they want to add aliases but including it here may be overkill for this project and cause bloat that not many use?
From @LeviticusMB in https://github.com/Microsoft/vscode/issues/11314#issuecomment-274280543
Essentials: Arrow keys, backspace, d (delete current word), c (capitalize), l (lowercase), u (uppercase) but see https://en.wikipedia.org/wiki/GNU_Readline and http://www.aboutlinux.info/2005/08/bash-shell-shortcuts.html.
@Tyriar does Gnome3 have any particular bindings worth sharing, besides the ones listed in the comment above?
Not that I'm aware of
From @peabnuts123 in https://github.com/Microsoft/vscode/issues/11314#issuecomment-301634061
On OSX "Use Option as Meta Key" is a setting in the default Terminal app. All this does is change the functionality of Option to send the Meta key instead (as opposed to typing in special characters such as ∂, not very useful on a Terminal IMO). The Meta key is then used for whatever by whatever application you run within it. A List of Features that the Option key "should do" is not really the right solution for this. For example, when using
tmux, I haveMeta-Zbound as my prefix for commands; so to split a pane I first pressOption-Z (Meta-Z)and then\. This does not work in the VSCode integrated terminal, and no amount of feature documenting is going to fix that.I think that the change that is needed here is a similar option for the Integrated terminal on OSX to support the Meta key within the terminal. I realise this may be an issue with the underlying terminal library itself, however.
The more I've thought about this the more I think it should be handled at a higher level than xterm.js. Most embedders have some keybinding system that is far more featureful than what xterm.js would be able to offer (Hyper and VS Code for example), especially if we were trying to minimize bloat. As such I suggest we close this off and instruct embedders to handle this themselves, perhaps setting up a FAQ on the website too?
Hi @Tyriar -- could you please advice what changes are necessary for Mac OSX users to be able to just alt as a meta. Using the awesome _Hyper_ terminal, which of course is using this really cool underlying library.
Here is the corresponding bug on Hyper: zeit/hyper#2578. Any recommendations or hints on what config to change would be much appreciated.
@saamalik the "alt as meta feature" on macOS needs support added to xterm.js, then Hyper would get it when they upgrade. It will involve hooking up a new option here:
And then using the option where the escape sequences are built from keystrokes:
@Tyriar added. Let me know if you'd like me to make any changes! Also not sure if we're supposed to checkin package-lock?
@saamalik best leave package-lock.json out, I just added it in https://github.com/xtermjs/xterm.js/pull/1214 so I'm not sure why it has so many changes for you 😕
@Tyriar ok removed package-lock.json.
Closing this as out of scope. Embedders will generally have their own keybindings system which would be better that the small one we would want to do for this, it would be better to leave this up to them rather than include another one that just adds bloat.
Also is there a simple way to update the key mappings? Like we generally do in Xdefaults, a single json file which can take in configs and override them with default will be good.
I am new to xterm but I am looking for this specifically to overwrite F1-F24 keys. Any advice here?
@Tyriar
@krishnautpala we decided on letting you the user of xterm.js come up with your own system for handling keybindings since most terminals/ides would have their own system anyway. If you need to override the F keys, use this API to handle the keys manually and cancel them before they get to xterm.js by returning false in the handler:
Most helpful comment
From @peabnuts123 in https://github.com/Microsoft/vscode/issues/11314#issuecomment-301634061