Skip to content

Commit

Permalink
Make autoshift longpress configurable
Browse files Browse the repository at this point in the history
This commit allows specifying the keys to produce on long press if not a
shifted, but a totally different character is wanted.

Such an explicit mapping takes precedence over shifting the key. That
means if all alpanumeric characters are configured for AutoShift, but
the ‘e’ key has an explicit mapping to produce ‘ë’, a long press on ‘e’
will result in ’ë’, not ‘E’.

Signed-off-by: Marco Herrn <[email protected]>
  • Loading branch information
hupfdule committed Apr 13, 2023
1 parent 7291137 commit 7722673
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "kaleidoscope/Runtime.h" // for Runtime, Runtime_
#include "kaleidoscope/key_defs.h" // for Key, Key_0, Key_1, Key_A, Key_F1, Key_F12, Key...
#include "kaleidoscope/keyswitch_state.h" // for keyToggledOn, keyIsInjected
#include "kaleidoscope/progmem_helpers.h" // for cloneFromProgmem

// IWYU pragma: no_include "HIDAliases.h"

Expand Down Expand Up @@ -57,6 +58,11 @@ bool AutoShift::enabledForKey(Key key) {
if (!key.isKeyboardKey())
return false;

// Check whether we have an explicit mapping for that key
if (isExplicitlyMapped(key)) {
return true;
}

// We compare only the keycode, and disregard any modifier flags applied to
// the key. This simplifies the comparison, and also allows AutoShift to
// apply to keys like `RALT(Key_E)`.
Expand Down Expand Up @@ -93,6 +99,19 @@ bool AutoShift::enabledForKey(Key key) {
return false;
}

bool AutoShift::isExplicitlyMapped(Key key) {
// Check whether the given key has an explicit mapping to a different one
for (uint8_t i{0}; i < explicitmappings_count_; ++i) {
LongPress mappedKey = cloneFromProgmem(explicitmappings_[i]);
if (mappedKey.key == key) {
return true;
}
}

// If no matches were found, return false
return false;
}

// =============================================================================
// Event handler hook functions

Expand Down Expand Up @@ -188,9 +207,24 @@ void AutoShift::flushEvent(bool is_long_press) {
KeyEvent event = queue_.event(0);
if (is_long_press) {
event.key = Runtime.lookupKey(event.addr);
uint8_t flags = event.key.getFlags();
flags ^= SHIFT_HELD;
event.key.setFlags(flags);

// If we have an explicit mapping for that key, apply that.
bool mapped= false;
for (uint8_t i{0}; i < explicitmappings_count_; ++i) {
LongPress mappedKey = cloneFromProgmem(explicitmappings_[i]);
if (mappedKey.key == event.key) {
event.key = mappedKey.alternate_key;
mapped= true;
}
}

// If there was no explicit mapping, just add the shift modifier
if (!mapped) {
// event.key = longpresses[event.key]
uint8_t flags = event.key.getFlags();
flags ^= SHIFT_HELD;
event.key.setFlags(flags);
}
}
queue_.shift();
Runtime.handleKeyswitchEvent(event);
Expand Down
35 changes: 35 additions & 0 deletions plugins/Kaleidoscope-AutoShift/src/kaleidoscope/plugin/AutoShift.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,22 @@
namespace kaleidoscope {
namespace plugin {

struct LongPress {
// The key that should result in a different value on long press.
Key key;
// The alternate Key value that should be produced on long press.
Key alternate_key;

// This is the constructor that should be used when creating a LongPress object in
// the PROGMEM array that will be used by explicit mappings (i.e. in the `AUTOSHIFT()`
// macro).
constexpr LongPress(Key key, Key alternate_key)
: key(key), alternate_key(alternate_key) {}
// This constructor is here so that we can create an empty LongPress object in RAM
// into which we can copy the values from a PROGMEM LongPress object.
LongPress() = default;
};

// =============================================================================
/// Kaleidoscope plugin for long-press auto-shift keys
///
Expand Down Expand Up @@ -232,6 +248,12 @@ class AutoShift : public Plugin {
EventHandlerResult onKeyswitchEvent(KeyEvent &event);
EventHandlerResult afterEachCycle();

template<uint8_t _explicitmappings_count>
void configureLongPresses(LongPress const (&explicitmappings)[_explicitmappings_count]) {
explicitmappings_ = explicitmappings;
explicitmappings_count_ = _explicitmappings_count;
}

private:
// ---------------------------------------------------------------------------
/// A container for AutoShift configuration settings
Expand Down Expand Up @@ -268,6 +290,12 @@ class AutoShift : public Plugin {

/// The default function for `isAutoShiftable()`
bool enabledForKey(Key key);

bool isExplicitlyMapped(Key key);

// An array of LongPress objects in PROGMEM.
LongPress const *explicitmappings_{nullptr};
uint8_t explicitmappings_count_{0};
};

// =============================================================================
Expand All @@ -288,3 +316,10 @@ class AutoShiftConfig : public Plugin {

extern kaleidoscope::plugin::AutoShift AutoShift;
extern kaleidoscope::plugin::AutoShiftConfig AutoShiftConfig;

#define AUTOSHIFT(longpress_defs...) \
{ \
static kaleidoscope::plugin::LongPress const qk_table[] PROGMEM = { \
longpress_defs}; \
AutoShift.configureLongPresses(qk_table); \
}

0 comments on commit 7722673

Please sign in to comment.