Mapping International Characters

How do I add characters like æøå/ÆØÅ and the euro sign to my keyboard layout?

I’d like to keep the US layout and hit those with fn and fn + shift combinations.

There may be easier ways of doing this, but I’m using macros that use the Unicode plugin to write special characters:


@algernon is the domain expert here. and

may get you started.

If you’re willing and able, it’d be super helpful if you can share what you learn here or on the wiki, so we can turn it into a proper tutorial.


The quick summary of things is this: if your keyboard is set to US-QWERTY, you will need some kind of OS-side assistance to input international characters. This can be a Compose key (as used in LangPack-Hungarian linked above), or you can use the Unicode plugin, also mentioned above. Both will need a bit of tweaking on the OS side, to enable either the Compose key, or Unicode input. But all major operating systems support both of these, it is up to you which one you prefer.

1 Like

Wow. I never heard about the compose key before! So damn cool!

However it is not implemented on windows out of the box, so that makes it a bad option for me, since I work as a consultant and can often not install software on my pc.

The unicode plugin seems to be a little easier and I think it will work out of the box on windows and linux. On mac it requires changing the Keyboard Input Source to unicode input.

In some distant future it would be cool, if the compose key could be built into the firmware - on top of the unicode plugin :slight_smile:

Anyways - I am going to try my luck with the unicode plugin.
I will be back with how it goes - but it might take a few days before I have the time for it.


The alternative is to use a modified firmware keymap where the three missing scancodes are available in the base layer and use your normal OS language keymap.


I have not found this to be true for macOS. I spent a while trying to get one to work, and it was a miserable failure. I had been hoping to have to keyboard do it, but the tiny amount of memory it has made that impossible, too.

For macOS, I think you need to switch the layout to Unicode Hex input.
You’ll also need to either have HostOS checking active or explicitly set the OS in the Arduino sketch.
I have it working on Linux, but haven’t tested yet on OS X/macOS (don’t have the HostOS guessing turned on); I will try to test that later today or tomorrow.


I don’t remember all the contortions I went through to get a compose key on macOS, but I tried multiple methods that other people had published, none of which worked acceptably well.

The big problem is that Apple has their own (Cocoa) input system for international characters, but it only works in applications built with it, so it (if I recall) doesn’t work in Emacs, and neither did the compose key hack. Getting it to work everywhere is basically impossible, or so much work that it’s pointless to try, though I might give some newer approach a chance anyway, I’m not at all hopeful that it will work in both Cocoa and non-Cocoa apps. (And I find the Cocoa system for international unicode characters to be both much more limited and awkward than a compose key, so I end up mostly not using them, even when I really want to.)

So I tried working with configuring the unicode plugin.

I mapped fn+o to give me unicode(00e5) which should be å.
I also configured my keyboard input source to be unicode in MacOS.

Pressing the key gives makes the keyboard type “00e5”, so something is wrong.
I also tried in on windows 10 with the same result.

Here are the changes I made to get the unicode plugin configured:

// import plugins
#include "Kaleidoscope-HostOS.h"
#include "Kaleidoscope/HostOS-select.h"
#include "Kaleidoscope-Unicode.h"

// add a alias for the macro
enum { 

 // define macro
 static void unicode(uint32_t codepoint, uint8_t keyState) {
  if (!keyToggledOn(keyState)) {

const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {
  switch (macroIndex) {

  case L_AA:
    unicode(0x00e5, keyState);
  return MACRO_NONE;

// add to use
  // other plugins here
  // Unicode input

And then add M(L_AA) to keyboard mapping.

But like I wrote it doesn’t work as expected, so something is wrong …

To make things worse I also managed to close the terminal window I was working in and now I can’t get the keyboard to accept my make flash commands …
Is it an environment variable / path thing or did I manage to brick my keyboard?

luke:Model01-Firmware lasse$ make flash
ls: /Users/lasse/Library/Arduino15/packages/keyboardio/hardware/avr/*: No such file or directory
BOARD_HARDWARE_PATH="/Users/lasse/Documents/Arduino/hardware" /Users/lasse/Documents/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope/bin//kaleidoscope-builder flash
Building output/Model01-Firmware/Model01-Firmware (0.0.0-gv1.13-57-ge6f5-dirty) ...
Press ENTER when ready...

stty: 1200: No such file or directory
make: *** [flash] Error 1
luke:Model01-Firmware lasse$

That actually sounds like the best approach to me. I keep an old standard keyboard around with physical danish layout. And if I could keep the OS layout as danish as well, that would allow a co-worker to pair program with me, with her using a standard keyboard and me showing off on my model01 :slight_smile:

Can you provide some more details on how to go about that?
Also to consider: If I change my layout to danish brackets go to the AltGr layer. How can I map them? (See also my other thread about a custom brackets key)

By default the HostOS plugin does no OS autodetection, so you either have to set that up (by adding a #define KALEIDOSCOPE_HOSTOS_GUESSER 1 to the top of your sketch, before the includes), or tell it your OS: HostOS.os(kaleidoscope::hostos::OSX) somewhere in your setup() method.

For the flashing issue, perhaps re-plugging the keyboard would help?

1 Like

The error flashing looks like it’s an environment variable issue…It looks like it’s got ARDUINO_PATH set to ~/Library/Arduino15 instead of ~/Documents/Arduino maybe? I’ve been using the Arduino IDE instead of make flash thought, so I’m not sure.

I have a fork here: . The particular file you’re interested in is layer-abg-multilingual.h . Note that the aliases assume a us-QWERTY layout so won’t exactly match the key codes generated under your danish OS keymap - but the overall result (which is the important bit) should turn out as you would expect.

I mapped the right alt key (=altgr) to the right thumb cluster so that one can use it like a 3rd level shift key. Just press the same key combination that you normally would on a danish layout (altgr+7890).

Have a look at for a full description of the changes.

I tried:

  • Plugging in and out multiple times
  • Rebooting
  • Changing USB ports
  • cloning a fresh copy of Model01-Firmware to make sure I didn’t change anything in by mistake

What does the last part of the message mean:

stty: 1200: No such file or directory
make: *** [flash] Error 1

That means that its autodetect logic failed, and couldn’t find a port, so it is treating the next argument (the baud rate) as if it was the serial device.

The auto-detection logic there is fragile, and the error messages are awful. Entirely my fault, for writing the script in shell, and failing to do any kind of error detection and handling.

Ah, I just reread this and I think I know what you mean now. If you want the magic keys in the FN layer to map to Danish bracket keys instead of the QWERTY bracket keys you’ll need to set up four (not two!) new macros taking the Key_*CurlyBracket macros as inspiration, but a) instead of using Key_LeftShift as the modifier key, use Key_RightAlt and b) use 7890 as the target keys rather than [].

Thanks you for taking the time to trying to understand my ramling :wink:
It might be easier to understand if you have a look at a classic danish pc105 layout:

So as you can see programming brackets go to AltGr + 7,8,9,0

What should I write in the keyboard layer to address that?

Anything I can try to get more info?
Would it help if I found a linux box or do a hard reset or something else??

Yes, I looked that up to see where the brackets were on Danish. AltGr is the Butterfly key on the stock firmware, so it should Just Work. Set your OS keymap to Danish and nothing more needs done - you have brackets.

Where you will find problems with the stock firmware is finding the Ũ^’* keys from the top right and the <> key in the bottom left - these are the us-QWERTY []\ keys and they don’t exist on the base layer. The first three and their magically-shifted counterparts are found on the Fn layer (they’re the ones labelled “[]{}\|” ), but the <> key does not exist anywhere at all.

Which is where the multilingual layout in my fork comes in - I move PgUp, PgDn and Num to the Fn layer and trash the Any key, giving four spare keys that can be used for these four “missing” keys. And because they’re on the base layer, you don’t need to use the magic-shifted keys.

1 Like