Custom Keyboard Layout for Coding: How to Set It Up on Linux (Ubuntu)

Custom Keyboard Layout for Coding: How to Set It Up on Linux (Ubuntu)

Keyboard Layouts are not particularly great for coding by default. Special characters need shift to be pressed or are not easily reachable. This is especially true on non-english (like german) layouts. The brackets, for example, are very pleasantly placed on the 4th row (counting from the bottom) of an EN-keyboard layout, but you need to press AltGr + 8 or 9 on an DE-keyboard layout. Not so great. See here how set-up a custom keyboard on Linux (Ubuntu).

The bad news: the best way I found, is to work on the X11/xkb files directly. Other variants (.Xkeymap, .Xmodmap) have huge drawbacks for me. So this seems to be the right way.

The good news: this methods adds a new region layout to your pc, to which you can easily switch, copy and store without worrying too much about messing up other layouts or system files.

Let's start, step by step:

  1. Open terminal
  2. Go to /usr/share/X11/xkb/symbols
  3. Choose a preferred base file, like de (for the german keyboard layouts, two letter country code)
  4. Copy the file: sudo cp de co (please remember the new name, co in my case, as it needs to be referenced in evdex.xml later)
  5. Edit the file: sudo gedit co
  6. Edit the name section and give the layout a unique name: name[Group1]="Coding";
  7. I started by deleting everything but the basic portion of the de layout
  8. Copy parts from other layouts you may want to use or write your own layouts. Mine is a mixture of german, english and custom keys. You may copy my layout below and modify as you need.
  9. Now add the new keyboard layout to /usr/share/X11/xkb/symbols/evdev.xml in order for X11 to recognize it
    1. Therefore open the file: sudo gedit /usr/share/X11/xkb/rules/evdev.xml
    2. Scroll down, until you find the end of the layoutList, marked by </layoutList>
    3. Insert the layout as the last XML element of layoutList (see code below)
    4. For <name></name>, use the same string as for the filename itself (co in my case)
  10. You may have to restart X once. Restart your PC or type sudo systemctl restart display-manager (warning: closes everything!)
  11. Now go to your Systems Settings > Region & Language then Click the + and under ... you should find the new Input Source named Coding
  12. You might want to fiddle a bit with it, so run setxkbmap -layout co to reload changes

General tips:

  • key names are no mystery
  • the second letter stands for the row on your keyboard, counting bottom to top (AA = first row, AC = third row)
  • the number stands for the position of the key from the left (AE01 = first key of the 5th row = "1")
  • special keys have specials names, like TLDE, for, you guessed, the tilde key
  • include load other layouts
    • for a general layout you want to keep the latin(type4) include
    • for AltGr combinations to work want to keep the level3(ralt_switch) include




// based on a keyboard map from an 'xkb/symbols/de' file

xkb_symbols "basic" {

    include "latin(type4)"


    key <AE01> {	[	  exclam,	1,	exclam 	]	};
    key <AE02> {	[	  at,		2,	at		]	};
    key <AE03> {	[	  numbersign,	3,	numbersign	]	};
    key <AE04> {	[	  dollar,	4,	dollar		]	};
    key <AE05> {	[	  percent,	5,	percent	]	};
    key <AE06> {	[	  ampersand,	6,	asciicircum	]	};
    key <AE07> {	[	  grave,	7,	ampersand	]	};
    key <AE08> {	[	  parenleft,	8,	asterisk	]	};
    key <AE09> {	[	  parenright,	9,	parenleft	]	};
    key <AE10> {	[	  asterisk,	0,	parenright	]	};

    key <AD11>	{ [bracketleft, braceleft, udiaeresis, Udiaeresis ] };
    key <AD12>	{ [bracketright, braceright, asciitilde, U010C ] };
    key <AC10>	{ [semicolon,	colon, odiaeresis, Odiaeresis ] };
    key <AC11>	{ [apostrophe,	quotedbl, adiaeresis, Adiaeresis ] };
    key <AB08> {	[     comma,	less		]	};
    key <AB09> {	[    period,	greater		]	};
    key <AB10> {	[     slash,	question	]	};
    key <AD03>	{ [         e,          E,	EuroSign,     EuroSign ]	};
    key <AD06>	{ [         z,          Z,	leftarrow,          yen ]	};
    key <AC02>  { [         s,          S,	ssharp,     U1E9E    ] };
    key <AB01>	{ [         y,          Y,	guillemotright,    U203A 	] };
    key <AB02>	{ [         x,          X,	guillemotleft,    U2039 	] };
    key <AB04>	{ [         v,          V,	doublelowquotemark, singlelowquotemark ]	};
    key <AB05>	{ [         b,          B,	leftdoublequotemark, leftsinglequotemark ] };
    key <AB06>	{ [         n,          N,	rightdoublequotemark, rightsinglequotemark ]	};
    key <TLDE>	{ [asciicircum, asciitilde, degree,	U2032	] };

    include "kpdl(comma)"
    include "level3(ralt_switch)"