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

The problem with self-input non-alphabetic keys in non-latin keyboard layouts #54

Open
sanarise opened this issue Dec 24, 2024 · 16 comments
Assignees

Comments

@sanarise
Copy link

Hi!
There is such a problem when using national keyboard layouts.
If there is a letter key is in the Latin keyboard layout, then everything is fine – then it works in another (national) layout too. But if this key is not alphabetic (for example, ";" "[" ), and in the national layout it produces a national symbol, then we get a self-input of this national symbol even in normal modal mode. Reproduces in Russian, Finnish, Greek etc. layouts with ";" key, for example.
Is it possible to fix it? Thanks!

@haberdashPI
Copy link
Owner

Hi @sanarise, thanks for taking the time to look at the extension and providing feedback!

I don't have any experience with international keyboard layouts, or writing software to support it. I have it on the roadmap for the project to learn more about this and make the necessary fixes to support other layouts, but I have been focusing my limited time for the project on improving code coverage, addressing any bug fixes that get identified along the way, and improving legibility of the code base. Knowing that there are folks with international layouts interested in using the extension would substantially raise the priority of that effort.

Are your problems limited to a small number number of keys, or are there many problems? It is already possible to modify the default keybindings as you see fit, so if it is just a small number of keys at issue, this should not be to hard to fix. Note that VSCode keybindings can be specified using layout independent bindings, so it may be possible to simply surround the appropriate keys in a bindings with []. But I don't really know if that would be the correct solution without understanding what keys are different in a given layout.

Note that the visual documentation will also ultimately need to be updated to support other keyboard layouts. Right now it assumes a fixed layout.

@sanarise
Copy link
Author

Are your problems limited to a small number number of keys, or are there many problems? It is already possible to modify the default keybindings as you see fit, so if it is just a small number of keys at issue, this should not be to hard to fix. Note that VSCode keybindings can be specified using layout independent bindings, so it may be possible to simply surround the appropriate keys in a bindings with []. But I don't really know if that would be the correct solution without understanding what keys are different in a given layout.

Yes, it seems that this is what we need! The symbols on which this problem is reproduced are exactly the symbols listed in the documentation at the link.

Note that the visual documentation will also ultimately need to be updated to support other keyboard layouts. Right now it assumes a fixed layout.

I'm not sure. Other layouts are needed only for the national text input in the insert mode. They do not appear in any way in the declaration of modal modes. The usual and annoying problem is that if a user inputs text in their national language, and then goes back into normal modal mode and tries to execute some command, then nothing works for them until they switch back to the English layout. This problem exists, for example, in vim and it is solved with various crutches rather crookedly. In vscode, given the link you gave me, developers thought about it, and in fact, when using these mnemonics, the problem is solved.

@sanarise
Copy link
Author

sanarise commented Dec 29, 2024

The only thing that remains a mystery to me is why the letter keys a-z work by default? I.e. there is no problem with them and there is no need to write "[KeyA]" instead of "a". Is it possible that one is being mapped to another somewhere?

@haberdashPI
Copy link
Owner

haberdashPI commented Dec 30, 2024

The only thing that remains a mystery to me is why the letter keys a-z work by default? I.e. there is no problem with them and there is no need to write "[KeyA]" instead of "a".

Can you clarify what you mean by "work by default"? I don't really understand what differences there are across various keyboard layouts. I think I used a german layout once when I was traveling in Europe, and vaguely remember that one or two alphabetic keys were swapped around (e and z maybe???). Are you saying that in normal mode the swapped keys are located in the US layout instead?

Possibly relevant point: some keys are ignored during normal model, and that is done by regex. (but must match the entire word)

[[bind]]
path = "edit.action.symmetric"
foreach.key = ["{key: [a-z]}", "shift+{key: [a-z]}"]
name = ""
description = "this key is ignored and has no associated command in syminsert mode"
key = "{key}"
command = "master-key.ignore"
mode = "syminsert"

@haberdashPI
Copy link
Owner

Other layouts are needed only for the national text input in the insert mode. They do not appear in any way in the declaration of modal modes.

That's helpful to understand, thank you. That sounds like a good approach for this extension as well, if that is something that works well for other layouts.

@haberdashPI
Copy link
Owner

haberdashPI commented Dec 30, 2024

The symbols on which this problem is reproduced are exactly the symbols listed in the documentation at the link.

So if I understand your point, the way to fix this problem in larkin.toml is to find any instances of a keybinding that uses a non-alphanumeric key and replace it with the layout agnostic versions (surrounded in []), and to make sure that there are default ignore bindings for these as well. Is that accurate?

@sanarise
Copy link
Author

sanarise commented Jan 2, 2025

https://disk.yandex.com/i/q9J0g02R0pe5Hw

I recorded a screencast where I use Russian and English layouts and several right-hand keys to demonstrate the behavior (arrows "jklh", square brackets, undo key "u" and semicolon ";").
Larkin preset is also used without any modifications.
Please note the following points:

  1. The cancel key works in both the Russian and English "default" layouts. That is, you do not need to use "[KeyU]" instead of "u" to operate it. The same applies to the arrow keys. And I do not know why this is so...
  2. Square brackets are ignored in normal mode, but the Russian characters on these keys are self-inserted.
  3. The key works only in the English layout, in the Russian it makes the self-insert of the national symbol.

To correct the 2nd and 3rd points, its need to use the appropriate mnemonics "[...]" in the command rules and in the ignore rule.

@sanarise
Copy link
Author

sanarise commented Jan 2, 2025

In fact, now in order for me to completely close this problem, I need to use the ignore rule with a complete list of "[...]"-keys.
And in the description of the commands, too, it is probably worth using only them. Even though the a-z keys work without specifying the corresponding "[Key...]" mnemonics, but for consistency it would probably be better to use them anyway.

@sanarise
Copy link
Author

sanarise commented Jan 2, 2025

A part of my ignore rule now:

[[bind]]
foreach.key = [
    '[Digit{key: [0-9]}]',
    'shift+[Digit{key: [0-9]}]',
    '[Key{key: [a-z]}]',
    'shift+[Key{key: [a-z]}]',
    '[Backquote]',
    'shift+[Backquote]',
    '[Minus]',
    'shift+[Minus]',
    '[Equal]',
    'shift+[Equal]',
    '[BracketLeft]',
    'shift+[BracketLeft]',
    '[BracketRight]',
    'shift+[BracketRight]',
    '[Backslash]',
    'shift+[Backslash]',
    '[Semicolon]',
    'shift+[Semicolon]',
    '[Quote]',
    'shift+[Quote]',
    '[Comma]',
    'shift+[Comma]',
    '[Period]',
    'shift+[Period]',
    '[Slash]',
    'shift+[Slash]',
    '[Tab]',
    'shift+[Tab]',
    '[Enter]',
    'shift+[Enter]',
    '[Space]',
    'shift+[Space]',
    '[Backspace]',
    'shift+[Backspace]',
    '[Delete]',
    'shift+[Delete]',
]
key = "{key}"
command = "master-key.ignore"

@sanarise
Copy link
Author

sanarise commented Jan 2, 2025

And there is another minor problem. Bindings that use "[...] "mnemonics are not displayed in the Masterkey Bindings Panel )

@haberdashPI
Copy link
Owner

haberdashPI commented Jan 3, 2025

Awesome, thanks for investigating this further @sanarise. Let me try to delineate the steps to resolve the issues you're seeing as I see them now. Feel free to amend or suggest further improvements.

  1. Replace all uses of keys in Larkin with the layout independent versions
  2. Nice to have: make sure it is easy to ignore all these layout independent versions via foreach. I think this might already be possible by using foreach.key = ['{key: \[[A-Za-z0-9]+\]}', 'shift+{key: \[[A-Za-z0-9]+\]}'], but I need to verify that it is working (and fix it if it isn't).
  3. Handle display of layout independent bindings in the Masterkey Bindings Panel — by this I assume you mean the visual documentation?
  4. Verify that the layout independent bindings display properly in the quick pick view — fix them if they aren't working

Question about 3: what do you think the best approach is for the letters shown in this visual documentation when using another layout? The US keyboard? Or the current layout? I believe there is a way to get access to the current keyboard layout via WebAPI, I just haven't investigated this sufficiently to figure out what it would involve (and whether there would be any roadblocks).

@sanarise
Copy link
Author

sanarise commented Jan 3, 2025

  1. Replace all uses of keys in Larkin with the layout independent versions

Yes, I think it's the right thing to do.

  1. Nice to have: make sure it is easy to ignore all these layout independent versions via foreach. I think this might already be possible by using foreach.key = ['{key: \[[A-Za-z0-9]+\]}', 'shift+{key: \[[A-Za-z0-9]+\]}'], but I need to verify that it is working (and fix it if it isn't).

Yes, we need to check this, but as I see it, it doesn't work for national layouts. So I used:

foreach.key = [
    '[Digit{key: [0-9]}]',
    'shift+[Digit{key: [0-9]}]',
    '[Key{key: [a-z]}]',
    'shift+[Key{key: [a-z]}]',
    ...
  1. Handle display of layout independent bindings in the Masterkey Bindings Panel — by this I assume you mean the visual documentation?

Yes, the same panel where the keyboard with multi-colored keys is displayed )

  1. Verify that the layout independent bindings display properly in the quick pick view — fix them if they aren't working

Question about 3: what do you think the best approach is for the letters shown in this visual documentation when using another layout? The US keyboard? Or the current layout? I believe there is a way to get access to the current keyboard layout via WebAPI, I just haven't investigated this sufficiently to figure out what it would involve (and whether there would be any roadblocks).

No, I think that only the US keyboard should be shown in this panel.
The idea is that there are no national layouts for us in modal modes. But it's very inconvenient to constantly switch US<->RU when editing a Russian-language document.
And therefore, it is desirable that with the current RU layout at the system level, in vscode modal modes, everything continues to work as if we were in the US layout.
In fact, layout independent bindings perfectly solve this problem. Everything is working fine for me at the moment. This is much better than tons of hacks + different system applications that control the system layout depending on different conditions to make it work in vim and emacs. All this works at least, but sometimes it glitches.))
For emacs, for example, to make it work, I had to use the Switch Key.app (which has not been supported for a long time and therefore does not work smoothly in recent macos's) + custom rule for Karabiner-Elements.
Therefore, I am very glad that in this case all this is solved in one place.

@haberdashPI
Copy link
Owner

conditions to make it work in vim and emacs. All this works at least, but sometimes it glitches.))
For emacs, for example, to make it work, I had to use the Switch Key.app (which has not been supported for a long time and therefore does not work smoothly in recent macos's) + custom rule for Karabiner-Elements.
Therefore, I am very glad that in this case all this is solved in one place.

Wow! What a pain. That sounds unpleasant.

Thanks so much for teaching me more about this. I'm going to put fixing the remaining issues at the top of my list of TODOs for this project.

Note to self: I think it is worth adding an explicit callout in the README that I'm happy to fix well scoped problems for actual users before wrapping up the 0.3 milestones.

@haberdashPI haberdashPI self-assigned this Jan 4, 2025
@haberdashPI
Copy link
Owner

@sanarise: could you send me the modified version of Larkin you have already setup using the layout independent bindings? Seems like a good place to start in cleaning up the remaining issues.

@sanarise
Copy link
Author

sanarise commented Jan 5, 2025

@sanarise: could you send me the modified version of Larkin you have already setup using the layout independent bindings?

The thing is, I don't use Larkin preset as such. I'm building my own super-duper ) preset almost from scratch. It is still far from complete and in many ways similar to vim, but with some special features. In my screencast, I used Larkin only so as not to confuse you with the specifics of my preset.
Now, in fact, I have only made the ignore rule that I posted above and changed a few bindings where the problem was very annoying. I did not modify the letter keys, because then the keyboard hint panel will become completely empty. This can be done after adding layout independent bindings support at the level of this panel.

@sanarise
Copy link
Author

sanarise commented Jan 5, 2025

By the way, I have another small feature request that is not directly related to the topic under discussion. If you find it necessary, then you will probably have a separate task. )

I would like to be able to change the cursor for a specific prefix (command = "master-key.prefix")
I sometimes want to have a visual response to prefix activation, but so far there is no such possibility, as I understand it. Or am I wrong?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants