Directory structure for plugins?

On the official keyboardio GitHub, I’m seeing two kinds of repository structures and scoping practices for plugins:

For instance MouseKeys has the source files directly under the src directory:


In these cases the actual plugin class declaration seems to be not under the Kaleidoscope namespace but ends in an underscore and instantiated at the global scope without the same.

OTOH for other plugins (originating from @algernon?) such as OneShot there is yet another subdirectory Kaleidoscope under the src directory which contains the actual sources, and directly under the src directory is a thin wrapper which merely #includes the actual header:


In most of these latter cases we see a commit with message The big rename or such. Also, the plugin class declaration is under the Kaleidoscope namespace without any trailing underscore, and instantiated at the global scope with the same name.

In both kinds of cases the name of the main header to be included is prefixed with Kaleidoscope-.

My question:

Is there a particular guideline (as yet apparently unimplemented in some cases) wrt file structure, namespace etc for core/thirdparty Kaleidoscope plugins?

There are number of things in play here, so let me share some context, which might help understand how we got where we are today.


In the beginning, there was only Kaleidoscope (then simply called KeyboardioFirmware), no plugins whatsoever in sight. It followed the Arduino conventions of shoving everything under src/, with global instances with classes of similar names (with an underscore appended). No namespacing or anything like it. That’s how big parts of Arduino were done, and the firmware inherited it.

When I first started playing with the firmware, the lack of extensibility prompted me to write my own firmware from scratch (without hardware at the time! how much of a fool I was…), but @jesse quickly persuaded me to abandon that road, and redo my work on top of KeyboardioFirmware. Some more details are available on my blog, but the gist of it is that I went down a different route, and used namespaces, because I disliked the ClassName_ thingy - it just made me uneasy. Because this all started out as a whole separate thing, I built them up with namespaces from day one, but used the name Animated Keyboard Extension Library for Arduino (or AKELA for short). The “Big Rename” happend when the libraries were transferred from my user on GitHub to the keyboardio organization, and when KeyboardioFirmware changed its name to Kaleidoscope. We did the renaming, but kept the directory structure, because there was no motivation at the time to make them similar. Keep in mind that at this point, MouseKeys, Macros, LEDControl and a few others were still part of Kaleidoscope itself, they were extracted out shortly after, and when extracting, the structure was kept, so that we didn’t introduce too many changes at the same time.

This is why the layout is different between plugins that originate from me, and those that don’t. It boils down to personal preference, there’s no real technical argument either way.

As for what new plugins should use… that’s a good question. We have not finalized that part of our coding style guide yet. It currently says that namespaces should be lowercase, and stuff in namespaces should be in similarly named directories. “My” plugin classes are in the kaleidoscope namespace, but due to historical reasons, the headers live under src/Kaleidoscope instead of src/kaleidoscope. We should change that at some point, but right now, it’s not a high priority.

However, and this is an important point: you absolutely must have a header in src/ with the same name as your plugin. This is a requirement imposed by Arduino. This is why there’s src/Kaleidoscope-OneShot.h, which simply includes Kaleidoscope/OneShot.h - to satisfy Arduino.

TL;DR: I’d suggest using namespaces, and kaleidoscope as the namespace, and src/kaleidoscope/ for the code itself, with src/Kaleidoscope-PLUGIN.h for Arduino. For naming, a Kaleidoscope- prefix is what others have used before to implement third party plugins. I don’t think we have an explicit recommendation (nor discouragement of doing so).


@algernon - Perhaps it’s worth us creating a ‘good’ sample plugin that follows all the conventions we agree on, which folks can fork and modify.