-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
[RFC] Fix function keys in embedded terminal #5014
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
Conversation
Can you combine the two PRs? Any other |
Sure thing! I imagine pretty much all the |
621ecf7
to
b30162b
Compare
@@ -793,6 +794,57 @@ static VTermKey convert_key(int key, VTermModifier *statep) | |||
case K_KMULTIPLY: return VTERM_KEY_KP_MULT; | |||
case K_KDIVIDE: return VTERM_KEY_KP_DIVIDE; | |||
|
|||
case K_S_F1: *statep |= VTERM_MOD_SHIFT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps all of these K_S_*
variants should be grouped in a separate switch before this one.
switch(key) {
case K_S_F2:
case K_S_F3:
case K_S_F4:
...
*statep |= VTERM_MOD_SHIFT;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and that switch should live in convert_modifiers()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about that, but if we took that approach, we'd still need to check all the K_S_*
keys individually in the big switch since the K_S_*
keys count as different keys from the K_*
ones.
If I understand your suggestion correctly, such a function would only let us go from
case K_S_F1: *statep |= VTERM_MOD_SHIFT;
case K_F1: return VTERM_KEY_FUNCTION(1);
to
case K_S_F1:
case K_F1: return VTERM_KEY_FUNCTION(1);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, but I think that's still preferable:
- the
*statep |= VTERM_MOD_SHIFT;
logic is a performed in a single place instead of repeated - modification of
statep
continues to be driven byconvert_modifiers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point. I'll make the change.
I'll look into it. Should be doable. Any key combination that vim can recognize should be able to be passed into the terminal fairly easily this way. |
ctrl-left/right seem pretty plug and play for this fix. ctrl+space might be a little trickier, but I think I can figure something out for it.
|
547c415
to
022a9d5
Compare
As of right now, the shifted function keys only work "in theory". It seems like nvim isn't able to recognize the codes for them consistently. If there are any platforms that nvim knows how to handle the shifted function keys on, or if someone were to implement that in nvim, the shifted function keys should just work. If you'd rather me take the shifted function key logic out, just let me know. |
@rjmill |
The logic looks fine to me. |
The problem with ctrl-space and ctrl+@ is that there doesn't seem to be a VTermKey enum value that corresponds to I've got some ideas on how to handle that, but they're all either dirty hacks or more significant/risky/clunky refactors that should probably get their own separate PR. It sounds like upstream changes aren't much of an option either. |
@leonerd can you say whether vterm has a ctrl-space key or some other way to send that key? |
022a9d5
to
3a3c3d9
Compare
Ctrl-space and ctrl-@ work now! Side note, ctrl-2 was also broken, but is now "fixed." Not sure why, but gnome-terminal and urxvt both interpret ctrl-2 the same as ctrl-space and ctrl-@ . So if anyone had been complaining about ctrl-2 outputting weird characters, that's taken care of now. |
Nice! Need to think about why that (much appreciated) hack is needed. We should add some test coverage to this PR (could just plop it in a new |
It's because there's already an ASCII representation for the character (0), but vim converts it to its own code, just like it does for all the other special keys. But since it's ASCII, vterm(quite sensibly) doesn't have a special enum for it. Hence why it needs to be handled differently. |
It might be feasible to convert it to ASCII earlier in the key handling process in keymap.c, but I imagine it will break some stuff, given that |
Sure, but I wondered why ASCII 0 was special, and ctrl-a (ASCII 1) is not. In
|
It looks like this block in It's less readable, for little gain I suppose. Though it could fill in whatever remaining modifier+special keys we're missing support for. |
I've got your suggestion mostly working, but there are still edge cases that aren't handled properly (including For what it's worth, if we go with the switch statements, any special keys/combinations we miss will be pretty trivial to tack on as we find them. Whereas if we miss stuff with the cleaner solution, it will most likely be an ordeal to support any keys we miss. I'll keep searching for a clean solution, if only to satisfy my curiosity, but I think there's a good chance that any practical solution to this is going to involve some kind of hack for the edge cases. |
ASCII 0 is not in the table, so yes it will be a special case. But anything else that's not in the table is just not supported by Vim 's input model which maps these keys to single integers. Right? Anything else that comes through would not be mapped to a |
Note: also see if shift+tab can be handled. |
This fix will handle shift+tab. (Shift+tab is actually what originally brought this issue to my attention, haha.) I'll try to get this wrapped up over the next week. |
Great! |
3a3c3d9
to
9dec8ba
Compare
After dusting this PR off, it looks like special keys are working as expecting in the terminal with the current implementation by putting it all into the big switch statement. I have a local branch where I implemented your suggestion to extract the block in It looks like I left off trying to get the branch with the extracted function to the same point of functionality as the branch with the switch statement. It seems that it mostly just doesn't handle ASCII 0. I remember having concerns that there might be other edge cases besides ASCII 0, but I don't remember why, nor do I see why there would be other edge cases besides ASCII 0. As long as those concerns don't turn out to be valid, I should be able to merge those changes into this PR tonight. |
c = Ctrl_AT; | ||
} | ||
|
||
c = unmodify_key(c, &mod_mask); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is modifying the global mod_mask
, is that what we want?
@justinmk I think we were planning on reusing that block of code to help ensure that we didn't miss any special keys with the switch statement. I agree that we should put the I'll go ahead and roll this back to the commit before the |
61874e8
to
ca716f3
Compare
ca716f3
to
27a1e8f
Compare
27a1e8f
to
a1d545f
Compare
@justinmk What else do I need to do to wrap up this PR? |
Some tests would be nice, but it's probably too complicated. I've added this to 0.2 milestone so it will get a look soonish. |
Thanks! I'd be happy to write some tests, but I'm not really sure where to start testing something like this. Is it something I can just figure out by poking around in the test suite? |
I've recently made extensive use of the embedded terminal. |
closes neovim#3101 closes neovim#4343 closes neovim#5024 closes neovim#5925
fix #4343
F5-F12 seem to be working perfectly. F1-F4 work as expected in htop and bash, but output extra characters in zsh.