Repository: neovim
Issue: Improve 'langmap', non-English keyboards
Labels: ux

Hello, NeoVim team

I am a Vim user with a non-English keyboard layout and I wonder if it would be possible to fix things in NeoVim. Is this even possible? I don't know if a terminal is able to register `ctrl` + `key` as two different keys, or if they get lumped into one control character. I know that at least my OS can do that: in Safari on OS X if I hold down the `ctrl` key the status bar says "Display a menu", because on OS X left-clicking while holding ctrl is like right-clicking.

If NeoVim could do that it would be a killer feature at least for me as a non-English user. I know C (see my GitHub repositories), but I have never worked on big projects, so I have no idea where to start. If this issue is feasible and someone were to tackle it I would gladly contribute as best as I can.
## Motivation

The default keyboard commands in Vim are easy to remember and easy to type when
your only language is English. Keystrokes like `daw` intuitively expand to
_delete around word_ in the user's mind and are simple enough to type quickly.

However, when using a non-English keyboard layout Vim becomes unusable. Even if
the language in question is using the Latin alphabet non-letter keys will be
awkward to reach. For instance, the `:` key will be below the `l` key on a
German keyboard, making such an important key very uncomfortable to reach. If
the keyboard is using a different alphabet, such as Cyrillic, even the most
basic tasks become impossible. I am not talking about hypothetical scenarios,
These are the issues I face every day.
## Possible solution in Vim - first attempt

Vim offers the `langmap` feature: every character gets mapped to a corresponding
other character:

```
:set langmap=ü[,+],ö\\;,ä',#\\\
```

This will map the lower-case home row to act like the home row on an English
keyboard. This is similar to the tip about using a Dvorak keyboard with default
Vim commands:

http://vim.wikia.com/wiki/Using_Vim_with_the_Dvorak_keyboard_layout

Just as described in the link, this method has problems: for instance using the
mapped keys is impossible in multi-key mappings:

```
noremap <C-[> a
```

This will work fine with the physical `[` key (alt + 5 on German Mac keyboards),
but not with the `ü` key which has be mapped to act like the `[` key. This is
not just a problem with umlauts, but with any character. Assume we wanted to
swap the function of `:` and `;`:

```
noremap : ;
noremap ; :
```

This will again work with the physical keys, but not with the mapped ones. This
is an inconvenience on Latin keyboards, but utterly crippling on a Cyrillic one.
## Possible solution in Vim - second attempt

Langmap is an elegant feature, but not suitable for the job. Let's get more
low-level by explicitly remapping keys:

```
noremap ü [
noremap + ]
noremap ö ;
noremap ä '
noremap # \
```

This has the exact same limitations as the above attempt.
## Possible solution in Vim - third attempt

Looking at the two above a common theme can be seen: we map some character to
another character and then map that to something else. So how about condensing
these mapping into one? For example, swapping the `:` and `;` keys becomes:

```
noremap ö :
noremap Ö ;
```

This works great for single keys and ASCII key-combos. It does not work for key
combos with non-ASCII characters:

```
noremap <C-Ü> <C-[>
```

Pressing `ctrl` + `ü` won't do anything. Furthermore, one has to do this for
every single keyboard layout. Instead of mapping every layout to English as a
common base and then mapping those keys to my liking I have to condense mappings
manually every time.
## Possible solution in Vim - fourth attempt

If the problem cannot be fixed at Vim level it has to be fixed at OS level:
change the keyboard layout for the OS. This works perfectly, but requires
switching keyboard layouts all the time. We can map English characters to
non-English targets in insert mode, but even then the user still has to switch
keyboard layouts when entering Vim and when leaving Vim. This could maybe be
automated at the OS-level but it's still an ugly hack around a problem that's in
Vim.
## Analysis of the solutions

My goal is to have a sort of neutral keyboard layout which can then be further
customised to my liking. This keyboard layout is the English one, since that's
what Vim was created for. Every other layout gets mapped to English before
further mapping.  Here is a sketch:

```
German:   ö -> ; -> :
Cyrillic: ч -> ; -> :
```

Both the keys `ö` and `ч` get mapped to a common base, the English key `;`.
Therefore language mappings need to take precedence over other mappings. This
needs to work implicitly with key combos as well:

```
ü -> [  ===>  <C-Ü> -> <C-[>
```

The user should not have to specify the second mapping, it should be implied by
the first one. Using `map` instead of `noremap` is not an option either if I
want to swap keys:

```
map ; :
map : ;
```

This will just run in circles. Recursive mapping can also interfere with
mappings used in plugins.
## Conclusion

Using keys quickly enters muscle memory and it would make sense to perform the
same actions with the same finger motions. Manipulating lines of text is the
same regardless of the language the text was written in, even if the text is
some pseudo-Latin _Lorem ipsum_. To prevent redundancy the keys pressed by the
user are first mapped to their English equivalents and then the English keys are
mapped according to the user's settings. That way the process of manipulating an
English, German or Cyrillic text is the same, and only the process of typing it
is language-dependent.