Efficient Multi Language Typing on Linux

January 15, 2018

I would like to be able to type Turkish and German characters on my US English keyboard as fast as possible, with minimum key strokes. Here is a solution.

I have a standard US keyboard with 104 keys, Das Keyboard Professional 4, that is with 2 Alt keys, no AltGr key, 2 logo keys and 1 menu key. The main reason I use a US layout is that I think the default keyboard shortcuts of many applications are optimized for it and I find the keys used in programming languages are more easily accessible. However, sometimes, you need to be able to type the characters of other languages, other than English, especially if you are not a native English speaker and/or living abroad. So having the English layout keyboard, I would like to be able to type characters both in Turkish and (Swiss) German, with minimum effort.

Turkish has the following non US-ASCII characters:

c-cedilla: ç Ç
g with breve: ğ Ğ
dotless i: ı
I with dot above: İ
o with diaeresis: ö Ö
s-cedilla: ş Ş
u with diaeresis: ü Ü

German has the following non US-ASCII characters:

a umlaut: ä Ä
o umlaut: same as o with diaeresis in Turkish, ö Ö
u umlaut: same as u with diaeresis in Turkish, ü Ü
sharp S: ß ẞ

Turkish Keyboard Layout

Turkish Keyboard Layout

German Keyboard Layout

German Keyboard Layout

Swiss Keyboard Layout. Note that Switzerland has four (de, fr, it, rm) national languages, that is why it includes some French characters. No additional characters are needed for Italian and Romansh. Also, ß (sharp S) is not used in Switzerland.

Swiss Keyboard Layout. Note that Switzerland has four (de, fr, it, rm) national languages, that is why it includes some French characters. No additional characters are needed for Italian and Romansh. Also, ß (sharp S) is not used in Switzerland.

The simplest and probably the most common way to solve this is to switch the keyboard layout when needed, but I have two problems with that. Since the key labels does not match, it is error prone, and more importantly, I find it hard and time consuming to switch between the keyboard layouts especially if you would like to use both the default layout and the characters in the other language simultaneously. It is even more difficult with more than two languages. Basically, you cannot fully utilize the muscle memory you have for the main layout with the other layouts.

One solution to this is to use Compose or Multi Key feature, which is actually a great way to type characters you rarely need. For example, you just press Compose key (which you need to assign to any key or a key combination), then then a , and it prints ä. I assigned menu key as my Compose key, so Menu + " + a = ä. This is great but if you type these characters a lot, it is still lots of key strokes, especially because you need to release the each individual key to use this feature. So there are three key press and key release actions needed for ä.

The fastest way should be just to assign whatever characters you need to some simple combinations. For example, you may have an AltGr key in your keyboard, and its purpose is actually to be able to type different symbols, e.g. at sign @ is usually typed using AltGr and another key like Q.

So how can we do the same for the Turkish and German characters above ? Probably there are a few ways to achieve this but I use xmodmap. Using the following xmodmap expressions in a file:

$ cat ~/.xmodmaprc

keycode 108 = Mode_switch
keycode  30 = u U udiaeresis Udiaeresis
keycode  31 = i I idotless Iabovedot
keycode  32 = o O odiaeresis Odiaeresis
keycode  38 = a A adiaeresis Adiaeresis
keycode  39 = s S scedilla Scedilla
keycode  42 = g G gbreve Gbreve
keycode  54 = c C ccedilla Ccedilla
keycode  56 = b B ssharp U1E9E

and running it with:

xmodmap ~/.xmodmaprc

You can read the man page of xmodmap but basically these expressions assign keycodes (basically the keys on the physical keyboard) to key symbols (basically the characters you want to type). The syntax is (I use ks for key symbol):

keycode <number> = ks shift_ks mode_switch_ks shift_mode_switch_ks

shift_ks means when the key is pressed with Shift modifier and mode_switch means when the key is pressed with Mode_switch modifier.

You can assign Mode_switch modifier to any key, and here I assigned it to right Alt (Alt_R) key (keycode 108) in the first line of the file.

So now, pressing Alt_R and a at the same time immediately gives me ä. So comparing this to switching between the layouts, or press and release 3 different keys with Compose, it is very simple and fast.

Note that, keycode 108 may not work for you. You can print the current keymap table with xmodmap -pke and use xev to see the keycodes for your keyboard. For example:

$ xmodmap -pke | grep Mode_switch

keycode 108 = Mode_switch NoSymbol Mode_switch

Also, as you see above, for the capital of sharp s ẞ (Shift + Mode_switch + keycode 56), I used the Unicode number rather than the symbol name. This is because this Unicode symbol does not have a key symbol name in Linux yet (no definition in /usr/include/X11/keysymdef.h).

This method can be adapted to many other languages as long as there is not much overlap for a single key, e.g. it is problematic when you have both é and è, then probably you need to assign these to non letter keys which is, I think, not very elegant.