Merge pull request #389 from keyboardio/f/monorepo-stage2

Pull in the rest of the plugins
pull/426/head
Jesse Vincent 6 years ago committed by GitHub
commit 76da3dc006
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,69 @@
# Kaleidoscope-Colormap
The `Colormap` extension provides an easier way to set up a different - static -
color map per-layer. This means that we can set up a map of colors for each key,
on a per-layer basis, and whenever a layer becomes active, the color map for
that layer is applied. Colors are picked from a 16-color palette, provided by
the [LED-Palette-Theme][plugin:l-p-t] plugin. The color map is stored in
`EEPROM`, and can be easily changed via the [FocusSerial][plugin:focusserial]
plugin, which also provides palette editing capabilities.
[plugin:focusserial]: FocusSerial.md
[plugin:l-p-t]: LED-Palette-Theme.md
## Using the extension
To use the extension, include the header, tell it the number of layers you have,
register the `Focus` hooks, and it will do the rest.
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-Colormap.h>
#include <Kaleidoscope-FocusSerial.h>
#include <Kaleidoscope-LED-Palette-Theme.h>
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings,
LEDPaletteTheme,
ColormapEffect,
Focus);
void setup(void) {
Kaleidoscope.setup();
ColormapEffect.max_layers(1);
}
```
## Plugin methods
The extension provides an `ColormapEffect` singleton object, with a single method:
### `.max_layers(max)`
> Tells the extension to reserve space in EEPROM for up to `max` layers. Can
> only be called once, any subsequent call will be a no-op.
## Focus commands
### `colormap.map`
> Without arguments, prints the color map: palette indexes for all layers.
>
> With arguments, updates the color map with new indexes. One does not need to
> give the full map, the plugin will process as many arguments as available, and
> ignore anything past the last key on the last layer (as set by the
> `.max_layers()` method).
## Dependencies
* [Kaleidoscope-EEPROM-Settings](EEPROM-Settings.md)
* [Kaleidoscope-FocusSerial](FocusSerial.md)
* [Kaleidoscope-LED-Palette-Theme](LED-Palette-Theme.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/Colormap/Colormap.ino

@ -0,0 +1,97 @@
# Kaleidoscope-Cycle
If you ever wanted a key that works like keys on old cell phones, when you press
a key and it cycles through a number of options in a sequence, then the cycling
key is what you are looking for. It is a bit different than on cell phones of
old, as it is a separate key, that works in combination of other keys: you press
a key, then the cycle key, and the cycle key will replace the previously input
symbol with another. Keep tapping the cycle key, and it will replace symbols
with new ones, in a loop.
## Using the plugin
To use the plugin, we need to include the header, and declare the behaviour
used. Then, we need to place a cycle key or two on the keymap. And finally, we
need to implement the [`cycleAction`][cycleaction] function that gets called
each time the cycling key triggers.
[cycleaction]: #cycleactionpreviouskey-cyclecount
```c++
#include <Kaleidoscope-Cycle.h>
// Somewhere in the keymap:
Key_Cycle
// later in the Sketch:
void cycleAction(Key previous_key, uint8_t cycle_count) {
if (previous_key.raw == Key_A.raw) {
cycleThrough (Key_B, Key_C, Key_D);
}
}
KALEIDOSCOPE_INIT_PLUGINS(Cycle);
void setup(void) {
Kaleidoscope.setup();
}
```
## Keymap markup
### `Key_Cycle`
> The key code for the cycle key. There can be as many of this on the keymap, as
> many one wants, but they all behave the same. There is little point in having
> more than one on each side.
## Plugin methods
The plugin provides a `Cycle` object, but to implement the actions, we need to
define a function ([`cycleAction`][cycleaction]) outside of the object. A
handler, of sorts. The object also provides a helper method to replace the
previous symbol with another. The plugin also provides one macro that is
particularly useful, and in most cases, should be used over the `.replace()`
method explained below.
### `cycleThrough(keys...)`
> Cycles through all the possibilities given in `keys` (starting from the
> beginning once it reached the end). This should be used from
> the [`cycleAction`][cycleaction] function, once it is determined what sequence
> to cycle through.
>
> To make the cycling loop complete, the first element of the `keys` list should
> be the one that - when followed by the Cycle key - triggers the action.
### `.replace(key)`
> Deletes the previous symbol (by sending a `Backspace`), and inputs the new
> one. This is used by `cycleThrough()` above, behind the scenes.
>
> The recommended method is to use the macro, but in special circumstances, this
> function can be of direct use as well.
## Overrideable methods
### `cycleAction(previous_key, cycle_count)`
> The heart and soul of the plugin, that must be defined in the Sketch. It will
> be called whenever the cycling key triggers, and the two arguments are the
> last key pressed (not counting repeated taps of the cycling key itself), and
> the number of times the cycling key has been pressed.
>
> It is up to us to decide what to do, and when. But the most common - and
> expected - action is to call `cycleThrough()` with a different sequence for
> each key we want to use together with the cycling key.
## Dependencies
* [Kaleidoscope-Ranges](Ranges.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/Cycle/Cycle.ino

@ -0,0 +1,53 @@
# Kaleidoscope-CycleTimeReport
A development and debugging aid, this plugin will measure average mainloop times
(in microseconds) and print it to `Serial` periodically. While not the most
reliable way to measure the speed of processing, it gives a reasonable
indication nevertheless.
## Using the plugin
The plugin comes with reasonable defaults (see below), and can be used out of
the box, without any further configuration:
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-CycleTimeReport.h>
KALEIDOSCOPE_INIT_PLUGINS(CycleTimeReport);
void setup (void) {
Serial.begin(9600);
Kaleidoscope.setup ();
}
```
## Plugin methods
The plugin provides a single object, `CycleTimeReport`, with the following
property. All times are in milliseconds.
### `.average_loop_time`
> A read-only by contract value, the average time of main loop lengths between
> two reports.
## Overrideable methods
### `cycleTimeReport()`
> Reports the average loop time. By default, it does so over `Serial`, every
> time when the report period is up.
>
> It can be overridden, to change how the report looks, or to make the report
> toggleable, among other things.
>
> It takes no arguments, and returns nothing, but has access to
> `CycleTimeReport.average_loop_time` above.
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/CycleTimeReport/CycleTimeReport.ino

@ -0,0 +1,124 @@
# Kaleidoscope-EEPROM-Keymap-Programmer
Inspired by a similar feature on other keyboards, the `EEPROM-Keymap-Programmer`
plugin implements an on-device keymap re-arrangement / re-coding system. There
are two modes of operation: in one, we need to press a key we want to change,
then another to copy from. In the other, we press a key to change, and then
input a key code (terminated by any non-number key).
## The two modes of operation
It is worth looking at the two separately, to better understand how they work,
and what they accomplish:
### Copy mode
In `COPY` mode, the plugin will use both the built-in, default keymap, and the
override stored in `EEPROM`. When we select a key to override, we need to tap
another, which will be used as the source. The source key's code will be looked
up from the built-in keymap. For example, lets say we want to swap `A` and `B`
for some odd reason. We can do this by triggering the keymap programmer mode,
then tapping `A` to select it as the destination, then `B` as the source. The
plugin will look up the keycode in the built-in keymap for the key in `B`'s
location, and replace the location of `A` in the override with it. Next, we
press the `B` key to select it as the destination, and we press the key that
used to be `A` (but is now `B` too) to select it as a source. Because source
keys are looked up in the built-in keymap, the plugin will find it is `A`.
Obviously, this method only works if we have a built-in keymap, and it does not
support copying from another layer. It is merely a way to rearrange simple
things, like alphanumerics.
### Code mode
In `CODE` mode, instead of selecting a source key, we need to enter a code:
press numbers to input the code, and any non-number key to end the sequence.
Thus, when entering keymap programmer mode, and selecting, say, the `A` key,
then tapping `5 SPACE` will set the key to `B` (which has the keycode of `5`).
This allows us to use keycodes not present on the built-in keymap, at the
expense of having to know the keycode, and allowing no mistakes.
## Using the plugin
Adding the functionality of the plugin to a Sketch is easier the usage explained
above, though it requires that the [EEPROM-Keymap][plugin:eeprom-keymap] plugin
is also used, and set up appropriately.
Once the prerequisites are dealt with, all we need to do is to use the plugin,
and find a way to trigger entering the keymap programmer mode. One such way is
to use a macro, as in the example below:
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Keymap.h>
#include <Kaleidoscope-EEPROM-Keymap-Programmer.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-Macros.h>
const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {
if (macroIndex == 0 && keyToggledOff(keyState)) {
EEPROMKeymapProgrammer.activate();
}
return MACRO_NONE;
}
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings,
EEPROMKeymapProgrammer,
EEPROMKeymap,
Macros);
void setup() {
Kaleidoscope.setup();
Layer.getKey = EEPROMKeymap.getKey;
EEPROMKeymap.max_layers(1);
EEPROMSettings.seal();
}
```
The plugin should be used as early as possible, otherwise other plugins that
hook into the event system may start processing events before the programmer can
take over.
## Plugin methods
The plugin provides the `EEPROMKeymapProgrammer` object, which has the following
methods and properties:
### `.activate()`
> Activates the keymap programmer. This is the function one needs to call from -
> say - a macro, to enter the edit state.
### `.mode`
> Set this property to the mode to use for editing: either
> `kaleidoscope::EEPROMKeymapProgrammer::COPY`, or
> `kaleidoscope::EEPROMKeymapProgrammer::CODE`.
>
> Defaults to `kaleidoscope::EEPROMKeymapProgrammer::CODE`.
## Focus commands
The plugin provides a single `Focus` hook: `FOCUS_HOOK_KEYMAP_PROGRAMMER`, which
in turn provides the following command:
### `keymap.toggleProgrammer`
> Toggles the programmer mode on or off.
## Dependencies
* [Kaleidoscope-EEPROM-Keymap][plugin:eeprom-keymap]
[plugin:eeprom-keymap]: EEPROM-Keymap.md
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/EEPROM-Keymap-Programmer/EEPROM-Keymap-Programmer.ino

@ -0,0 +1,41 @@
# Kaleidoscope-Escape-OneShot
Turn the `Esc` key into a special key, that can cancel any active `OneShot`
effect - or act as the normal `Esc` key if none are active, or if any of them
are still held. For those times when one accidentally presses a one-shot key, or
change their minds.
## Using the plugin
To use the plugin, one needs to include the header, and activate it. No further
configuration is necessary.
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-OneShot.h>
#include <Kaleidoscope-Escape-OneShot.h>
KALEIDOSCOPE_INIT_PLUGINS(OneShot,
EscapeOneShot);
void setup () {
Kaleidoscope.setup ();
}
```
The plugin only makes sense when using one-shot keys.
## Plugin methods
The plugin provides the `EscapeOneShot` object, which has no public methods.
## Dependencies
* [Kaleidoscope-OneShot](OneShot.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/Escape-OneShot/Escape-OneShot.ino

@ -0,0 +1,62 @@
# Kaleidoscope-FingerPainter
The `FingerPainter` plugin provides an elaborate `LED` mode, in which one's able
to paint with their fingers: when edit mode is toggled on, keys will - instead
of performing their normal function - cycle through the global palette - as
provided by the [LED-Palette-Theme][plugin:l-p-t] plugin -, one by one for each tap.
This allows us to edit the theme with the keyboard only, without any special
software (except to toggle edit mode on and off).
## Using the plugin
To use the plugin, just include the header, add it to the list of used plugins.
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-LEDControl.h>
#include <Kaleidoscope-LED-Palette-Theme.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-FingerPainter.h>
#include <Kaleidoscope-FocusSerial.h>
KALEIDOSCOPE_INIT_PLUGINS(LEDControl,
EEPromSettings,
LEDPaletteTheme,
FingerPainter,
Focus);
void setup() {
Kaleidoscope.setup();
}
```
## Plugin methods
The plugin provides the `FingerPainter` object, which provides no public methods.
## Focus commands
### `fingerpainter.clear`
> Clears the canvas, so that one can start a new painting.
### `fingerpainter.toggle`
> Toggles the painting mode on and off.
## Dependencies
* [Kaleidoscope-EEPROM-Settings](EEPROM-Settings.md)
* [Kaleidoscope-FocusSerial](FocusSerial.md)
* [Kaleidoscope-LED-Palette-Theme][plugin:l-p-t]
* [Kaleidoscope-LEDControl](LEDControl.md)
[plugin:l-p-t]: LED-Palette-Theme.md
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/FingerPainter/FingerPainter.ino

@ -0,0 +1,84 @@
# Kaleidoscope-GhostInTheFirmware
Born out of the desire to demo LED effects on the keyboard without having to
touch it by hand (which would obstruct the video), the `GhostInTheFirmware`
plugin allows one to inject events at various delays, by telling it which keys
to press. Unlike macros, these press keys at given positions, as if they were
pressed by someone typing on it - the firmware will not see the difference.
Given a sequence (with press- and delay times), the plugin will walk through it
once activated, and hold the key for the specified amount, release it, and move
on to the next after the delay time.
## Using the plugin
To use the plugin, one needs to include the header, and configure it with a list
of key coordinates, a press time, and a delay time quartett. One also needs a
way to trigger starting the sequence, and a macro is the most convenient way for
that.
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-GhostInTheFirmware.h>
#include <Kaleidoscope-Macros.h>
const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) {
if (macro_index == 0 && keyToggledOn(key_state))
GhostInTheFirmware.activate();
return MACRO_NONE;
}
static const kaleidoscope::plugin::GhostInTheFirmware::GhostKey ghost_keys[] PROGMEM = {
{0, 0, 200, 50},
{0, 0, 0}
};
KALEIDOSCOPE_INIT_PLUGINS(GhostInTheFirmware,
Macros);
void setup() {
Kaleidoscope.setup ();
GhostInTheFirmware.ghost_keys = ghost_keys;
}
```
The plugin won't be doing anything until its `activate()` method is called -
hence the macro.
## Plugin methods
The plugin provides the `GhostInTheFirmware` object, which has the following
methods and properties:
### `.activate()`
> Start playing back the sequence. Best called from a macro.
### `.ghost_keys`
> Set this property to the sequence of keys to press, by assigning a sequence to
> this variable. Each element is a quartett of `row`, `column`, a `pressTime`,
> and a `delay`. Each of these will be pressed in different cycles, unlike
> macros which play back within a single cycle.
>
> The key at `row`, `column` will be held for `pressTime` milliseconds, and
> after an additional `delay` milliseconds, the plugin will move on to the next
> entry in the sequence.
>
> The sequence *MUST* reside in `PROGMEM`.
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/GhostInTheFirmware/GhostInTheFirmware.ino
## Upgrading
Previous versions of `GhostInTheFirmware` used
`kaleidoscope::GhostInTheFirmware::GhostKey` as a type for defining keys. In
newer versions, this is `kaleidoscope::plugin::GhostInTheFirmware::GhostKey`.
The old name still works, but will be removed by 2019-01-14.

@ -0,0 +1,89 @@
# Kaleidoscope-Heatmap
The `Heatmap` plugin provides a LED effect, that displays a heatmap on the
keyboard. The LEDs under each key will have a color according to how much use
they see. Fewer used keys will have deep blue colors, that gradually turns
lighter, then green, to yellow, and finally red for the most used keys. The
heatmap is not updated on every key press, but periodically. It's precision is
also an approximation, and not a hundred percent exact. Nevertheless, it is a
reasonable estimate.
## Using the plugin
The plugin comes with reasonable defaults pre-configured, all one needs to do is
include the header, and make sure the plugin is in use:
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-LEDControl.h>
#include <Kaleidoscope-Heatmap.h>
static const cRGB heat_colors[] PROGMEM = {
{ 0, 0, 0}, // black
{255, 25, 25}, // blue
{ 25, 255, 25}, // green
{ 25, 25, 255} // red
};
KALEIDOSCOPE_INIT_PLUGINS(LEDControl, HeatmapEffect);
void setup() {
Kaleidoscope.setup ();
HeatmapEffect.heat_colors = heat_colors;
HeatmapEffect.heat_colors_length = 4;
}
```
This sets up the heatmap to update every second (by default). It also registers
a new LED effect, which means that if you have not set up any other effects,
then Heatmap will likely be the default. You may not want that, so setting up
at least one other LED effect, such as `LEDOff` is highly recommended.
## Plugin methods
The plugin provides a `HeatmapEffect` object, which has the following methods
and properties:
### `.activate()`
> When called, immediately activates the Heatmap effect. Mostly useful in the
> `setup()` method of the Sketch, or in macros that are meant to switch to the
> heatmap effect, no matter where we are in the list.
### `.update_delay`
> The number of milliseconds to wait between updating the heatmap. Updating the
> heatmap incurs a significant performance penalty, and should not be done too
> often. Doing it too rarely, on the other hand, make it much less useful. One
> has to strike a reasonable balance.
>
> Defaults to *1000*.
### `.heat_colors`
> A cRGB array describing the gradian of colors that will be used, from colder
> to hoter keys.
> E.g. with `heat_colors = {{100, 0, 0}, {0, 100, 0}, {0, 0, 100}}`, a key
> with a temperature of 0.8 (0=coldest, 1=hotest), will end up with a color
> `{0, 40, 60}`.
>
> Defaults to `{{0, 0, 0}, {25, 255, 25}, {25, 255, 255}, {25, 25, 255}}`
> (black, green, yellow, red)
### `.heat_colors_length`
> Length of the `heat_colors` array.
>
> Defaults to *4*
## Dependencies
* [Kaleidoscope-LEDControl](LEDControl.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/Heatmap/Heatmap.ino

@ -0,0 +1,96 @@
# Kaleidoscope-HostOS
The `HostOS` extension is not all that useful in itself, rather, it is a
building block other plugins and extensions can use to not repeat the same
guesswork and logic.
The goal is to have a single place that remembers the host OS, whether set by
the end-user in a Sketch, or via a macro, or some other way. This information
can then be reused by other plugins.
See the [Unicode][plugin:unicode] extension for an example about how to use
`HostOS` in practice.
[plugin:unicode]: Unicode.md
## Using the extension
The extension provides a `HostOS` singleton object.
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-HostOS.h>
void someFunction(void) {
if (HostOS.os() == kaleidoscope::hostos::LINUX) {
// do something linux-y
}
if (HostOS.os() == kaleidoscope::hostos::OSX) {
// do something OSX-y
}
}
KALEIDOSCOPE_INIT_PLUGINS(HostOS)
void setup(void) {
Kaleidoscope.setup ();
}
```
## Extension methods
The extension provides the following methods on the `HostOS` singleton:
### `.os()`
> Returns the stored type of the Host OS.
### `.os(type)`
> Sets the type of the host OS, overriding any previous value. The type is then
> stored in EEPROM for persistence.
## Host OS Values
The OS type (i.e. the return type of `.os()` and the arguments to `.os(type)`) will be one of the following:
- `kaleidoscope::hostos::LINUX`
- `kaleidoscope::hostos::OSX`
- `kaleidoscope::hostos::WINDOWS`
- `kaleidoscope::hostos::OTHER`
## Focus commands
The plugin provides the `FocusHostOSCommand` object, which, when enabled,
provides the `hostos.type` Focus command.
### `hostos.type [type]`
> Without argument, returns the current OS type set (a numeric value).
>
> With an argument, it sets the OS type.
>
> This command can be used from the host to reliably set the OS type within the firmware.
## Dependencies
* [Kaleidoscope-EEPROM-Settings](EEPROM-Settings.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the extension.
[plugin:example]: ../../examples/HostOS/HostOS.ino
## Upgrading
Prior versions of `HostOS` used to include a way to auto-detect the host
operating system. This code was brittle, unreliable, and rather big too. For
these reasons, this functionality was removed. The `autoDetect()` method is now
a no-op, and is deprecated. The `Kaleidoscope/HostOS-select.h` header is
similarly obsolete, and has even been removed (for unrelated reasons). The
`autoDetect()` method will be removed by 2019-01-14.
Furthermore, `HostOS` now depends on `Kaleidoscope-EEPROM-Settings`, that plugin
should be initialized first.

@ -0,0 +1,56 @@
# Kaleidoscope-LED-ActiveModColor
With this plugin, any active modifier on the keyboard will have the LED under it
highlighted. No matter how the modifier got activated (a key press, a macro,
anything else), the coloring will apply. Layer keys, be them layer toggles,
momentary switches, or one-shot layer keys count as modifiers as far as the
plugin is concerned.
## Using the plugin
To use the plugin, one needs to include the header, and activate the effect. It
is also possible to use a custom color instead of the white default.
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-LEDControl.h>
#include <Kaleidoscope-LED-ActiveModColor.h>
KALEIDOSCOPE_INIT_PLUGINS(LEDControl,
ActiveModColorEffect);
void setup () {
Kaleidoscope.setup ();
ActiveModColorEffect.highlight_color = CRGB(0x00, 0xff, 0xff);
}
```
It is recommended to place the activation (the `KALEIDOSCOPE_INIT_PLUGINS` parameter) of the
plugin last, so that it can reliably override any other plugins that may work
with the LEDs, and apply the highlight over those.
## Plugin properties
The plugin provides the `ActiveModColorEffect` object, which has the following
properties:
### `.highlight_color`
> The color to use for highlighting the modifiers. Defaults to a white color.
### `.sticky_color`
> The color to use for highlighting one-shot modifiers when they are sticky. Defaults to a red color.
## Dependencies
* [Kaleidoscope-LEDControl](LEDControl.md)
* [Kaleidoscope-OneShot](OneShot.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/LED-ActiveModColor/LED-ActiveModColor.ino

@ -0,0 +1,128 @@
# Kaleidoscope-LED-Palette-Theme
A common base for plugins that want to provide themes, or theme-related
capabilities, using a 16 color palette. In other words, this is for plugin
authors primarily. The primary aim of the plugin is to provide not only a common
palette, but tools that make it easier to use it too.
## Using the plugin
To use the plugin, one needs to do a bit more than include the header, and tell
the firmware to use it. Itself being a mere building block, to use it to its
full extent, we need to create our own plugin on top of it.
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-LED-Palette-Theme.h>
#include <Kaleidoscope-FocusSerial.h>
namespace example {
class TestLEDMode : public LEDMode {
public:
TestLEDMode() {}
protected:
void setup(void) final;
void update(void) final;
kaleidoscope::EventHandlerResult onFocusEvent(const char *command);
private:
static uint16_t map_base_;
};
uint16_t TestLEDMode::map_base_;
void TestLEDMode::setup(void) {
map_base_ = LEDPaletteTheme.reserveThemes(1);
}
void TestLEDMode::update(void) {
LEDPaletteTheme.updateHandler(map_base_, 0);
}
kaleidoscope::EventHandlerResult
TestLEDMode::onFocusEvent(const char *command) {
return LEDPaletteTheme.themeFocusEvent(command, PSTR("testLedMode.map"), map_base_, 1);
}
}
example::TestLEDMode TestLEDMode;
KALEIDOSCOPE_INIT_PLUGINS(
Focus,
LEDPaletteTheme,
TestLEDMode,
EEPROMSettings
);
void setup() {
Kaleidoscope.setup();
TestLEDMode.activate();
}
```
This is a simple extension, where it provides a `testLEDMode.map` Focus command,
with which one can set the theme which will be saved to EEPROM.
## Plugin methods
The plugin provides the `LEDPaletteTheme` object, which has the following methods and properties:
### `.reserveThemes(max_themes)`
> Reserve space in EEPROM for `max_themes`. Each key on a theme uses half a byte
> of space. The function returns the `theme_base` to be used with the rest of
> the methods.
>
> The `theme_base` is a pointer into the EEPROM where the theme storage starts.
### `.updateHandler(theme_base, theme)`
> A helper we can call in our plugin's `.update()` method: given an EEPROM
> location (`theme_base`), and a `theme` index, it will update the keyboard with
> the colors of the specified theme.
>
> The `theme` argument can be any index between zero and `max_themes`. How the
> plugin decides which theme to display depends entirely on the plugin.
### `.themeFocusEvent(command, expected_command, theme_base, max_themes)`
> To be used in a custom `Focus` handler: handles the `expected_command` Focus
> command, and provides a way to query and update the themes supported by the
> plugin.
>
> When queried, it will list the color indexes. When used as a setter, it
> expects one index per key.
>
> The palette can be set via the `palette` focus command, provided by the
> `LEDPaletteTheme` plugin.
## Focus commands
### `palette`
> Without arguments, prints the palette: RGB values for all 16 colors.
>
> With arguments, updates the palette with new colors. One does not need to give
> the full palette, the plugin will process as many arguments as available, and
> ignore anything past the last index. It expects colors to have all three
> components specified, or none at all. Thus, partial palette updates are
> possible, but only on the color level, not at component level.
## Dependencies
* [Kaleidoscope-EEPROM-Settings](EEPROM-Settings.md)
* [Kaleidoscope-FocusSerial](FocusSerial.md)
* [Kaleidoscope-LEDControl](LEDControl.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/LED-Palette-Theme/LED-Palette-Theme.ino

@ -0,0 +1,71 @@
# Kaleidoscope-LEDEffects
The `LEDEffects` plugin provides a selection of LED effects, each of them fairly
simple, simple enough to not need a plugin of their own.
## Using the plugin
There are a number of different effects included in the package, all of them are
available once including the header, and one's free to choose any number of
them.
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-LEDEffects.h>
KALEIDOSCOPE_INIT_PLUGINS(LEDControl, JukeBoxEffect);
void setup(void) {
Kaleidoscope.setup();
}
```
## Included effects
All of these effects will scan the active layers, and apply effects based on
what keys are active on each position, thus, it needs no hints or configuration
to figure out our layout!
### `MiamiEffect`
Applies a color effect to the keyboard, inspired by the popular Miami keyset:
![Miami](extras/MiamiEffect.png)
Alphas, punctuation, numbers, the space bar, the numbers and the dot on the
keypad, and half the function keys will be in a cyan-ish color, the rest in
magenta.
### `JukeboxEffect`
Applies a color effect to the keyboard, inspired by the JukeBox keyset:
![Jukebox](extras/JukeboxEffect.png)
Alphas, punctuation, numbers, the space bar, the numbers and the dot on the
keypad, and half the function keys will be in a beige-ish color, the rest in
light green, except for the `Esc` key, which will be in red.
An alternative color scheme exists under the `JukeboxAlternateEffect` name,
where the light green and red colors are swapped.
## Plugin methods
The plugin provides a single method on each of the included effect objects:
### `.activate()`
> When called, immediately activates the effect. Mostly useful in the `setup()`
> method of the Sketch, or in macros that are meant to switch to the selected
> effect, no matter where we are in the list.
## Dependencies
* [Kaleidoscope-LEDControl](LEDControl.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/LEDEffects/LEDEffects.ino

@ -0,0 +1,107 @@
# Kaleidoscope-Leader
Leader keys are a kind of key where when they are tapped, all following keys are
swallowed, until the plugin finds a matching sequence in the dictionary, it
times out, or fails to find any possibilities. When a sequence is found, the
corresponding action is executed, but the processing still continues. If any key
is pressed that is not the continuation of the existing sequence, processing
aborts, and the key is handled normally.
This behaviour is best described with an example. Suppose we want a behaviour
where `LEAD u` starts unicode input mode, and `LEAD u h e a r t` should result
in a heart symbol being input, and we want `LEAD u 0 0 e 9 SPC` to input `é`,
and any other hex code that follows `LEAD u`, should be handled as-is, and
passed to the host. Obviously, we can't have all of this in a dictionary.
So we put `LEAD u` and `LEAD u h e a r t` in the dictionary only. The first will
start unicode input mode, the second will type in the magic sequence that
results in the symbol, and then aborts the leader sequence processing. With this
setup, if we type `LEAD u 0`, then `LEAD u` will be handled first, and start
unicode input mode. Then, at the `0`, the plugin notices it is not part of any
sequence, so aborts leader processing, and passes the key on as-is, and it ends
up being sent to the host. Thus, we covered all the cases of our scenario!
## Using the plugin
To use the plugin, one needs to include the header, implement some actions,
create a dictionary, and configure the provided `Leader` object to use the
dictionary:
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-Leader.h>
static void leaderA(uint8_t seq_index) {
Serial.println("leaderA");
}
static void leaderTX(uint8_t seq_index) {
Serial.println("leaderTX");
}
static const kaleidoscope::Leader::dictionary_t leader_dictionary[] PROGMEM =
LEADER_DICT({LEADER_SEQ(LEAD(0), Key_A), leaderA},
{LEADER_SEQ(LEAD(0), Key_T, Key_X), leaderTX});
KALEIDOSCOPE_INIT_PLUGINS(Leader);
void setup() {
Serial.begin(9600);
Kaleidoscope.setup();
Leader.dictionary = leader_dictionary;
}
```
The dictionary is made up of a list of keys, and an action callback. Using the
`LEADER_DICT` and `LEADER_SEQ` helpers is recommended. The dictionary *must* be
marked `PROGMEM`!
**Note** that we need to use the `Leader` object before any other that adds or
changes key behaviour! Failing to do so may result in unpredictable behaviour.
## Plugin methods
The plugin provides the `Leader` object, with the following methods and properties:
### `.dictionary`
> Set this property to the dictionary `Leader` should use. The dictionary is an
> array of `kaleidoscope::Leader::dictionary_t` elements. Each element is made
> up of two elements, the first being a list of keys, the second an action to
> perform when the sequence is found.i
>
> The dictionary *MUST* reside in `PROGMEM`.
### `.reset()`
> Finishes the leader sequence processing. This is best called from actions that
> are final actions, where one does not wish to continue the leader sequence
> further in the hopes of finding a longer match.
### `.time_out`
> The number of milliseconds to wait before a sequence times out. Once the
> sequence timed out, if there is a partial match with an action, that will be
> performed, otherwise the Leader sequence will simply reset.
>
> Defaults to 1000.
## Dependencies
* [Kaleidoscope-Ranges](Ranges.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/Leader/Leader.ino
## Upgrading
Previous versions of `Leader` used `kaleidoscope::Leader::dictionary_t` as a
type for defining the dictionary. In newer versions, this is
`kaleidoscope::plugin::Leader::dictionary_t`. The old name still works, but will
be removed by 2019-01-14.

@ -0,0 +1,188 @@
# Kaleidoscope-OneShot
One-shots are a new kind of behaviour for your standard modifier and momentary
layer keys: instead of having to hold them while pressing other keys, they can
be tapped and released, and will remain active until any other key is pressed.
In short, they turn `Shift, A` into `Shift+A`, and `Fn, 1` to `Fn+1`. The main
advantage is that this allows us to place the modifiers and layer keys to
positions that would otherwise be awkward when chording. Nevertheless, they
still act as normal when held, that behaviour is not lost.
Furthermore, if a one-shot key is tapped two times in quick succession, it
becomes sticky, and remains active until disabled with a third tap. This can be
useful when one needs to input a number of keys with the modifier or layer
active, and still does not wish to hold the key down. If this feature is
undesirable, unset the `OneShot.double_tap_sticky` property (see later).
To make multi-modifier, or multi-layer shortcuts possible, one-shot keys remain
active if another one-shot of the same type is tapped, so `Ctrl, Alt, b` becomes
`Ctrl+Alt+b`, and `L1, L2, c` is turned into `L1+L2+c`. Furthermore, modifiers
and other layer keys do not cancel the one-shot effect, either.
## Using One-Shot Keys
To enter one-shot mode, tap _quickly_ on a one-shot key. The next
normal (non-one-shot) key you press will have the modifier applied,
and then the modifier will automatically turn off. If the Shift key is
a one-shot modifier, then hitting `Shift, a, b` will give you `Ab`,
_if you hit shift quickly._
Longish keypresses do not activate one-shot mode. If you press `Shift,
a, b`, as above, but hold the Shift key a bit longer, you'll get `ab`.
To enter sticky mode, _tap twice quickly_ on a one-shot key. The
modifier will now stay on until you press it again. Continuing the
`Shift` example, tapping `Shift, Shift` _quickly_ and then `a, b, c,
Shift, d, e, f` will give you `ABCdef`.
This can be a bit tricky; combining this plugin with
[LED-ActiveModColor](LED-ActiveModColor).md
will help you understand what state your one-shot is in; when a
one-shot key is active, it will have a white LED highlight; when
sticky, a red highlight.
## Using the plugin
After adding one-shot keys to the keymap, all one needs to do, is enable the
plugin:
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-OneShot.h>
#include <kaleidoscope/hid.h>
// somewhere in the keymap...
OSM(LeftControl), OSL(_FN)
KALEIDOSCOPE_INIT_PLUGINS(OneShot);
void setup() {
Kaleidoscope.setup();
}
```
## Keymap markup
There are two macros the plugin provides:
### `OSM(mod)`
> A macro that takes a single argument, the name of the modifier: `LeftControl`,
> `LeftShift`, `LeftAlt`, `LeftGui` or their right-side variant. When marked up
> with this macro, the modifier will act as a one-shot modifier.
### `OSL(layer)`
> Takes a layer number as argument, and sets up the key to act as a one-shot
> layer key.
>
> Please note that while `Kaleidoscope` supports more, one-shot layers are
> limited to 8 layers only.
## Plugin methods
The plugin provides one object, `OneShot`, which implements both one-shot
modifiers and one-shot layer keys. It has the following methods:
### `.isActive()`
> Returns if any one-shot key is in flight. This makes it possible to
> differentiate between having a modifier or layer active, versus having them
> active only until after the next key getting pressed. And this, in turn, is
> useful for macros that need to fiddle with either modifier or layer state: if
> one-shots are not active, they need not restore the original state.
### `.isPressed()`
> Returns true if any one-shot key is still held.
### `.isSticky(key)`
> Returns if the key is currently sticky.
### `.isModifierActive(key)`
> Returns if the modifier `key` has a one-shot state active. Use this together
> with `hid::isModifierKeyActive` to catch cases where a one-shot modifier is
> active, but not registered yet.
### `.cancel([with_stickies])`
> The `cancel()` method can be used to cancel any pending one-shot effects,
> useful when one changed their minds, and does not wish to wait for the
> timeout.
>
> The optional `with_stickies` argument, if set to `true`, will also cancel
> sticky one-shot effects. If omitted, it defaults to `false`, and not canceling
> stickies.
### `.inject(key, keyState)`
> Simulates a key event, specifically designed to inject one-shot keys into the
> event loop. The primary purpose of this method is to make it easier to trigger
> multiple one-shots at the same time.
>
> See the example sketch for more information about its use.
## Plugin properties
Along with the methods listed above, the `OneShot` object has the following
properties too:
### `.time_out`
> Set this property to the number of milliseconds to wait before timing out and
> cancelling the one-shot effect (unless interrupted or cancelled before by any
> other means).
>
> Defaults to 2500.
### `.hold_time_out`
> Set this property to the number of milliseconds to wait before considering a
> held one-shot key as intentionally held. In this case, the one-shot effect
> will not trigger when the key is released. In other words, holding a one-shot
> key at least this long, and then releasing it, will not trigger the one-shot
> effect.
>
> Defaults to 200.
### `.double_tap_sticky`
> Set this boolean property to make the plugin treat a double-tap of a one-shot
> key as making it sticky until a third tap. Setting it to `false` disables this
> behaviour, in which case double-tapping a one-shot modifier will just restart
> the timer.
>
> Defaults to `true`.
### `.double_tap_sticky_layers`
> The same as `.double_tap_sticky`, but only applies to layers. The two can be
> set separately.
>
> Defaults to `true`.
### `.double_tap_time_out`
> Set this property to the number of milliseconds within which a second
> uninterrupted tap of the same one-shot key will be treated as a sticky-tap.
> Only takes effect when `.double_tap_sticky` is set.
>
>
> Setting the property to `-1` will make the double-tap timeout use `.time_out`
> for its calculations.
>
> Defaults to -1.
## Dependencies
* [Kaleidoscope-Ranges](Ranges.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/OneShot/OneShot.ino

@ -0,0 +1,158 @@
# Kaleidoscope-Qukeys
## Concept
This Kaleidoscope plugin allows you to overload keys on your keyboard so that they produce
one keycode (i.e. symbol) when tapped, and a different keycode -- most likely a modifier
(e.g. `shift` or `alt`) -- when held.
## Setup
- Include the header file:
```
#include <Kaleidoscope-Qukeys.h>
```
- Use the plugin in the `KALEIDOSCOPE_INIT_PLUGINS` macro:
```
KALEIDOSCOPE_INIT_PLUGINS(Qukeys);
```
- Define some `Qukeys` of the format `Qukey(layer, row, col, alt_keycode)`
(layers, rows and columns are all zero-indexed, rows are top to bottom and
columns are left to right):
- For the Keyboardio Model 01, key coordinates refer to [this header
file](Hardware-Model01/blob/f469015346535cb864a340bf8eb317d268943248/src/Kaleidoscope-Hardware-Model01.h#L267-L279)..md
```
QUKEYS(
// l, r, c, alt_keycode
kaleidoscope::plugin::Qukey(0, 2, 1, Key_LeftGui), // A/cmd
kaleidoscope::plugin::Qukey(0, 2, 2, Key_LeftAlt), // S/alt
kaleidoscope::plugin::Qukey(0, 2, 3, Key_LeftControl), // D/ctrl
kaleidoscope::plugin::Qukey(0, 2, 4, Key_LeftShift), // F/shift
kaleidoscope::plugin::Qukey(0, 1, 14, Key_LeftShift), // P/shift
kaleidoscope::plugin::Qukey(0, 3, 15, Key_LeftShift) // Minus/shift
)
```
`Qukeys` will work best if it's the first plugin in the `INIT()` list, because when typing
overlap occurs, it will (temporarily) mask keys and block them from being processed by
other plugins. If those other plugins handle the keypress events first, it may not work as
expected. It doesn't _need_ to be first, but if it's `INIT()`'d after another plugin that
handles typing events, especially one that sends extra keyboard HID reports, it is more
likely to generate errors and out-of-order events.
## Configuration
### `.setTimeout(time_limit)`
> Sets the time length in milliseconds which determines if a key has been tapped or held.
>
> Defaults to 250.
### `.setReleaseDelay(release_delay)`
> Sets the time length in milliseconds to artificially delay the release of the Qukey.
>
> This is to accommodate users who are in the habit of releasing modifiers and the keys
> they modify (almost) simultaneously, since the Qukey may be detected as released
> *slightly* before the other key, which would not trigger the desired alternate keycode.
>
> It is best to keep this a very small value such as 20 to avoid over-extending the
> modifier to further keystrokes.
>
> Defaults to 0.
### `.activate()`
### `.deactivate()`
### `.toggle()`
> activate/deactivate `Qukeys`
### DualUse key definitions
In addition to normal `Qukeys` described above, Kaleidoscope-Qukeys also treats
DualUse keys in the keymap as `Qukeys`. This makes `Qukeys` a drop-in replacement
for the `DualUse` plugin, without the need to edit the keymap.
The plugin provides a number of macros one can use in keymap definitions:
#### `CTL_T(key)`
> A key that acts as the *left* `Control` when held, or used in conjunction with
> other keys, but as `key` when tapped in isolation. The `key` argument must be
> a plain old key, and can't have any modifiers or anything else applied.
#### `ALT_T(key)`
> A key that acts as the *left* `Alt` when held, or used in conjunction with
> other keys, but as `key` when tapped in isolation. The `key` argument must be
> a plain old key, and can't have any modifiers or anything else applied.
#### `SFT_T(key)`
> A key that acts as the *left* `Shift` when held, or used in conjunction with
> other keys, but as `key` when tapped in isolation. The `key` argument must be
> a plain old key, and can't have any modifiers or anything else applied.
#### `GUI_T(key)`
> A key that acts as the *left* `GUI` when held, or used in conjunction with
> other keys, but as `key` when tapped in isolation. The `key` argument must be
> a plain old key, and can't have any modifiers or anything else applied.
#### `MT(mod, key)`
> A key that acts as `mod` when held, or used in conjunction with other keys,
> but as `key` when tapped in isolation. The `key` argument must be a plain old
> key, and can't have any modifiers or anything else applied. The `mod` argument
> can be any of the modifiers, *left* or *right* alike.
#### `LT(layer, key)`
> A key that momentarily switches to `layer` when held, or used in conjunction
> with other keys, but as `key` when tapped in isolation. The `key` argument
> must be a plain old key, and can't have any modifiers or anything else
> applied.
## Design & Implementation
When a `Qukey` is pressed, it doesn't immediately add a corresponding keycode to the HID
report; it adds that key to a queue, and waits until one of three things happens:
1. a time limit is reached
2. the `Qukey` is released
3. a subsequently-pressed key is released
Until one of those conditions is met, all subsequent keypresses are simply added to the
queue, and no new reports are sent to the host. Once a condition is met, the `Qukey` is
flushed from the queue, and so are any subsequent keypresses (up to, but not including,
the next `Qukey` that is still pressed).
Basically, if you hold the `Qukey`, then press and release some other key, you'll get the
alternate keycode (probably a modifier) for the `Qukey`, even if you don't wait for a
timeout. If you're typing quickly, and there's some overlap between two keypresses, you
won't get the alternate keycode, and the keys will be reported in the order that they were
pressed -- as long as the keys are released in the same order they were pressed.
The time limit is mainly there so that a `Qukey` can be used as a modifier (in its
alternate state) with a second input device (e.g. a mouse). It can be quite short (200ms
is probably short enough) -- as long as your "taps" while typing are shorter than the time
limit, you won't get any unintended alternate keycodes.
## Further reading
The [example][plugin:example] can help to learn how to use this plugin.
[plugin:example]: ../../examples/Qukeys/Qukeys.ino
## Upgrading
Previous versions of `Qukeys` used `kaleidoscope::Qukey` objects within the
`QUKEYS` macro. In newer versions, this is `kaleidoscope::plugin::Qukey`
instead. The old name still works, but will be removed by 2019-01-14.

@ -0,0 +1,39 @@
# Kaleidoscope-Ranges
## kaleidoscope::ranges enum
This plugin defines the `ranges` enum that many plugins use.
To explain its purpose, first a brief digression to explain how Kaleidoscope implements keys.
Keys in Kaleidoscope are defined as follows:
```c++
// in Kaleidoscope/src/key_defs.h
typedef union Key_ {
struct {
uint8_t keyCode;
uint8_t flags;
};
uint16_t raw;
// bunch of operator overloads elided...
} Key;
```
That is, a key is a 16-bit integer that, by default, has 8 bits for the keyCode and 8 bits for flags.
For normal keypresses, this is straightforward: the 8-bit keyCode is the normal HID code corresponding to a normal keyboard key and the flags are used to indicate the modifiers being held.
However, many plugins want to be able to make key presses do something special and need some way of indicating that a key is not just an ordinary key.
To do this, we take advantage of the fact that our flags field is 8 bits, but there are only five normal modifiers (control, shift, GUI, right alt, and left alt).
<!-- question: does bit six have any signicance? it seems to be unused
--> Therefore, we can use a bit to indicate that something special is happening with a given key:
In this case, by setting the high bit of the flags field, we indicate that this is a reserved key and isn't going to be interpreted normally.
This way, a plugin can make a key be sent with the high bit of the flags field set, then it is free to use the rest of the 16 bits as it sees fit and be assured that it won't conflict with the built-in keys.
However, there is a problem with this:
Many plugins will want to do this, so how can they be sure that the key codes they make won't be interpreted by another plugin?
Thus, we come to the purpose of this enum:
The `range` enum gives the ranges of possible raw key values that each plugin will use; by referring to it, plugins can be sure none of them will step on each others' toes.
**In summary, the values in the enum here gives the possible raw keycode values that the various plugins will inject; if you're trying to make a plugin that will be injecting special key events, you should probably add yourself to the enum here.**

@ -0,0 +1,63 @@
# Kaleidoscope-Redial
If you ever wanted to just repeat the last key pressed, no matter what it was,
this plugin is made for you. It allows you to configure a key that will repeat
whatever the last previously pressed key was. Of course, one can limit which
keys are remembered...
## Using the plugin
To use the plugin, we'll need to enable it, and configure a key to act as the
"redial" key. This key should be on the keymap too.
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-Redial.h>
#include <kaleidoscope-Ranges.h>
enum {
REDIAL = kaleidoscope::ranges::SAFE_START,
};
#define Key_Redial (Key) {.raw = REDIAL}
// Place Key_Redial somewhere on the keymap...
KALEIDOSCOPE_INIT_PLUGINS(Redial);
void setup() {
Kaleidoscope.setup();
Redial.key = Key_Redial;
}
```
## Overrideable plugin methods
### `bool shouldRemember(Key mapped_key)`
> If one wants to change what keys the plugin remembers, simply override the
> `kaleidoscope::Redial::shouldRemember` function. Whenever a key is to be
> remembered, this function will be called with the key as argument. It should
> return `true` if the key should be remembered (and repeated by Redial),
> `false` otherwise.
>
> By default, the plugin will remember alphanumeric keys only.
## Plugin properties
The `Redial` object has only one property, the key to trigger it.
### `.key`
> The key to trigger the redial effect. Be aware that whatever key you specify
> here, will have its action shadowed by the redial functionality. Choose
> something unused, see the example sketch for one way to do that.
>
> There is no default.
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/Redial/Redial.ino

@ -0,0 +1,69 @@
# Kaleidoscope-ShapeShifter
`ShapeShifter` is a plugin that makes it considerably easier to change what
symbol is input when a key is pressed together with `Shift`. If one wants to
rearrange the symbols on the number row for example, without modifying the
layout on the operating system side, this plugin is where one can turn to.
What it does, is very simple: if any key in its dictionary is found pressed
while `Shift` is held, it will press another key instead of the one triggering
the event. For example, if it sees `Shift + 1` pressed together, which normally
results in a `!`, it will press `4` instead of `1`, inputting `$`.
## Using the plugin
To use the plugin, one needs to include the header, create a dictionary, and
configure the provided `ShapeShifter` object to use the dictionary:
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-ShapeShifter.h>
static const kaleidoscope::plugin::ShapeShifter::dictionary_t shape_shift_dictionary[] PROGMEM = {
{Key_1, Key_4},
{Key_4, Key_1},
{Key_NoKey, Key_NoKey},
};
KALEIDOSCOPE_INIT_PLUGINS(ShapeShifter);
void setup() {
Kaleidoscope.setup();
ShapeShifter.dictionary = shape_shift_dictionary;
}
```
The dictionary is made up of `Key` pairs: the first one is to replace, the
second is the replacement. The dictionary must be closed with a `{Key_NoKey,
Key_NoKey}` pair, and **must** reside in `PROGMEM`.
## Plugin methods
The plugin provides the `ShapeShifter` object, with the following methods and
properties:
### `.dictionary`
> Set this property to the dictionary `ShapeShifter` should use. The dictionary
> is an array of `kaleidoscope::ShapeShifter::dictionary_t` elements, which is
> just a very verbose way of saying that its a pair of keys. The first one is
> the one to replace, and the other is to replace it with.
>
> Be aware that the replacement key will be pressed with `Shift` held, so do
> keep that in mind!
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/ShapeShifter/ShapeShifter.ino
## Upgrading
Previous versions of `ShapeShifter` used
`kaleidoscope::ShapeShifter::dictionary_t` as a type for defining the
dictionary. In newer versions, this is
`kaleidoscope::plugin::ShapeShifter::dictionary_t`. The old name still works,
but will be removed by 2019-01-14.

@ -0,0 +1,164 @@
# Kaleidoscope-SpaceCadet
[Space Cadet][space-cadet] is a way to make it more convenient to input
parens - those `(` and `)` things -, symbols that a lot of programming languages
use frequently. If you are working with Lisp, you are using these all the time.
What it does, is that it turns your left and right `Shift` keys into parens if
you tap and release them, without pressing any other key while holding them.
Therefore, to input, say, `(print foo)`, you don't need to press `Shift`, hold
it, and press `9` to get a `(`, you simply press and release `Shift`, and
continue writing. You use it as if you had a dedicated key for parens!
But if you wish to write capital letters, you hold it, as usual, and you will
not see any parens when you release it. You can also hold it for a longer time,
and it still would act as a `Shift`, without the parens inserted on release:
this is useful when you want to augment some mouse action with `Shift`, to
select text, for example.
After getting used to the Space Cadet style of typing, you may wish to enable
this sort of functionality on other keys, as well. Fortunately, the Space Cadet
plugin is configurable and extensible to support adding symbols to other keys.
Along with `(` on your left `Shift` key and `)` on your right `Shift` key,
you may wish to add other such programming mainstays as `{` to your left-side `cmd` key,
`}` to your right-side `alt` key, `[` to your left `Control` key, and `]` to your right
`Control` key. You can map the keys in whatever way you may wish to do, so feel free to
experiment with different combinations and discover what works best for you!
[space-cadet]: https://en.wikipedia.org/wiki/Space-cadet_keyboard
## Using the plugin
Using the plugin with its defaults is as simple as including the header, and
enabling the plugin:
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-SpaceCadet.h>
KALEIDOSCOPE_INIT_PLUGINS(SpaceCadet);
void setup() {
Kaleidoscope.setup();
}
```
This assumes a US QWERTY layout on the host computer, though the plugin sends
the correct keymap code for each symbol. Because the mapping is entirely
configurable, though, you may switch out keys at your leisure.
If you wish to enable additional modifier keys (or disable the default behavior
for the shift and parentheses combinations), configuration is as simple as
passing a new keymap into the SpaceCadet object, as shown below:
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-SpaceCadet.h>
KALEIDOSCOPE_INIT_PLUGINS(SpaceCadet);
void setup() {
Kaleidoscope.setup();
//Set the keymap with a 250ms timeout per-key
//Setting is {KeyThatWasPressed, AlternativeKeyToSend, TimeoutInMS}
//Note: must end with the SPACECADET_MAP_END delimiter
static kaleidoscope::plugin::SpaceCadet::KeyBinding spacecadetmap[] = {
{Key_LeftShift, Key_LeftParen, 250}
, {Key_RightShift, Key_RightParen, 250}
, {Key_LeftGui, Key_LeftCurlyBracket, 250}
, {Key_RightAlt, Key_RightCurlyBracket, 250}
, {Key_LeftAlt, Key_RightCurlyBracket, 250}
, {Key_LeftControl, Key_LeftBracket, 250}
, {Key_RightControl, Key_RightBracket, 250}
, SPACECADET_MAP_END
};
//Set the map.
SpaceCadet.map = spacecadetmap;
}
```
## Plugin methods
The plugin provides the `SpaceCadet` object, with the following methods and
properties:
### `.map`
> Set the key map. This takes an array of
> `kaleidoscope::plugin::SpaceCadet::KeyBinding` objects with the special
> `SPACECADET_MAP_END` sentinal to mark the end of the map. Each KeyBinding
> object takes, in order, the key that was pressed, the key that should be sent
> instead, and an optional per-key timeout override
>
> If not explicitly set, defaults to mapping left `shift` to `(` and right `shift`
> to `)`.
### `kaleidoscope::plugin::SpaceCadet::KeyBinding`
> An object consisting of the key that is pressed, the key that should be sent
> in its place, and the timeout (in milliseconds) until the key press is
> considered to be a "held" key press. The third parameter, the timeout, is
> optional and may be set per-key or left out entirely (or set to `0`) to use
> the default timeout value.
### `.time_out`
> Set this property to the number of milliseconds to wait before considering a
> held key in isolation as its secondary role. That is, we'd have to hold a
> `Shift` key this long, by itself, to trigger the `Shift` role in itself. This
> timeout setting can be overridden by an individual key in the keymap, but if
> it is omitted or set to `0` in the key map, the global timeout will be used.
>
> Defaults to 1000.
### `.enable()`
> This method enables the SpaceCadet plugin. This is useful for interfacing
> with other plugins or macros, especially where SpaceCadet functionality isn't
> always desired.
>
> The default behavior is `enabled`.
### `.disable()`
> This method disables the SpaceCadet behavior. This is useful for interfacing
> with other plugins or macros, especially where SpaceCadet functionality isn't
> always desired.
### `.active()`
> This method returns `true` if SpaceCadet is enabled and `false` if SpaceCadet
> is disabled. This is useful for interfacing with other plugins or macros,
> especially where SpaceCadet functionality isn't always desired.
### `Key_SpaceCadetEnable`
> This provides a key for placing on a keymap for enabling the SpaceCadet
> behavior. This is only triggered on initial downpress, and does not
> trigger again if held down or when the key is released.
### `Key_SpaceCadetDisable`
> This provides a key for placing on a keymap for disabling the SpaceCadet
> behavior. This is only triggered on initial downpress, and does not
> trigger again if held down or when the key is released.
## Dependencies
* [Kaleidoscope-Ranges](Ranges.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/SpaceCadet/SpaceCadet.ino
## Upgrading
Previous versions of `SpaceCadet` used
`kaleidoscope::SpaceCadet::KeyBinding` as a type for defining keybindings. In newer versions, this is
`kaleidoscope::plugin::SpaceCadet::KeyBinding`. The old name still works,
but will be removed by 2019-01-14.

@ -0,0 +1,96 @@
# Kaleidoscope-Steno
Stenography is a way to write in shorthand, a chorded input system that allows
very fast input (considerably higher than normal touch typing), by using
shorthand chords and a dictionary. This plugin implements the `GeminiPR`
protocol that supports a number of systems, including [Plover][plover].
[plover]: http://www.openstenoproject.org/plover/
While Plover supports a normal QWERTY keyboard too, having a dedicated plugin
comes with important advantages:
* No need to toggle Plover on and off, because the normal keys are not taken
over by Plover anymore.
* Easier toggling, because you only have to toggle the layer, not Plover too. If
you switch back to a keyboard layer, without toggling Plover off, nothing
unexpected will happen. Plover will not take over the keys.
* The `GeminiPR` protocol supports language systems other than English.
Do note that the `GeminiPR` protocol is implemented over the virtual serial
port, so any plugin that wants to use that port too, will run into
conflicts with the Steno plugin. In other words, don't use it together
with [Focus][k:focus].
[k:focus]: FocusSerial.md
## What is Steno? Why should I use it? How do I learn?
As mentioned above, steno (short for "stenography") is a shorthand, chorded
input system that allows very fast input - licensed stenographers are required
to type **225 WPM at 95% accuracy** to get their license. Although reaching that
speed typically takes 2-6 years of practice and training, lower speeds
comparable to or exceeding that of touch typing can reportedly be reached in
only a few months.
[This talk][stenotalk] (YouTube link) gives a brief introduction to Steno, how
it works, and why it is cool.
[stenotalk]: https://youtu.be/Wpv-Qb-dB6g
One recommend way to get started with learning Steno is with [Plover][plover].
Plover is software for your computer that will interpret the steno input from
your Model 01 (or other NKRO QWERTY keyboard); it is available for Windows,
macOS, and Linux. Plover's [Beginner's Guide][ploverguide] is a great place to
get started with Steno in general and Plover in particular.
[ploverguide]: https://github.com/openstenoproject/plover/wiki/Beginner's-Guide:-Get-Started-with-Plover
## Using the plugin
To use the plugin, simply include the header in your Sketch, tell the firmware
to use the `GeminiPR` object, and place Steno keys on your keymap. It is best
illustrated with an example:
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-Steno.h>
// Somewhere in the keymap:
S(S1), S(S2), etc
KALEIDOSCOPE_INIT_PLUGINS(GeminiPR);
void setup() {
Kaleidoscope.setup();
}
```
## Keys provided by the plugin
The plugin provides a number of keys one can put on the keymap, that allow
correspond to various Steno keys. All of these must be used together with the
`S()` macro provided by the plugin, as can be seen in the example above.
The provided keys are: `FN`, `N1`, `N2`, `N3`, `N4`, `N5`, `N6`, `S1`, `S2`,
`TL`, `KL`, `PL`, `WL`, `HL`, `RL`, `A`, `O`, `ST1`, `ST2`, `RE1`, `RE2`, `PWR`,
`ST3`, `ST4`, `E`, `U`, `FR`, `RR`, `PR`, `BR`, `LR`, `GR`, `TR`, `SR`, `DR`,
`N7`, `N8`, `N9`, `NA`, `NB`, `NC`, `ZR`.
See the [example][plugin:example] for the default/suggested placements of each
of these keys.
## Plugin methods and properties
The plugin provides a `GeminiPR` object, with no public methods or properties.
## Dependencies
* [Kaleidoscope-Ranges](Ranges.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/Steno/Steno.ino

@ -0,0 +1,104 @@
# Kaleidoscope-Syster
Syster is a way to input symbols in a different way: instead of macros, Leader
sequences or the like, we trigger the special input mode, and enter the symbol's
name. Once finished, we hit `Space`, and this plugin will do the rest: delete
everything we typed, look up an action for the entered symbol, and execute that.
There are a number of ways this can be useful, but the easiest showcase is
symbolic Unicode input: `SYSTER coffee SPACE` turns into `☕`, with just a
little code.
## Using the plugin
To use the plugin, one needs to include the header and set up a function that
will handle the symbol actions:
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-HostOS.h>
#include <Kaleidoscope-Syster.h>
#include <Kaleidoscope-Unicode.h>
#include <kaleidoscope/hid.h>
void systerAction(kaleidoscope::plugin::Syster::action_t action, const char *symbol) {
switch (action) {
case kaleidoscope::plugin::Syster::StartAction:
Unicode.type (0x2328);
break;
case kaleidoscope::plugin::Syster::EndAction:
handleKeyswitchEvent (Key_Backspace, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED);
kaleidoscope::hid::sendKeyboardReport ();
handleKeyswitchEvent (Key_Backspace, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED);
kaleidoscope::hid::sendKeyboardReport ();
break;
case kaleidoscope::plugin::Syster::SymbolAction:
Serial.print ("systerAction: symbol=");
Serial.println (symbol);
if (strcmp (symbol, "coffee") == 0) {
Unicode.type (0x2615);
}
break;
}
}
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, HostOS, Unicode, Syster);
void setup() {
Serial.begin(9600);
Kaleidoscope.setup ();
}
```
**Note** that we need to use the `Syster` object before any other that adds or
changes key behaviour! Failing to do so may result in unpredictable behaviour.
## Plugin methods
The plugin provides the `Syster` object, with no public methods. There are two
methods outside of the object, however, that can be overridden:
### `systerAction(action, symbol)`
> Called whenever an action needs to be taken, which can happen in three cases:
> First, when the `Syster` key is pressed and the alternate processing starts.
> In this case, `action` will be set to
> `kaleidoscope::plugin::Syster::StartAction`, and `symbol` will be `NULL`. This
> function can be used to do some setup to make it more obvious that the Syster
> input mode is active, such as sending a Unicode symbol to the host, or
> lighting up LEDs, or anything else we'd like.
>
> Second, when the sequence is finished with a `Space`. In this case, `action`
> will be set to `kaleidoscope::plugin::Syster::EndAction` and `symbol` will be
> `NULL`. This can be used to undo anything that the start action did, if need
> be.
>
> Third, when the action for the symbol should be made. In this case, `action`
> is set to `kaleidoscope::plugin::Syster::SymbolAction`, and `symbol` will be a
> C string. It is up to us, what we do with this information, how we handle it.
### `keyToChar(key)`
> A function that turns a keycode into a character. If using QWERTY on the host,
> the default implementation is sufficient. When using something else, you may
> have to reimplement this function.
## Dependencies
* [Kaleidoscope-Ranges](Ranges.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/Syster/Syster.ino
## Upgrading
Previous versions of `Syster` used `kaleidoscope::Syster::action_t` as the type
of Syster actions. In newer versions, this is
`kaleidoscope::plugin::Syster::action_t`. The old name still works, but will be
removed by 2019-01-14.

@ -0,0 +1,153 @@
# Kaleidoscope-TapDance
Tap-dance keys are general purpose, multi-use keys, which trigger a different
action based on the number of times they were tapped in sequence. As an example
to make this clearer, one can have a key that inputs `A` when tapped once,
inputs `B` when tapped twice, and lights up the keyboard in Christmas colors
when tapped a third time.
This behaviour is most useful in cases where we have a number of things we
perform rarely, where tapping a single key repeatedly is not counter-productive.
Such cases include - for example - multimedia forward / backward keys: forward
on single tap, backward on double. Of course, one could use modifiers to achieve
a similar effect, but that's two keys to use, this is only one. We can also hide
some destructive functionality behind a number of taps: reset the keyboard after
4 taps, and light up LEDs in increasingly frightful colors until then.
## How does it work?
To not interfere with normal typing, tap-dance keys have two ways to decide when
to call an action: they either get interrupted, or they time out. Every time a
tap-dance key is pressed, the timer resets, so one does not have to finish the
whole tapping sequence within a short time limit. The tap-dance counter
continues incrementing until one of these cases happen.
When a tap-dance key is pressed and released, and nothing is pressed on the
keyboard until the timeout is reached, then the key will time out, and trigger
an action. Which action, depends on the number of times it has been tapped up
until this point.
When a tap-dance key is pressed and released, and another key is hit before the
timer expires, then the tap-dance key will trigger an action first, perform it,
and only then will the firmware continue handling the interrupting key press.
This is to preserve the order of keys pressed.
In both of these cases, the [`tapDanceAction`][tdaction] will be called, with
`tapDanceIndex` set to the index of the tap-dance action (as set in the keymap),
the `tapCount`, and `tapDanceAction` set to either
`kaleidoscope::plugin::TapDance::Interrupt`, or
`kaleidoscope::plugin::TapDance::Timeout`. If we continue holding the key, then
as long as it is held, the same function will be called with `tapDanceAction`
set to `kaleidoscope::plugin::TapDance::Hold`. When the key is released, after
either an `Interrupt` or `Timeout` action was triggered, the function will be
called with `tapDanceAction` set to `kaleidoscope::plugin::TapDance::Release`.
These actions allow us to create sophisticated tap-dance setups, where one can
tap a key twice and hold it, and have it repeat, for example.
There is one additional value the `tapDanceAction` parameter can take:
`kaleidoscope::plugin::TapDance::Tap`. It is called with this argument for each
and every tap, even if no action is to be triggered yet. This is so that we can
have a way to do some side-effects, like light up LEDs to show progress, and so
on.
## Using the plugin
To use the plugin, we need to include the header, and declare the behaviour
used. Then, we need to place tap-dance keys on the keymap. And finally, we need
to implement the [`tapDanceAction`][tdaction] function that gets called each
time an action is to be performed.
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-TapDance.h>
// Somewhere in the keymap:
TD(0)
// later in the Sketch:
void tapDanceAction(uint8_t tap_dance_index, byte row, byte col, uint8_t tap_count,
kaleidoscope::plugin::TapDance::ActionType tap_dance_action) {
switch (tap_dance_index) {
case 0:
return tapDanceActionKeys(tap_count, tap_dance_action,
Consumer_ScanNextTrack, Consumer_ScanPreviousTrack);
}
}
KALEIDOSCOPE_INIT_PLUGINS(TapDance);
void setup() {
Kaleidoscope.setup ();
}
```
## Keymap markup
### `TD(id)`
> A key that acts as a tap-dance key. The actions performed depend on the
> implementation for the `id` index within the [`tapDanceActions`][tdactions]
> function.
>
> The `id` parameter here is what will be used as `tap_dance_index` in the
> handler function.
[tdaction]: #tapdanceactiontapdanceindex-tapcount-tapdanceaction
## Plugin methods
The plugin provides a `TapDance` object, but to implement the actions, we need
to define a function ([`tapDanceAction`][tdaction]) outside of the object. A
handler, of sorts. Nevertheless, the plugin provides one macro that is
particularly useful: `tapDanceActionKeys`. Apart from that, it provides one
property only:
### `.time_out`
> The number of loop iterations to wait before a tap-dance sequence times out.
> Once the sequence timed out, the action for it will trigger, even without an
> interruptor. Defaults to 5, and the timer resets with every tap of the same
### `tapDanceActionKeys(tap_count, tap_dance_action, keys...)`
> Sets up an action where for each subsequent tap, a different key will be
> chosen from the list of keys supplied in the `keys...` argument.
>
> If we have `Key_A` and `Key_B` in the list, then, if tapped once, this
> function will input `A`, but when tapped twice, will input `B`.
>
> When all our actions are just different keys, this is a very handy macro to
> use.
>
> The `tap_count` and `tap_dance_actions` parameters should be the same as the
> similarly named parameters of the `tapDanceAction` function.
### `tapDanceAction(tap_dance_index, row, col, tap_count, tap_dance_action)`
> The heart of the tap-dance plugin is the handler method. This is called every
> time any kind of tap-dance action is to be performed. See the
> *[How does it work?](#how-does-it-work)* section for details about when and
> how this function is called.
>
> The `tap_dance_index` and `tap_count` parameters help us choose which action
> to perform. The `row` and `col` parameters tell us where the tap-dance key is
> on the keyboard.
## Dependencies
* [Kaleidoscope-Ranges](Ranges.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/TapDance/TapDance.ino
## Upgrading
Previous versions of `TapDance` used `kaleidoscope::TapDance::ActionType` as the
type of TapDance actions. In newer versions, this is
`kaleidoscope::plugin::TapDance::ActionType`. The old name still works, but will
be removed by 2019-01-14.

@ -0,0 +1,51 @@
# Kaleidoscope-TopsyTurvy
`TopsyTurvy` is a plugin that inverts the behaviour of the `Shift` key for some
selected keys. That is, if configured so, it will input `!` when pressing the
`1` key without `Shift`, but with the modifier pressed, it will input the
original `1` symbol.
## Using the plugin
To use the plugin, one needs to include the header, mark keys to apply plugin
effects to, and use the plugin:
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-TopsyTurvy.h>
// In the keymap:
TOPSY(1), TOPSY(2), TOPSY(3)
KALEIDOSCOPE_INIT_PLUGINS(TopsyTurvy);
void setup () {
Kaleidoscope.setup ();
}
```
## Keymap markup
There is only one macro that the plugin provides, which one can use in keymap definitions:
### `TOPSY(key)`
> Mark the specified `key` (without the `Key_` prefix!) for TopsyTurvy, and swap
> the effect of `Shift` when the key is used. One can have any number of
> topsy-turvy keys on a keymap.
>
> The keys must be plain old keys, modifiers or anything other augmentation
> cannot be applied.
The plugin provides a number of macros one can use in keymap definitions:
## Plugin methods
The plugin provides the `TopsyTurvy` object, without any public methods or properties.
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/TopsyTurvy/TopsyTurvy.ino

@ -0,0 +1,35 @@
# Kaleidoscope-TriColor
The `TriColor` effect extension is a part of
the [`LEDEffects`][plugin:ledeffects] library, not a stand-alone base library of
its own. It is used to implement the effects in that library.
[plugin:ledeffects]: LEDEffects.md
It is a class that can be used to create LED effects that all follow a similar
pattern: alphas and similar in one color; modifiers, special keys, and half the
function keys in another, and `Esc` in a third (this latter being optional). If
we have a color scheme that follows this pattern, the `TriColor` extension can
make it a lot easier to implement it.
## Using the extension
Because the extension is part of the [`LEDEffects`][plugin:ledeffects] library,
we need to include that header:
```c++
#include <Kaleidoscope-LEDEffects.h>
```
Then, we simply create a new instance of the `TriColor` class, with appropriate
colors set for the constructor:
```c++
kaleidoscope::TriColor BlackAndWhiteEffect (CRGB(0x00, 0x00, 0x00),
CRGB(0xff, 0xff, 0xff),
CRGB(0x80, 0x80, 0x80));
```
The first argument is the base color, the second is for modifiers and special
keys, the last one is for the `Esc` key. If the last one is omitted, the
extension will use the modifier color for it.

@ -0,0 +1,123 @@
# Kaleidoscope-TypingBreaks
Typing on the keyboard for an extended period of time may lead to injuries,
which is why it is highly recommended to take frequent breaks from the
keyboard - and from the computer as well. But sometimes - more often than one
would wish to admit - we tend to forget about this, and plow through, at the
cost of hand's health.
No more.
With the `TypingBreaks` plugin, we can instruct the keyboard to lock itself up
after some time, or after a number of key presses. It will stay locked for a few
minutes (or whatever amount we told it to), forcing us to take a break.
## Using the plugin
The plugin comes with reasonable defaults (see below), and can be used out of
the box, without any further configuration:
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-TypingBreaks.h>
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, TypingBreaks);
void setup (void) {
Kaleidoscope.setup ();
TypingBreaks.settings.idle_time_limit = 60;
}
```
## Plugin methods
The plugin provides a single object, `TypingBreaks`, with the following
properties. All times are in seconds.
### `.settings.idle_time_limit`
> The amount of time that can pass between two pressed keys, before the plugin
> considers it a new session, and starts all timers and counters over.
>
> Defaults to 300 seconds (5 minutes).
### `.settings.lock_time_out`
> The length of the session, after which the keyboard will be locked.
>
> Defaults to 2700 seconds (45 minutes).
### `.settings.lock_length`
> The length until the keyboard lock is held. Any key pressed while the lock is
> active, will be discarded.
>
> Defaults to 300 seconds (5 minutes).
### `.settings.left_hand_max_keys`
> It is possible to lock the keyboard after a number of keys pressed, too. If
> this happens sooner than the timeout, the keyboard will still be locked.
>
> This property controls how many keys can be pressed on the left side.
>
> Defaults to 0 (off).
### `.settings.right_hand_max_keys`
> It is possible to lock the keyboard after a number of keys pressed, too. If
> this happens sooner than the timeout, the keyboard will still be locked.
>
> This property controls how many keys can be pressed on the right side.
>
> Defaults to 0 (off).
## Focus commands
### `typingbreaks.idleTimeLimit [limit]`
> Get or set the `.settings.idle_time_limit` property.
### `typingbreaks.lockTimeOut [time_out]`
> Get or set the `.settings.lock_time_out` property.
### `typingbreaks.lockLength [length]`
> Get or set the `.settings.lock_length` property.
### `typingbreaks.leftMaxKeys [max]`
> Get or set the `.settings.left_hand_max_keys` property.
### `typingbreaks.rightMaxKeys [max]`
> Get or set the `.settings.right_hand_max_keys` property.
## Dependencies
* [Kaleidoscope-EEPROM-Settings](EEPROM-Settings.md)
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/TypingBreaks/TypingBreaks.ino
## Upgrading
Older versions of the plugin used to provide EEPROM storage for the settings
only optionally, when it was explicitly enabled via the
`TypingBreaks.enableEEPROM()` method. Similarly, the Focus hooks were optional
too.
Both of them are unconditionally enabled now, because they add so much to the
plugin. This means that any calls to `TypingBreaks.enableEEPROM()` can be safely
removed, the method is a no-op by now.
Storing the settable settings in EEPROM makes it depend on
`Kaleidoscope-EEPROM-Settings`, which should be initialized before this plugin
is.

@ -0,0 +1,116 @@
# Kaleidoscope-Unicode
The `Unicode` extension makes it easier to write plugins that input Unicode
symbols on the host. Because inputting Unicode varies from OS to OS, this helper
library was made to hide most of the differences. All one has to do, is set up
the `HostOS` singleton properly, and the `Unicode` library will handle the rest,
by providing an easy interface for inputting Unicode symbols by their 32-bit
codepoints.
## Using the extension
Using the extension is as simple as including the header, registering it with
`Kaleidoscope.use()`, and then using any of the methods provided by the
`Unicode` singleton object.
```c++
#include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-HostOS.h>
#include <Kaleidoscope-Unicode.h>
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, HostOS, Unicode);
void setup() {
Kaleidoscope.setup();
Unicode.type(0x2328);
}
```
## Extension methods
The extension provides a number of methods on the `Unicode` object, but also has
symbols that can be [overridden](#overrideable-methods), to add custom
functionality.
### `.type(code_point)`
> Starts the Unicode input method using the [`.start()`](#start) method, inputs
> the `code_point` using [`.typeCode()`](#typeCode), and finishes up with
> the [`.end()`](#end) method. For each hexadecimal digit sent to the host,
> the [`.input()`](#input) method will also be called.
>
> This method is most useful when one knows the code point of the Unicode symbol
> to enter ahead of time, when the code point does not depend on anything else.
### `.typeCode(code_point)`
> Inputs the hex codes for `code_point`, and the hex codes only. Use when the
> input method is to be started and ended separately.
>
> For example, a macro that starts Unicode input, and switches to a layer full
> of macros that send the hex codes is one scenario where this function is of
> use.
### `.start()`
> Starts the Unicode input method. The way it starts it, depends on the host
> operating system.
### `.input()`
> If the host operating system requires keys being held during the Unicode
> input, this function will hold them for us.
### `.end()`
> Finishes the Unicode input method, in an OS-specific way.
## Overrideable methods
### `hexToKey(hex_digit)`
> A function that returns a `Key` struct, given a 8-bit hex digit. For most
> uses, the built-in version of this function is sufficient, but if the keymap
> on the OS-side has any of the hexadecimal symbols on other scancodes than
> QWERTY, this function should be overridden to use the correct scan codes.
### `unicodeCustomStart()`
> If the host OS type is set to `kaleidoscope::hostos::Custom`, then this function will
> be called whenever the [`.start()`](#start) method is called. The default
> implementation does nothing, and should be overridden to implement the custom
> magic needed to enter unicode input mode.
### `unicodeCustomInput()`
> If the host OS type is set to `kaleidoscope::hostos::Custom`, then this function will
> be called whenever the [`.input()`](#input) method is called. The default
> implementation does nothing, and should be overridden to implement the custom
> magic needed while inputting the hex code itself (such as holding additional
> keys).
### `unicodeCustomEnd()`
> If the host OS type is set to `kaleidoscope::hostos::Custom`, then this function will
> be called whenever the [`.end()`](#end) method is called. The default
> implementation does nothing, and should be overridden to implement the custom
> magic needed to leave unicode input mode.
## Dependencies
* [Kaleidoscope-HostOS](HostOS.md)
## Other Configuration
On OS X/macOS, you'll need to change the input method to be "Unicode Hex Input".
You can do this by going to System Preferences > Keyboard > Input Sources, clicking
the `+` button, selecting it from the list, then setting it as the active input method.
## Further reading
Starting from the [example][plugin:example] is the recommended way of getting
started with the plugin.
[plugin:example]: ../../examples/Unicode/Unicode.ino

@ -0,0 +1,60 @@
/* -*- mode: c++ -*-
* Kaleidoscope-EEPROM-Colormap -- Per-layer colormap effect
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-Colormap.h>
#include <Kaleidoscope-FocusSerial.h>
#include <Kaleidoscope-LED-Palette-Theme.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_NoKey,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_NoKey),
};
// *INDENT-ON*
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings,
LEDPaletteTheme,
ColormapEffect,
Focus);
void setup() {
Kaleidoscope.setup();
ColormapEffect.max_layers(1);
ColormapEffect.activate();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,61 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Cycle -- Key sequence cycling dead key for Kaleidoscope.
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-Cycle.h>
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_Cycle,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_Cycle),
};
void cycleAction(Key previous_key, uint8_t cycle_count) {
if (previous_key.raw == Key_E.raw) {
if (cycle_count == 1) {
Cycle.replace(Key_F);
} else if (cycle_count == 2) {
Cycle.replace(Key_G);
}
}
if (previous_key.raw == Key_A.raw) {
cycleThrough(Key_A, Key_B, Key_C, Key_D);
}
}
KALEIDOSCOPE_INIT_PLUGINS(Cycle);
void setup() {
Kaleidoscope.setup();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,50 @@
/* -*- mode: c++ -*-
* Kaleidoscope-CycleTimeReport -- Scan cycle time reporting
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-CycleTimeReport.h>
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_skip,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_skip),
};
KALEIDOSCOPE_INIT_PLUGINS(CycleTimeReport);
void setup() {
Serial.begin(9600);
Kaleidoscope.setup();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,71 @@
/* -*- mode: c++ -*-
* Kaleidoscope-EEPROM-Keymap-Programmer -- On-the-fly reprogrammable keymap.
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-EEPROM-Keymap.h>
#include <Kaleidoscope-EEPROM-Keymap-Programmer.h>
#include <Kaleidoscope-Macros.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(M(0), Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_NoKey,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_NoKey),
};
// *INDENT-ON*
const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {
if (macroIndex == 0 && keyToggledOff(keyState)) {
EEPROMKeymapProgrammer.activate();
}
return MACRO_NONE;
}
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings,
EEPROMKeymapProgrammer,
EEPROMKeymap,
Macros);
void setup() {
Serial.begin(9600);
Kaleidoscope.setup();
Layer.getKey = EEPROMKeymap.getKey;
EEPROMKeymap.max_layers(1);
EEPROMSettings.seal();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,73 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Escape-OneShot -- Turn ESC into a key that cancels OneShots, if active.
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-OneShot.h>
#include <Kaleidoscope-Escape-OneShot.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
OSM(LeftControl), Key_Backspace, OSM(LeftGui), Key_LeftShift,
Key_Keymap1_Momentary,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, OSM(RightAlt), Key_Spacebar, OSM(RightControl),
OSL(1)
),
[1] = KEYMAP_STACKED
(
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___,
___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
Key_UpArrow, Key_DownArrow, Key_LeftArrow, Key_RightArrow, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___,
___
),
};
// *INDENT-ON*
KALEIDOSCOPE_INIT_PLUGINS(OneShot,
EscapeOneShot);
void setup() {
Kaleidoscope.setup();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,65 @@
/* -*- mode: c++ -*-
* Kaleidoscope-FingerPainter -- On-the-fly keyboard painting.
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-LEDControl.h>
#include <Kaleidoscope-LED-Palette-Theme.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-FingerPainter.h>
#include <Kaleidoscope-FocusSerial.h>
#include "LED-Off.h"
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_skip,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_skip),
};
// *INDENT-ON*
KALEIDOSCOPE_INIT_PLUGINS(LEDControl,
LEDOff,
EEPROMSettings,
LEDPaletteTheme,
FingerPainter,
Focus);
void setup() {
Kaleidoscope.setup();
EEPROMSettings.seal();
FingerPainter.activate();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,145 @@
/* -*- mode: c++ -*-
* Kaleidoscope-GhostInTheFirmware -- Let the keyboard write for you!
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-GhostInTheFirmware.h>
#include <Kaleidoscope-LED-Stalker.h>
#include <Kaleidoscope-Macros.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(___, ___, ___, ___, ___, ___, M(0),
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___,
___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___,
___),
};
// *INDENT-ON*
class EventDropper_ : public kaleidoscope::Plugin {
public:
EventDropper_() {}
kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) {
return kaleidoscope::EventHandlerResult::EVENT_CONSUMED;
}
};
static EventDropper_ EventDropper;
const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) {
if (macro_index == 0 && keyToggledOn(key_state))
GhostInTheFirmware.activate();
return MACRO_NONE;
}
static const kaleidoscope::plugin::GhostInTheFirmware::GhostKey ghost_keys[] PROGMEM = {
{0, 6, 200, 50},
{0, 5, 200, 50},
{0, 4, 200, 50},
{0, 3, 200, 50},
{0, 2, 200, 50},
{0, 1, 200, 50},
{0, 0, 200, 50},
{1, 0, 200, 50},
{1, 1, 200, 50},
{1, 2, 200, 50},
{1, 3, 200, 50},
{1, 4, 200, 50},
{1, 5, 200, 50},
{1, 6, 200, 50},
{2, 6, 200, 50},
{2, 5, 200, 50},
{2, 4, 200, 50},
{2, 3, 200, 50},
{2, 2, 200, 50},
{2, 1, 200, 50},
{2, 0, 200, 50},
{3, 0, 200, 50},
{3, 1, 200, 50},
{3, 3, 200, 50},
{3, 4, 200, 50},
{3, 5, 200, 50},
{0, 7, 200, 50},
{1, 7, 200, 50},
{2, 7, 200, 50},
{3, 7, 200, 50},
{3, 6, 200, 50},
{3, 9, 200, 50},
{3, 8, 200, 50},
{2, 8, 200, 50},
{1, 8, 200, 50},
{0, 8, 200, 50},
{3, 10, 200, 50},
{3, 11, 200, 50},
{3, 12, 200, 50},
{3, 13, 200, 50},
{3, 14, 200, 50},
{3, 15, 200, 50},
{2, 15, 200, 50},
{2, 14, 200, 50},
{2, 13, 200, 50},
{2, 12, 200, 50},
{2, 11, 200, 50},
{2, 10, 200, 50},
{2, 9, 200, 50},
{1, 9, 200, 50},
{1, 10, 200, 50},
{1, 11, 200, 50},
{1, 12, 200, 50},
{1, 13, 200, 50},
{1, 14, 200, 50},
{1, 15, 200, 50},
{0, 15, 200, 50},
{0, 14, 200, 50},
{0, 13, 200, 50},
{0, 12, 200, 50},
{0, 11, 200, 50},
{0, 10, 200, 50},
{0, 9, 200, 50},
{0, 0, 0, 0}
};
KALEIDOSCOPE_INIT_PLUGINS(GhostInTheFirmware,
StalkerEffect,
Macros,
EventDropper);
void setup() {
Kaleidoscope.setup();
StalkerEffect.variant = STALKER(BlazingTrail);
GhostInTheFirmware.ghost_keys = ghost_keys;
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,55 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Heatmap -- Heatmap LED effect for Kaleidoscope.
* Copyright (C) 2016, 2017, 2018 Gergely Nagy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-LEDControl.h>
#include <Kaleidoscope-Heatmap.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_NoKey,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_NoKey),
};
// *INDENT-ON*
KALEIDOSCOPE_INIT_PLUGINS(LEDControl,
HeatmapEffect);
void setup() {
Kaleidoscope.setup();
HeatmapEffect.activate();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,56 @@
/* -*- mode: c++ -*-
* Kaleidoscope-HostOS -- Host OS detection and tracking for Kaleidoscope
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-HostOS.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_skip,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_skip),
};
// *INDENT-ON*
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, HostOS);
void setup() {
Serial.begin(9600);
Kaleidoscope.setup();
Serial.print("Host OS id is: ");
Serial.println(HostOS.os(), DEC);
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,53 @@
/* -*- mode: c++ -*-
* Kaleidoscope-LED-ActiveModColor -- Light up the LEDs under the active modifiers
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-LEDControl.h>
#include <Kaleidoscope-LED-ActiveModColor.h>
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_skip,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_skip),
};
KALEIDOSCOPE_INIT_PLUGINS(LEDControl,
ActiveModColorEffect);
void setup() {
Kaleidoscope.setup();
ActiveModColorEffect.highlight_color = CRGB(0x00, 0xff, 0xff);
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,92 @@
/* -*- mode: c++ -*-
* Kaleidoscope-LED-Palette-Theme -- Palette-based LED theme foundation
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-LEDControl.h>
#include <Kaleidoscope-LED-Palette-Theme.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-FocusSerial.h>
namespace example {
class TestLEDMode : public kaleidoscope::LEDMode {
public:
TestLEDMode() {}
kaleidoscope::EventHandlerResult onFocusEvent(const char *command);
protected:
void setup() final;
void update(void) final;
private:
static uint16_t map_base_;
};
uint16_t TestLEDMode::map_base_;
void
TestLEDMode::setup() {
map_base_ = LEDPaletteTheme.reserveThemes(1);
}
void
TestLEDMode::update(void) {
LEDPaletteTheme.updateHandler(map_base_, 0);
}
kaleidoscope::EventHandlerResult
TestLEDMode::onFocusEvent(const char *command) {
return LEDPaletteTheme.themeFocusEvent(command, PSTR("testLedMode.map"), map_base_, 1);
}
}
example::TestLEDMode TestLEDMode;
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_NoKey,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_NoKey),
};
// *INDENT-ON*
KALEIDOSCOPE_INIT_PLUGINS(Focus, LEDPaletteTheme, TestLEDMode, EEPROMSettings);
void setup() {
Kaleidoscope.setup();
TestLEDMode.activate();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,59 @@
/* -*- mode: c++ -*-
* Kaleidoscope-LEDEffects -- An assorted collection of LED effects for Kaleidoscope
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-LEDEffects.h>
#include "LED-Off.h"
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_LEDEffectNext, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_NoKey,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_NoKey),
};
// *INDENT-ON*
KALEIDOSCOPE_INIT_PLUGINS(LEDControl,
LEDOff,
MiamiEffect,
JukeboxEffect,
JukeboxAlternateEffect);
void setup() {
Kaleidoscope.setup();
MiamiEffect.activate();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,64 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Leader -- VIM-style leader keys
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-Leader.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
LEAD(0),
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
LEAD(0)),
};
// *INDENT-ON*
static void leaderTestA(uint8_t seq_index) {
Serial.println(F("leaderTestA"));
}
static void leaderTestAA(uint8_t seq_index) {
Serial.println(F("leaderTestAA"));
}
static const kaleidoscope::plugin::Leader::dictionary_t leader_dictionary[] PROGMEM =
LEADER_DICT({LEADER_SEQ(LEAD(0), Key_A), leaderTestA},
{LEADER_SEQ(LEAD(0), Key_A, Key_A), leaderTestAA});
KALEIDOSCOPE_INIT_PLUGINS(Leader);
void setup() {
Kaleidoscope.setup();
Leader.dictionary = leader_dictionary;
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,88 @@
/* -*- mode: c++ -*-
* Kaleidoscope-OneShot -- One-shot modifiers and layers
* Copyright (C) 2016-2018 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-Macros.h>
#include <Kaleidoscope-OneShot.h>
// Macros
enum {
OSMALTCTRL,
};
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
OSM(LeftControl), Key_Backspace, OSM(LeftGui), OSM(LeftShift),
M(OSMALTCTRL),
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
OSM(RightShift), OSM(RightAlt), Key_Spacebar, OSM(RightControl),
OSL(1)),
[1] = KEYMAP_STACKED
(
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___,
___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___, ___,
Key_UpArrow, Key_DownArrow, Key_LeftArrow, Key_RightArrow,___, ___,
___, ___, ___, ___, ___, ___, ___,
___, ___, ___, ___,
___),
};
// *INDENT-ON*
void macroOneShotAltControl(uint8_t keyState) {
OneShot.inject(OSM(LeftAlt), keyState);
OneShot.inject(OSM(LeftControl), keyState);
}
const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {
if (macroIndex == OSMALTCTRL) {
macroOneShotAltControl(keyState);
}
return MACRO_NONE;
}
KALEIDOSCOPE_INIT_PLUGINS(OneShot, Macros);
void setup() {
Kaleidoscope.setup();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,81 @@
// -*- mode: c++ -*-
#include <Kaleidoscope.h>
#include <Kaleidoscope-Qukeys.h>
#include <Kaleidoscope-Macros.h>
enum { MACRO_TOGGLE_QUKEYS };
// *INDENT-OFF*
KEYMAPS(
[0] = KEYMAP_STACKED
(
Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_Q,
M(MACRO_TOGGLE_QUKEYS), Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, SFT_T(J), CTL_T(K), ALT_T(L), GUI_T(Semicolon), Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
LT(1,E)
),
[1] = KEYMAP_STACKED
(
___, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G,
Key_A, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G,
Key_A, Key_B, Key_C, Key_D, Key_E, Key_F,
Key_A, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G,
Key_1, Key_2, Key_3, Key_4,
___,
___, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G,
Key_A, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G,
Key_A, Key_B, Key_C, Key_D, Key_E, Key_F,
Key_A, Key_B, Key_C, Key_D, Key_E, Key_F, Key_G,
Key_1, Key_2, Key_3, Key_4,
___
),
)
// *INDENT-ON*
// Defining a macro (on the "any" key: see above) to toggle Qukeys on and off
const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) {
switch (macro_index) {
case MACRO_TOGGLE_QUKEYS:
if (keyToggledOn(key_state))
Qukeys.toggle();
break;
}
return MACRO_NONE;
}
// Use Qukeys
KALEIDOSCOPE_INIT_PLUGINS(Qukeys, Macros);
void setup() {
QUKEYS(
kaleidoscope::plugin::Qukey(0, 2, 1, Key_LeftGui), // A/cmd
kaleidoscope::plugin::Qukey(0, 2, 2, Key_LeftAlt), // S/alt
kaleidoscope::plugin::Qukey(0, 2, 3, Key_LeftControl), // D/ctrl
kaleidoscope::plugin::Qukey(0, 2, 4, Key_LeftShift), // F/shift
kaleidoscope::plugin::Qukey(0, 3, 6, ShiftToLayer(1)) // Q/layer-shift (on `fn`)
)
Qukeys.setTimeout(200);
Qukeys.setReleaseDelay(20);
Kaleidoscope.setup();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,66 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Redial -- Redial support for Kaleidoscope
* Copyright (C) 2018 Gergely Nagy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-Redial.h>
#include <Kaleidoscope-Ranges.h>
enum {
REDIAL = kaleidoscope::ranges::SAFE_START,
};
#define Key_Redial (Key) {.raw = REDIAL}
bool kaleidoscope::plugin::Redial::shouldRemember(Key mapped_key) {
if (mapped_key >= Key_A && mapped_key <= Key_Z)
return true;
return false;
}
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_Redial,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_Redial),
};
// *INDENT-ON*
KALEIDOSCOPE_INIT_PLUGINS(Redial);
void setup() {
Kaleidoscope.setup();
Redial.key = Key_Redial;
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,59 @@
/* -*- mode: c++ -*-
* Kaleidoscope-ShapeShifter -- Change the shifted symbols on any key of your choice
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-ShapeShifter.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_skip, Key_1, Key_2, Key_3, Key_4, Key_5, Key_skip,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_NoKey,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_NoKey),
};
// *INDENT-ON*
static const kaleidoscope::plugin::ShapeShifter::dictionary_t shape_shift_dictionary[] PROGMEM = {
{Key_1, Key_2},
{Key_2, Key_1},
{Key_NoKey, Key_NoKey},
};
KALEIDOSCOPE_INIT_PLUGINS(ShapeShifter);
void setup() {
Kaleidoscope.setup();
ShapeShifter.dictionary = shape_shift_dictionary;
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,67 @@
/* -*- mode: c++ -*-
* Kaleidoscope-SpaceCadet -- Space Cadet Shift
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-SpaceCadet.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_SpaceCadetEnable,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_skip,
Key_SpaceCadetDisable, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_skip),
};
// *INDENT-ON*
KALEIDOSCOPE_INIT_PLUGINS(SpaceCadet);
void setup() {
Kaleidoscope.setup();
//Set the SpaceCadet map
//Setting is {KeyThatWasPressed, AlternativeKeyToSend, TimeoutInMS}
//Note: must end with the SPACECADET_MAP_END delimiter
static kaleidoscope::plugin::SpaceCadet::KeyBinding spacecadetmap[] = {
{Key_LeftShift, Key_LeftParen, 250}
, {Key_RightShift, Key_RightParen, 250}
, {Key_LeftGui, Key_LeftCurlyBracket, 250}
, {Key_RightAlt, Key_RightCurlyBracket, 250}
, {Key_LeftAlt, Key_RightCurlyBracket, 250}
, {Key_LeftControl, Key_LeftBracket, 250}
, {Key_RightControl, Key_RightBracket, 250}
, SPACECADET_MAP_END
};
//Set the map.
SpaceCadet.map = spacecadetmap;
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,70 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Steno -- Steno protocols for Kaleidoscope
* Copyright (C) 2017 Joseph Wasson
* Copyright (C) 2017, 2018 Gergely Nagy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-Steno.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_Keymap1,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_Keymap1),
[1] = KEYMAP_STACKED
(XXX, XXX, XXX, XXX, XXX, XXX, S(N6),
XXX, S(N1), S(N2), S(N3), S(N4), S(N5), S(ST1),
S(FN), S(S1), S(TL), S(PL), S(HL), S(ST1),
S(PWR), S(S2), S(KL), S(WL), S(RL), S(ST2), S(ST2),
S(RE1), XXX, S(A), S(O),
___,
S(N7), XXX, XXX, XXX, XXX, XXX, XXX,
S(ST3), S(N8), S(N9), S(NA), S(NB), S(NC), XXX,
S(ST3), S(FR), S(PR), S(LR), S(TR), S(DR),
S(ST4), S(ST4), S(RR), S(BR), S(GR), S(SR), S(ZR),
S(E), S(U), XXX, S(RE2),
___),
};
// *INDENT-ON*
KALEIDOSCOPE_INIT_PLUGINS(GeminiPR);
void setup() {
Serial.begin(9600);
Kaleidoscope.setup();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,79 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Syster -- Symbolic input system
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-HostOS.h>
#include <Kaleidoscope-Syster.h>
#include <Kaleidoscope-Unicode.h>
#include <kaleidoscope/hid.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
SYSTER,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
SYSTER),
};
// *INDENT-ON*
void systerAction(kaleidoscope::plugin::Syster::action_t action, const char *symbol) {
switch (action) {
case kaleidoscope::plugin::Syster::StartAction:
Unicode.type(0x2328);
break;
case kaleidoscope::plugin::Syster::EndAction:
handleKeyswitchEvent(Key_Backspace, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED);
kaleidoscope::hid::sendKeyboardReport();
handleKeyswitchEvent(Key_Backspace, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED);
kaleidoscope::hid::sendKeyboardReport();
break;
case kaleidoscope::plugin::Syster::SymbolAction:
Serial.print("systerAction: symbol=");
Serial.println(symbol);
if (strcmp(symbol, "coffee") == 0) {
Unicode.type(0x2615);
}
break;
}
}
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings,
HostOS,
Unicode,
Syster);
void setup() {
Kaleidoscope.setup();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,64 @@
/* -*- mode: c++ -*-
* Kaleidoscope-TapDance -- Tap-dance keys
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-TapDance.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
TD(0),
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
TD(1)),
};
// *INDENT-ON*
static void tapDanceEsc(uint8_t tap_dance_index, uint8_t tap_count, kaleidoscope::TapDance::ActionType tap_dance_action) {
tapDanceActionKeys(tap_count, tap_dance_action, Key_Escape, Key_Tab);
}
void tapDanceAction(uint8_t tap_dance_index, byte row, byte col, uint8_t tap_count, kaleidoscope::TapDance::ActionType tap_dance_action) {
switch (tap_dance_index) {
case 0:
return tapDanceActionKeys(tap_count, tap_dance_action, Key_Tab, Key_Escape);
case 1:
return tapDanceEsc(tap_dance_index, tap_count, tap_dance_action);
}
}
KALEIDOSCOPE_INIT_PLUGINS(TapDance);
void setup() {
Kaleidoscope.setup();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,51 @@
/* -*- mode: c++ -*-
* Kaleidoscope-TopsyTurvy -- Turn the effect of Shift upside down for certain keys
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-TopsyTurvy.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_NoKey, TOPSY(1), TOPSY(2), TOPSY(3), TOPSY(4), TOPSY(5), Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_skip,
Key_skip, TOPSY(6), TOPSY(7), TOPSY(8), TOPSY(9), TOPSY(0), Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_skip),
};
// *INDENT-ON*
KALEIDOSCOPE_INIT_PLUGINS(TopsyTurvy);
void setup() {
Kaleidoscope.setup();
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,54 @@
/* -*- mode: c++ -*-
* Kaleidoscope-TypingBreaks -- Enforced typing breaks
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-TypingBreaks.h>
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_skip,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_skip),
};
// *INDENT-ON*
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, TypingBreaks);
void setup() {
Kaleidoscope.setup();
TypingBreaks.settings.idle_time_limit = 60;
}
void loop() {
Kaleidoscope.loop();
}

@ -0,0 +1,76 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Unicode -- Unicode input helpers
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-HostOS.h>
#include "Kaleidoscope-Macros.h"
#include <Kaleidoscope-Unicode.h>
enum { MACRO_KEYBOARD_EMOJI };
// *INDENT-OFF*
const Key keymaps[][ROWS][COLS] PROGMEM = {
[0] = KEYMAP_STACKED
(
Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
Key_skip,
M(MACRO_KEYBOARD_EMOJI), Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
Key_skip),
};
// *INDENT-ON*
static void unicode(uint32_t character, uint8_t keyState) {
if (keyToggledOn(keyState)) {
Unicode.type(character);
}
}
const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {
switch (macroIndex) {
case MACRO_KEYBOARD_EMOJI:
unicode(0x2328, keyState);
break;
}
return MACRO_NONE;
}
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings,
HostOS,
Macros,
Unicode);
void setup() {
Kaleidoscope.setup();
}
void loop() {
Kaleidoscope.loop();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Colormap -- Per-layer colormap effect
* Copyright (C) 2016, 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/Colormap.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Cycle -- Key sequence cycling dead key for Kaleidoscope.
* Copyright (C) 2016, 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/Cycle.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-CycleTimeReport -- Scan cycle time reporting
* Copyright (C) 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/CycleTimeReport.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-EEPROM-Keymap-Programmer -- On-the-fly reprogrammable keymap.
* Copyright (C) 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/EEPROM-Keymap-Programmer.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Escape-OneShot -- Turn ESC into a key that cancels OneShots, if active.
* Copyright (C) 2016, 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/Escape-OneShot.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-FingerPainter -- On-the-fly keyboard painting.
* Copyright (C) 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/FingerPainter.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-GhostInTheFirmware -- Let the keyboard write for you!
* Copyright (C) 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/GhostInTheFirmware.h>

@ -0,0 +1,21 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Heatmap -- Heatmap LED effect for Kaleidoscope.
* Copyright (C) 2016, 2017 Gergely Nagy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/Heatmap.h>

@ -0,0 +1,21 @@
/* -*- mode: c++ -*-
* Kaleidoscope-HostOS -- Host OS detection and tracking for Kaleidoscope
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/HostOS.h>
#include <kaleidoscope/plugin/HostOS-Focus.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-LED-ActiveModColor -- Light up the LEDs under the active modifiers
* Copyright (C) 2016, 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/LED-ActiveModColor.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-LED-Palette-Theme -- Palette-based LED theme foundation
* Copyright (C) 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/LED-Palette-Theme.h>

@ -0,0 +1,22 @@
/* -*- mode: c++ -*-
* Kaleidoscope-LEDEffects -- An assorted collection of LED effects for Kaleidoscope
* Copyright (C) 2016, 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/TriColor.h>
#include <kaleidoscope/plugin/Miami.h>
#include <kaleidoscope/plugin/Jukebox.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Leader -- VIM-style leader keys
* Copyright (C) 2016, 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/Leader.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-OneShot -- One-shot modifiers and layers
* Copyright (C) 2016-2018 Keyboard.io, Inc.
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/OneShot.h>

@ -0,0 +1,21 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Qukeys -- Assign two keycodes to a single key
* Copyright (C) 2017 Michael Richters
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/Qukeys.h>

@ -0,0 +1,56 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Ranges -- Common ranges, used by a number of Kaleidoscope plugins.
* Copyright (C) 2016, 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
namespace kaleidoscope {
namespace ranges {
enum : uint16_t {
FIRST = 0xc000,
KALEIDOSCOPE_FIRST = FIRST,
OS_FIRST,
OSM_FIRST = OS_FIRST,
OSM_LAST = OSM_FIRST + 7,
OSL_FIRST,
OSL_LAST = OSL_FIRST + 7,
OS_LAST = OSL_LAST,
DU_FIRST,
DUM_FIRST = DU_FIRST,
DUM_LAST = DUM_FIRST + (8 << 8),
DUL_FIRST,
DUL_LAST = DUL_FIRST + (8 << 8),
DU_LAST = DUL_LAST,
TD_FIRST,
TD_LAST = TD_FIRST + 15,
LEAD_FIRST,
LEAD_LAST = LEAD_FIRST + 7,
CYCLE,
SYSTER,
TT_FIRST,
TT_LAST = TT_FIRST + 255,
STENO_FIRST,
STENO_LAST = STENO_FIRST + 42,
SC_FIRST,
SC_LAST,
SAFE_START,
KALEIDOSCOPE_SAFE_START = SAFE_START
};
}
}

@ -0,0 +1,21 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Redial -- Redial support for Kaleidoscope
* Copyright (C) 2018 Gergely Nagy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/Redial.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-ShapeShifter -- Change the shifted symbols on any key of your choice
* Copyright (C) 2016, 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/ShapeShifter.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-SpaceCadet -- Space Cadet Shift
* Copyright (C) 2016, 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/SpaceCadet.h>

@ -0,0 +1,21 @@
/* Kaleidoscope-Steno -- Steno protocols for Kaleidoscope
* Copyright (C) 2017 Joseph Wasson
* Copyright (C) 2017 Gergely Nagy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/GeminiPR.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Syster -- Symbolic input system
* Copyright (C) 2016, 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/Syster.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-TapDance -- Tap-dance keys
* Copyright (C) 2016, 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/TapDance.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-TopsyTurvy -- Turn the effect of Shift upside down for certain keys
* Copyright (C) 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/TopsyTurvy.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-TypingBreaks -- Enforced typing breaks
* Copyright (C) 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/TypingBreaks.h>

@ -0,0 +1,20 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Unicode -- Unicode input helpers
* Copyright (C) 2016, 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <kaleidoscope/plugin/Unicode.h>

@ -0,0 +1,44 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Qukeys -- Assign two keycodes to a single key
* Copyright (C) 2017 Michael Richters
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Kaleidoscope.h>
// Helper functions for converting between separate (row,col)
// coordinates and a single-byte key number (addr). This works as long
// as the keyboard has fewer than 256 keys.
namespace kaleidoscope {
namespace addr {
inline uint8_t row(uint8_t key_addr) {
return (key_addr / COLS);
}
inline uint8_t col(uint8_t key_addr) {
return (key_addr % COLS);
}
inline uint8_t addr(uint8_t row, uint8_t col) {
return ((row * COLS) + col);
}
inline void mask(uint8_t key_addr) {
KeyboardHardware.maskKey(row(key_addr), col(key_addr));
}
inline void unmask(uint8_t key_addr) {
KeyboardHardware.unMaskKey(row(key_addr), col(key_addr));
}
} // namespace addr {
} // namespace kaleidoscope {

@ -0,0 +1,67 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Colormap -- Per-layer colormap effect
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope-Colormap.h>
#include <EEPROM.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-FocusSerial.h>
namespace kaleidoscope {
namespace plugin {
uint16_t ColormapEffect::map_base_;
uint8_t ColormapEffect::max_layers_;
uint8_t ColormapEffect::last_highest_layer_;
void ColormapEffect::max_layers(uint8_t max_) {
if (map_base_ != 0)
return;
max_layers_ = max_;
map_base_ = ::LEDPaletteTheme.reserveThemes(max_layers_);
}
void ColormapEffect::onActivate(void) {
last_highest_layer_ = Layer.top();
if (last_highest_layer_ <= max_layers_)
::LEDPaletteTheme.updateHandler(map_base_, last_highest_layer_);
}
void ColormapEffect::update(void) {
if (Layer.top() == last_highest_layer_)
return;
onActivate();
}
void ColormapEffect::refreshAt(byte row, byte col) {
if (last_highest_layer_ <= max_layers_)
::LEDPaletteTheme.refreshAt(map_base_, last_highest_layer_, row, col);
}
EventHandlerResult ColormapEffect::onFocusEvent(const char *command) {
return ::LEDPaletteTheme.themeFocusEvent(command, PSTR("colormap.map"),
map_base_, max_layers_);
}
}
}
kaleidoscope::plugin::ColormapEffect ColormapEffect;

@ -0,0 +1,46 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Colormap -- Per-layer colormap effect
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Kaleidoscope-LEDControl.h>
#include <Kaleidoscope-LED-Palette-Theme.h>
namespace kaleidoscope {
namespace plugin {
class ColormapEffect : public LEDMode {
public:
ColormapEffect(void) {}
void max_layers(uint8_t max_);
EventHandlerResult onFocusEvent(const char *command);
protected:
void onActivate(void) final;
void update(void) final;
void refreshAt(byte row, byte col) final;
private:
static uint8_t last_highest_layer_;
static uint8_t max_layers_;
static uint16_t map_base_;
};
}
}
extern kaleidoscope::plugin::ColormapEffect ColormapEffect;

@ -0,0 +1,91 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Cycle -- Key sequence cycling dead key for Kaleidoscope.
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-Cycle.h>
#include "kaleidoscope/hid.h"
namespace kaleidoscope {
namespace plugin {
// --- state ---
Key Cycle::last_non_cycle_key_;
uint8_t Cycle::cycle_count_;
// --- helpers ---
#define isCycle(k) (k.raw == kaleidoscope::ranges::CYCLE)
// --- api ---
void Cycle::replace(Key key) {
handleKeyswitchEvent(Key_Backspace, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED);
hid::sendKeyboardReport();
handleKeyswitchEvent(Key_Backspace, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED);
hid::sendKeyboardReport();
handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED);
hid::sendKeyboardReport();
handleKeyswitchEvent(key, UNKNOWN_KEYSWITCH_LOCATION, WAS_PRESSED | INJECTED);
hid::sendKeyboardReport();
}
void Cycle::replace(uint8_t cycle_size, const Key cycle_steps[]) {
uint8_t idx = cycle_count_ % cycle_size;
Key key;
key.raw = pgm_read_word(cycle_steps + idx);
replace(key);
}
// --- hooks ---
EventHandlerResult Cycle::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) {
if (key_state & INJECTED)
return EventHandlerResult::OK;
if (!keyIsPressed(key_state) && !keyWasPressed(key_state)) {
if (isCycle(mapped_key)) {
return EventHandlerResult::EVENT_CONSUMED;
}
return EventHandlerResult::OK;
}
if (!isCycle(mapped_key)) {
if (keyToggledOn(key_state)) {
last_non_cycle_key_.raw = mapped_key.raw;
cycle_count_ = 0;
}
return EventHandlerResult::OK;
}
if (!keyToggledOff(key_state)) {
return EventHandlerResult::EVENT_CONSUMED;
}
++cycle_count_;
cycleAction(last_non_cycle_key_, cycle_count_);
return EventHandlerResult::EVENT_CONSUMED;
}
}
}
__attribute__((weak))
void cycleAction(Key previous_key, uint8_t cycle_count) {
}
kaleidoscope::plugin::Cycle Cycle;

@ -0,0 +1,50 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Cycle -- Key sequence cycling dead key for Kaleidoscope.
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Kaleidoscope.h>
#include <Kaleidoscope-Ranges.h>
#define Key_Cycle ((Key) { .raw = kaleidoscope::ranges::CYCLE })
#define cycleThrough(...) ({ \
static const Key __k[] PROGMEM = { __VA_ARGS__ }; \
Cycle.replace(sizeof(__k) / sizeof(Key), &__k[0]); \
})
namespace kaleidoscope {
namespace plugin {
class Cycle : public kaleidoscope::Plugin {
public:
Cycle(void) {}
static void replace(Key key);
static void replace(uint8_t cycle_size, const Key cycle_steps[]);
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state);
private:
static Key last_non_cycle_key_;
static uint8_t cycle_count_;
};
}
}
void cycleAction(Key previous_key, uint8_t cycle_count);
extern kaleidoscope::plugin::Cycle Cycle;

@ -0,0 +1,62 @@
/* -*- mode: c++ -*-
* Kaleidoscope-CycleTimeReport -- Scan cycle time reporting
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope-CycleTimeReport.h>
namespace kaleidoscope {
namespace plugin {
uint32_t CycleTimeReport::next_report_time_;
uint32_t CycleTimeReport::loop_start_time_;
uint32_t CycleTimeReport::average_loop_time;
EventHandlerResult CycleTimeReport::onSetup() {
next_report_time_ = millis() + 1000;
return EventHandlerResult::OK;
}
EventHandlerResult CycleTimeReport::beforeEachCycle() {
loop_start_time_ = micros();
return EventHandlerResult::OK;
}
EventHandlerResult CycleTimeReport::afterEachCycle() {
uint32_t loop_time = micros() - loop_start_time_;
if (average_loop_time)
average_loop_time = (average_loop_time + loop_time) / 2;
else
average_loop_time = loop_time;
if (millis() >= next_report_time_) {
cycleTimeReport();
average_loop_time = 0;
next_report_time_ = millis() + 1000;
}
return EventHandlerResult::OK;
}
}
}
__attribute__((weak)) void cycleTimeReport(void) {
Serial.print(F("# average loop time: "));
Serial.println(CycleTimeReport.average_loop_time);
}
kaleidoscope::plugin::CycleTimeReport CycleTimeReport;

@ -0,0 +1,43 @@
/* -*- mode: c++ -*-
* Kaleidoscope-CycleTimeReport -- Scan cycle time reporting
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Kaleidoscope.h>
namespace kaleidoscope {
namespace plugin {
class CycleTimeReport : public kaleidoscope::Plugin {
public:
CycleTimeReport() {}
EventHandlerResult onSetup();
EventHandlerResult beforeEachCycle();
EventHandlerResult afterEachCycle();
static uint32_t average_loop_time;
private:
static uint32_t next_report_time_;
static uint32_t loop_start_time_;
};
}
}
void cycleTimeReport(void);
extern kaleidoscope::plugin::CycleTimeReport CycleTimeReport;

@ -0,0 +1,119 @@
/* -*- mode: c++ -*-
* Kaleidoscope-EEPROM-Keymap-Programmer -- On-the-fly reprogrammable keymap.
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope-EEPROM-Keymap-Programmer.h>
#include <Kaleidoscope-FocusSerial.h>
namespace kaleidoscope {
namespace plugin {
uint16_t EEPROMKeymapProgrammer::update_position_;
EEPROMKeymapProgrammer::state_t EEPROMKeymapProgrammer::state_;
EEPROMKeymapProgrammer::mode_t EEPROMKeymapProgrammer::mode;
Key EEPROMKeymapProgrammer::new_key_;
void EEPROMKeymapProgrammer::nextState(void) {
switch (state_) {
case INACTIVE:
state_ = WAIT_FOR_KEY;
break;
case WAIT_FOR_KEY:
if (mode == CODE)
state_ = WAIT_FOR_CODE;
else
state_ = WAIT_FOR_SOURCE_KEY;
break;
case WAIT_FOR_CODE:
case WAIT_FOR_SOURCE_KEY:
::EEPROMKeymap.updateKey(update_position_, new_key_);
cancel();
break;
}
}
void EEPROMKeymapProgrammer::cancel(void) {
update_position_ = 0;
new_key_ = Key_NoKey;
state_ = INACTIVE;
}
EventHandlerResult EEPROMKeymapProgrammer::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) {
if (state_ == INACTIVE)
return EventHandlerResult::OK;
if (state_ == WAIT_FOR_KEY) {
if (keyToggledOn(key_state)) {
update_position_ = Layer.top() * ROWS * COLS + row * COLS + col;
}
if (keyToggledOff(key_state)) {
if ((uint16_t)(Layer.top() * ROWS * COLS + row * COLS + col) == update_position_)
nextState();
}
return EventHandlerResult::EVENT_CONSUMED;
}
if (state_ == WAIT_FOR_SOURCE_KEY) {
if (keyToggledOn(key_state)) {
new_key_ = Layer.getKeyFromPROGMEM(Layer.top(), row, col);
}
if (keyToggledOff(key_state)) {
if (new_key_ == Layer.getKeyFromPROGMEM(Layer.top(), row, col))
nextState();
}
return EventHandlerResult::EVENT_CONSUMED;
}
// WAIT_FOR_CODE state
if (mapped_key < Key_1 || mapped_key > Key_0)
return EventHandlerResult::OK;
if (!keyToggledOn(key_state)) {
return EventHandlerResult::EVENT_CONSUMED;
}
uint8_t n;
if (mapped_key.keyCode == Key_0.keyCode)
n = 0;
else
n = mapped_key.keyCode - Key_1.keyCode + 1;
new_key_.raw = new_key_.raw * 10 + n;
return EventHandlerResult::EVENT_CONSUMED;
}
EventHandlerResult EEPROMKeymapProgrammer::onFocusEvent(const char *command) {
const char *cmd = PSTR("keymap.toggleProgrammer");
if (::Focus.handleHelp(command, cmd))
return EventHandlerResult::OK;
if (strcmp_P(command, cmd) != 0)
return EventHandlerResult::OK;
if (state_ == INACTIVE)
activate();
else
cancel();
return EventHandlerResult::EVENT_CONSUMED;
}
}
}
kaleidoscope::plugin::EEPROMKeymapProgrammer EEPROMKeymapProgrammer;

@ -0,0 +1,59 @@
/* -*- mode: c++ -*-
* Kaleidoscope-EEPROM-Keymap-Programmer -- On-the-fly reprogrammable keymap.
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Kaleidoscope.h>
#include <Kaleidoscope-EEPROM-Keymap.h>
namespace kaleidoscope {
namespace plugin {
class EEPROMKeymapProgrammer : public kaleidoscope::Plugin {
public:
typedef enum {
CODE,
COPY,
} mode_t;
static mode_t mode;
EEPROMKeymapProgrammer(void) {}
static void activate(void) {
nextState();
}
static void nextState(void);
static void cancel(void);
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state);
EventHandlerResult onFocusEvent(const char *command);
private:
typedef enum {
INACTIVE,
WAIT_FOR_KEY,
WAIT_FOR_CODE,
WAIT_FOR_SOURCE_KEY,
} state_t;
static state_t state_;
static uint16_t update_position_; // layer, row, col
static Key new_key_;
};
}
}
extern kaleidoscope::plugin::EEPROMKeymapProgrammer EEPROMKeymapProgrammer;

@ -0,0 +1,43 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Escape-OneShot -- Turn ESC into a key that cancels OneShots, if active.
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-OneShot.h>
#include <Kaleidoscope-Escape-OneShot.h>
namespace kaleidoscope {
namespace plugin {
EventHandlerResult EscapeOneShot::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState) {
if (mapped_key.raw != Key_Escape.raw ||
(keyState & INJECTED) ||
!keyToggledOn(keyState))
return EventHandlerResult::OK;
if (!::OneShot.isActive() || ::OneShot.isPressed())
return EventHandlerResult::OK;
KeyboardHardware.maskKey(row, col);
::OneShot.cancel(true);
return EventHandlerResult::EVENT_CONSUMED;
}
}
}
kaleidoscope::plugin::EscapeOneShot EscapeOneShot;

@ -0,0 +1,33 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Escape-OneShot -- Turn ESC into a key that cancels OneShots, if active.
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Kaleidoscope.h>
namespace kaleidoscope {
namespace plugin {
class EscapeOneShot : public kaleidoscope::Plugin {
public:
EscapeOneShot(void) {}
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState);
};
}
}
extern kaleidoscope::plugin::EscapeOneShot EscapeOneShot;

@ -0,0 +1,117 @@
/* -*- mode: c++ -*-
* Kaleidoscope-FingerPainter -- On-the-fly keyboard painting.
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope-FingerPainter.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <Kaleidoscope-FocusSerial.h>
#include <Kaleidoscope-LEDControl.h>
#include <Kaleidoscope-LED-Palette-Theme.h>
namespace kaleidoscope {
namespace plugin {
uint16_t FingerPainter::color_base_;
bool FingerPainter::edit_mode_;
EventHandlerResult FingerPainter::onSetup() {
color_base_ = ::LEDPaletteTheme.reserveThemes(1);
::LEDControl.mode_add(this);
return EventHandlerResult::OK;
}
void FingerPainter::update(void) {
::LEDPaletteTheme.updateHandler(color_base_, 0);
}
void FingerPainter::refreshAt(byte row, byte col) {
::LEDPaletteTheme.refreshAt(color_base_, 0, row, col);
}
void FingerPainter::toggle(void) {
edit_mode_ = !edit_mode_;
}
EventHandlerResult FingerPainter::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) {
if (!edit_mode_)
return EventHandlerResult::OK;
if (!keyToggledOn(key_state)) {
return EventHandlerResult::EVENT_CONSUMED;
}
if (row >= ROWS || col >= COLS)
return EventHandlerResult::EVENT_CONSUMED;
uint8_t color_index = ::LEDPaletteTheme.lookupColorIndexAtPosition(color_base_, KeyboardHardware.getLedIndex(row, col));
// Find the next color in the palette that is different.
// But do not loop forever!
bool turn_around = false;
cRGB old_color = ::LEDPaletteTheme.lookupPaletteColor(color_index), new_color = old_color;
while (memcmp(&old_color, &new_color, sizeof(cRGB)) == 0) {
color_index++;
if (color_index > 15) {
color_index = 0;
if (turn_around)
break;
turn_around = true;
}
new_color = ::LEDPaletteTheme.lookupPaletteColor(color_index);
}
::LEDPaletteTheme.updateColorIndexAtPosition(color_base_, KeyboardHardware.getLedIndex(row, col), color_index);
return EventHandlerResult::EVENT_CONSUMED;
}
EventHandlerResult FingerPainter::onFocusEvent(const char *command) {
enum {
TOGGLE,
CLEAR,
} sub_command;
if (::Focus.handleHelp(command, PSTR("fingerpainter.toggle\nfingerpainter.clear")))
return EventHandlerResult::OK;
if (strncmp_P(command, PSTR("fingerpainter."), 14) != 0)
return EventHandlerResult::OK;
if (strcmp_P(command + 14, PSTR("toggle")) == 0)
sub_command = TOGGLE;
else if (strcmp_P(command + 14, PSTR("clear")) == 0)
sub_command = CLEAR;
else
return EventHandlerResult::OK;
if (sub_command == CLEAR) {
for (uint16_t i = 0; i < ROWS * COLS / 2; i++) {
EEPROM.update(color_base_ + i, 0);
}
return EventHandlerResult::OK;
}
::FingerPainter.activate();
toggle();
return EventHandlerResult::OK;
}
}
}
kaleidoscope::plugin::FingerPainter FingerPainter;

@ -0,0 +1,45 @@
/* -*- mode: c++ -*-
* Kaleidoscope-FingerPainter -- On-the-fly keyboard painting.
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Kaleidoscope-LEDControl.h>
namespace kaleidoscope {
namespace plugin {
class FingerPainter : public LEDMode {
public:
FingerPainter(void) {}
static void toggle(void);
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state);
EventHandlerResult onFocusEvent(const char *command);
EventHandlerResult onSetup();
protected:
void update(void) final;
void refreshAt(byte row, byte col) final;
private:
static uint16_t color_base_;
static bool edit_mode_;
};
}
}
extern kaleidoscope::plugin::FingerPainter FingerPainter;

@ -0,0 +1,55 @@
/* Kaleidoscope-Steno -- Steno protocols for Kaleidoscope
* Copyright (C) 2017 Joseph Wasson
* Copyright (C) 2017, 2018 Gergely Nagy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope-Steno.h>
namespace kaleidoscope {
namespace plugin {
namespace steno {
uint8_t GeminiPR::keys_held_;
uint8_t GeminiPR::state_[6];
EventHandlerResult GeminiPR::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState) {
if (mapped_key < geminipr::START ||
mapped_key > geminipr::END)
return EventHandlerResult::OK;
if (keyToggledOn(keyState)) {
uint8_t key = mapped_key.raw - geminipr::START;
++keys_held_;
state_[key / 7] |= 1 << (6 - (key % 7));
} else if (keyToggledOff(keyState)) {
--keys_held_;
if (keys_held_ == 0) {
state_[0] |= 0x80;
Serial.write(state_, sizeof(state_));
memset(state_, 0, sizeof(state_));
}
}
return EventHandlerResult::EVENT_CONSUMED;
}
}
}
}
kaleidoscope::plugin::steno::GeminiPR GeminiPR;

@ -0,0 +1,97 @@
/* Kaleidoscope-Steno -- Steno protocols for Kaleidoscope
* Copyright (C) 2017 Joseph Wasson
* Copyright (C) 2017, 2018 Gergely Nagy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Kaleidoscope.h>
#include <Kaleidoscope-Ranges.h>
#define S(n) (Key) {.raw = kaleidoscope::plugin::steno::geminipr::n }
namespace kaleidoscope {
namespace plugin {
namespace steno {
class GeminiPR : public kaleidoscope::Plugin {
public:
GeminiPR(void) {}
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t keyState);
private:
static uint8_t keys_held_;
static uint8_t state_[6];
};
namespace geminipr {
enum {
START = kaleidoscope::ranges::STENO_FIRST,
FN = START,
NUM,
N1 = NUM,
N2,
N3,
N4,
N5,
N6,
SL,
S1 = SL,
S2,
TL,
KL,
PL,
WL,
HL,
RL,
A,
O,
STR,
ST1 = STR,
ST2,
RES1,
RE1 = RES1,
RES2,
RE2 = RES2,
PWR,
ST3,
ST4,
E,
U,
FR,
RR,
PR,
BR,
LR,
GR,
TR,
SR,
DR,
N7,
N8,
N9,
NA,
NB,
NC,
ZR,
END = ZR,
};
}
}
}
}
extern kaleidoscope::plugin::steno::GeminiPR GeminiPR;

@ -0,0 +1,76 @@
/* -*- mode: c++ -*-
* Kaleidoscope-GhostInTheFirmware -- Let the keyboard write for you!
* Copyright (C) 2017 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-GhostInTheFirmware.h>
namespace kaleidoscope {
namespace plugin {
const GhostInTheFirmware::GhostKey *GhostInTheFirmware::ghost_keys;
bool GhostInTheFirmware::is_active_;
bool GhostInTheFirmware::is_pressed_;
uint16_t GhostInTheFirmware::current_pos_;
uint32_t GhostInTheFirmware::start_time_;
uint16_t GhostInTheFirmware::press_timeout_;
uint16_t GhostInTheFirmware::delay_timeout_;
void GhostInTheFirmware::activate(void) {
is_active_ = true;
}
EventHandlerResult GhostInTheFirmware::beforeReportingState() {
if (!is_active_)
return EventHandlerResult::OK;
if (press_timeout_ == 0) {
press_timeout_ = pgm_read_word(&(ghost_keys[current_pos_].pressTime));
delay_timeout_ = pgm_read_word(&(ghost_keys[current_pos_].delay));
if (press_timeout_ == 0) {
current_pos_ = 0;
is_active_ = false;
return EventHandlerResult::OK;
}
is_pressed_ = true;
start_time_ = millis();
} else {
if (is_pressed_ && ((millis() - start_time_) > press_timeout_)) {
is_pressed_ = false;
start_time_ = millis();
byte row = pgm_read_byte(&(ghost_keys[current_pos_].row));
byte col = pgm_read_byte(&(ghost_keys[current_pos_].col));
handleKeyswitchEvent(Key_NoKey, row, col, WAS_PRESSED);
} else if (is_pressed_) {
byte row = pgm_read_byte(&(ghost_keys[current_pos_].row));
byte col = pgm_read_byte(&(ghost_keys[current_pos_].col));
handleKeyswitchEvent(Key_NoKey, row, col, IS_PRESSED);
} else if ((millis() - start_time_) > delay_timeout_) {
current_pos_++;
press_timeout_ = 0;
}
}
return EventHandlerResult::OK;
}
}
}
kaleidoscope::plugin::GhostInTheFirmware GhostInTheFirmware;

@ -0,0 +1,56 @@
/* -*- mode: c++ -*-
* Kaleidoscope-GhostInTheFirmware -- Let the keyboard write for you!
* Copyright (C) 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Kaleidoscope.h>
namespace kaleidoscope {
namespace plugin {
class GhostInTheFirmware : public kaleidoscope::Plugin {
public:
typedef struct {
byte row;
byte col;
uint16_t pressTime;
uint16_t delay;
} GhostKey;
static const GhostKey *ghost_keys;
GhostInTheFirmware(void) {}
static void activate(void);
EventHandlerResult beforeReportingState();
private:
static bool is_active_;
static bool is_pressed_;
static uint16_t current_pos_;
static uint32_t start_time_;
static uint16_t press_timeout_;
static uint16_t delay_timeout_;
static void loopHook(bool is_post_clear);
};
}
// For backwards compatibility
typedef kaleidoscope::plugin::GhostInTheFirmware GhostInTheFirmware;
}
extern kaleidoscope::plugin::GhostInTheFirmware GhostInTheFirmware;

@ -0,0 +1,205 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Heatmap -- Heatmap LED effect for Kaleidoscope.
* Copyright (C) 2016, 2017 Gergely Nagy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope.h>
#include <Kaleidoscope-Heatmap.h>
namespace kaleidoscope {
namespace plugin {
// store the number of times each key has been strock
uint16_t Heatmap::heatmap_[ROWS][COLS];
// max of heatmap_ (we divide by it so we start at 1)
uint16_t Heatmap::highest_ = 1;
// next heatmap computation time
uint32_t Heatmap::next_heatmap_comp_time_ = 0;
// in the cRGB struct the order is blue, green, red (It should be called cBGR…)
// default heat_colors black green yellow red
static const cRGB heat_colors_default_[] PROGMEM = {{0, 0, 0}, {25, 255, 25}, {25, 255, 255}, {25, 25, 255}};
// colors from cold to hot
const cRGB *Heatmap::heat_colors = heat_colors_default_;
uint8_t Heatmap::heat_colors_length = 4;
// number of millisecond to wait between each heatmap computation
uint16_t Heatmap::update_delay = 1000;
cRGB Heatmap::computeColor(float v) {
// compute the color corresponding to a value between 0 and 1
/*
* for exemple, if:
* v=0.8
* heat_colors_lenth=4 (hcl)
* the red components of heat_colors are: 0, 25, 25, 255 (rhc)
* the red component returned by computeColor will be: 117
*
* 255 | /
* | /
* | /
* 117 | - - - - - - -/
* | /
* 25 | ______/ |
* | __/
* | _/ |
* |/_________________
* 0 1 2 3
* 2.4
* idx1 | idx2
* <>
* fb
*
* in this exemple, I call red heat_colors: rhc
* idx1 = floor(v×(hcl-1)) = floor(0.8×3) = floor(2.4) = 2
* idx2 = idx1 + 1 = 3
* fb = v×(hcl-1)-idx1 = 0.8×3 - 2 = 0.4
* red = (rhc[idx2]-rhc[idx1])×fb + rhc[idx1] = (255-25)×(2.4-2) + 25 = 117
*/
float fb = 0;
uint8_t idx1, idx2;
if (v <= 0) {
// if v = 0, don't bother computing fb and use heat_colors[0]
idx1 = idx2 = 0;
} else if (v >= 1) {
// if v = 1,
// don't bother computing fb and use heat_colors[heat_colors_length-1]
idx1 = idx2 = heat_colors_length - 1;
} else {
float val = v * (heat_colors_length - 1);
// static_cast from float to int just drop the decimal part of the number
// static_cast<int>(5.9) → 5
idx1 = static_cast<int>(val);
idx2 = idx1 + 1;
fb = val - static_cast<float>(idx1);
}
uint8_t r = static_cast<uint8_t>((pgm_read_byte(&(heat_colors[idx2].r)) - pgm_read_byte(&(heat_colors[idx1].r))) * fb + pgm_read_byte(&(heat_colors[idx1].r)));
uint8_t g = static_cast<uint8_t>((pgm_read_byte(&(heat_colors[idx2].g)) - pgm_read_byte(&(heat_colors[idx1].g))) * fb + pgm_read_byte(&(heat_colors[idx1].g)));
uint8_t b = static_cast<uint8_t>((pgm_read_byte(&(heat_colors[idx2].b)) - pgm_read_byte(&(heat_colors[idx1].b))) * fb + pgm_read_byte(&(heat_colors[idx1].b)));
return {b, g, r};
}
void Heatmap::shiftStats(void) {
// this method is called when:
// 1. a value in heatmap_ reach INT8_MAX
// 2. highest_ reach heat_colors_length*512 (see Heatmap::loopHook)
// we divide every heatmap element by 2
for (uint8_t r = 0; r < ROWS; r++) {
for (uint8_t c = 0; c < COLS; c++) {
heatmap_[r][c] = heatmap_[r][c] >> 1;
}
}
// and also divide highest_ accordingly
highest_ = highest_ >> 1;
}
void Heatmap::resetMap(void) {
// this method can be used as a way to work around an existing bug with a single key
// getting special attention or if the user just wants a button to reset the map
for (uint8_t r = 0; r < ROWS; r++) {
for (uint8_t c = 0; c < COLS; c++) {
heatmap_[r][c] = 0;
}
}
highest_ = 1;
}
EventHandlerResult Heatmap::onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state) {
// this methode is called frequently by Kaleidoscope
// even if the module isn't activated
// if it is a synthetic key, skip it
if (key_state & INJECTED)
return EventHandlerResult::OK;
// if the key is not toggled on, skip it
if (!keyToggledOn(key_state))
return EventHandlerResult::OK;
// increment the heatmap_ value related to the key
heatmap_[row][col]++;
// check highest_
if (highest_ < heatmap_[row][col]) {
highest_ = heatmap_[row][col];
// if highest_ (and so heatmap_ value related to the key)
// is close to overflow: call shiftStats
// NOTE: this is barely impossible since shiftStats should be
// called much sooner by Heatmap::loopHook
if (highest_ == INT16_MAX)
shiftStats();
}
return EventHandlerResult::OK;
}
EventHandlerResult Heatmap::beforeEachCycle() {
// this methode is called frequently by Kaleidoscope
// even if the module isn't activated
// call shiftStats (divide every heatmap value by 2)
// if highest_ reach heat_colors_length*512.
// So after the shift, highest_ will be heat_colors_length*256. We
// didn't lose any precision in our heatmap since between each color we have a
// maximum precision of 256 ; said differently, there is 256 state (at max)
// between heat_colors[x] and heat_colors[x+1].
if (highest_ > (static_cast<uint16_t>(heat_colors_length) << 9))
shiftStats();
return EventHandlerResult::OK;
}
void Heatmap::update(void) {
// this methode is called frequently by the LEDControl::loopHook
// do nothing if we didn't reach next_heatmap_comp_time_ yet
if (next_heatmap_comp_time_ && (millis() < next_heatmap_comp_time_))
return;
// do the heatmap computing
// (we reach next_heatmap_comp_time_ or next_heatmap_comp_time_ was never scheduled)
// schedule the next heatmap computing
next_heatmap_comp_time_ = millis() + update_delay;
// for each key
for (uint8_t r = 0; r < ROWS; r++) {
for (uint8_t c = 0; c < COLS; c++) {
// how much the key was pressed compared to the others (between 0 and 1)
// (total_keys_ can't be equal to 0)
float v = static_cast<float>(heatmap_[r][c]) / highest_;
// we could have used an interger instead of a float, but then we would
// have had to change some multiplication in division.
// / on uint is slower than * on float, so I stay with the float
// https://forum.arduino.cc/index.php?topic=92684.msg2733723#msg2733723
// set the LED color accordingly
::LEDControl.setCrgbAt(r, c, computeColor(v));
}
}
}
}
}
kaleidoscope::plugin::Heatmap HeatmapEffect;

@ -0,0 +1,52 @@
/* -*- mode: c++ -*-
* Kaleidoscope-Heatmap -- Heatmap LED effect for Kaleidoscope.
* Copyright (C) 2016, 2017, 2018 Gergely Nagy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Kaleidoscope.h>
#include <Kaleidoscope-LEDControl.h>
namespace kaleidoscope {
namespace plugin {
class Heatmap : public LEDMode {
public:
Heatmap(void) {}
static uint16_t update_delay;
static const cRGB *heat_colors;
static uint8_t heat_colors_length;
void resetMap(void);
EventHandlerResult onKeyswitchEvent(Key &mapped_key, byte row, byte col, uint8_t key_state);
EventHandlerResult beforeEachCycle();
protected:
void update(void) final;
private:
static uint16_t heatmap_[ROWS][COLS];
static uint16_t highest_;
static uint32_t next_heatmap_comp_time_;
static void shiftStats(void);
static cRGB computeColor(float v);
};
}
}
extern kaleidoscope::plugin::Heatmap HeatmapEffect;

@ -0,0 +1,46 @@
/* -*- mode: c++ -*-
* Kaleidoscope-HostOS -- Host OS detection and tracking for Kaleidoscope
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Kaleidoscope-HostOS.h>
#include <Kaleidoscope-FocusSerial.h>
namespace kaleidoscope {
namespace plugin {
EventHandlerResult FocusHostOSCommand::onFocusEvent(const char *command) {
const char *cmd = PSTR("hostos.type");
if (::Focus.handleHelp(command, cmd))
return EventHandlerResult::OK;
if (strcmp_P(command, cmd) != 0)
return EventHandlerResult::OK;
if (Serial.peek() == '\n') {
Serial.println(::HostOS.os());
} else {
uint8_t new_os = Serial.parseInt();
::HostOS.os((hostos::Type) new_os);
}
Serial.read();
return EventHandlerResult::EVENT_CONSUMED;
}
}
}
kaleidoscope::plugin::FocusHostOSCommand FocusHostOSCommand;

@ -0,0 +1,33 @@
/* -*- mode: c++ -*-
* Kaleidoscope-HostOS -- Host OS detection and tracking for Kaleidoscope
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Kaleidoscope.h>
namespace kaleidoscope {
namespace plugin {
class FocusHostOSCommand : public kaleidoscope::Plugin {
public:
FocusHostOSCommand() {}
EventHandlerResult onFocusEvent(const char *command);
};
}
}
extern kaleidoscope::plugin::FocusHostOSCommand FocusHostOSCommand;

@ -0,0 +1,51 @@
/* -*- mode: c++ -*-
* Kaleidoscope-HostOS -- Host OS detection and tracking for Kaleidoscope
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <kaleidoscope/plugin/HostOS.h>
#include <Kaleidoscope-EEPROM-Settings.h>
#include <EEPROM.h>
namespace kaleidoscope {
namespace plugin {
EventHandlerResult HostOS::onSetup(void) {
if (is_configured_)
return EventHandlerResult::OK;
eeprom_slice_ = ::EEPROMSettings.requestSlice(sizeof(os_));
is_configured_ = true;
if (os_ != hostos::UNKNOWN) {
return EventHandlerResult::OK;
}
os_ = (hostos::Type)EEPROM.read(eeprom_slice_);
return EventHandlerResult::OK;
}
void HostOS::os(hostos::Type new_os) {
os_ = new_os;
EEPROM.update(eeprom_slice_, os_);
}
}
}
kaleidoscope::plugin::HostOS HostOS;

@ -0,0 +1,66 @@
/* -*- mode: c++ -*-
* Kaleidoscope-HostOS -- Host OS detection and tracking for Kaleidoscope
* Copyright (C) 2016, 2017, 2018 Keyboard.io, Inc
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Kaleidoscope.h>
namespace kaleidoscope {
namespace plugin {
namespace hostos {
typedef enum {
LINUX,
OSX,
WINDOWS,
OTHER,
UNKNOWN = 0xff,
AUTO = UNKNOWN
} Type;
}
#define _DEPRECATED_MESSAGE_AUTODETECT \
"The auto-detect mechanism of HostOS was removed, because it was\n" \
"too unreliable. As such, the HostOS.autoDetect() method does\n" \
"nothing anymore. Please consider other ways of changing the\n" \
"HostOS type."
class HostOS : public kaleidoscope::Plugin {
public:
HostOS() {}
EventHandlerResult onSetup();
hostos::Type os(void) {
return os_;
}
void os(hostos::Type new_os);
void autoDetect() DEPRECATED(AUTODETECT) {}
private:
hostos::Type os_;
uint16_t eeprom_slice_;
bool is_configured_ = false;
};
}
namespace hostos = plugin::hostos;
}
extern kaleidoscope::plugin::HostOS HostOS;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save