-
Notifications
You must be signed in to change notification settings - Fork 331
Changelog
Outside of combos where one could reasonably be selecting maybe 2-4 keys spread across the keyboard, I would imagine that the most common case for specifying key positions is to describe "positional-hold-tap" behavior for homerow mods that should only activate a hold in one key when a key from the other half of the keyboard is tapped.
I've updated the key position selector component to allow dragging to select a number of keys within a region.
I've been seeing more users attempt to use the editor with keymaps that are completely unparseable due to the use of helpers like the zmk-nodefree configuration. To reduce confusion (it's not technically an error) I'm adding some sanity checks to the keymap parser so that helpful messaging can be displayed to the user.
As things move along I would like to extend this to be a little more strict... not so much for reasons of being opinionated, but rather to reduce needless complexity. As an example, some keymaps have multiple devicetree root nodes to keep things like behaviors and combos separate. It's technically acceptable, in that it can be used to successfully build ZMK firmware, but having to search each of these root nodes impacts performance.
I already wrote about this at length in a comment on my de facto "Behavior Editing Progress Blog" so I won't try to repeat that here. I'm not sure if I'm more jazzed about this or for the behavior editing work that brought it about.
Making big progress on a big feature. I've created scripts to extract schema information about every behavior in ZMK's repository, and overlay metadata files where I add more details to help clarify restrictions or suggest useful helpers to the Keymap Editor.
One example of this is in behaviors like caps-word and mod-morph which
include a mods
property. The the end user this property is a selection
of modifiers, but its representation in the devicetree is a bitwise
union of the bit masks of the selected modifiers' HID codes --
effectively a single int
. In my overlay I specify a helper type I call
"integer-union"
and have special serialization/deserialization methods
to take care of devicetree, but from the perspective of the API and app
its an array of selectable values.
I also had the opportunity to reuse some of my existing components. Bindings are of course able to reuse the same bind value rendered in the keymap, but a number of properties represent the positions of keys that should/shouldn't trigger that behavior which is something I've already taken care of in the Combo Editor.
I'm slowly getting more familiar with Devicetree syntax and working with language grammars, and as I do so I'm finding better ways to organize the code to implement this functionality. This is all behind-the-scenes stuff, but crucial to upcoming work on behavior editing.
Pre-defined behaviors (those listed in the ZMK documentation and already
have a binding ready to use like &mt
/<
implementations of hold tap)
have parameters defined manually. Custom behaviors parsed out of a keymap,
like a hold-tap implementation that uses sticky-layer as its tap function
would not have parameters available which means the value picker can't
show a useful prompt to the user.
Such a behavior would define something like bindings = <&mo>, <&sl>;
so
the job of the parameter resolver would be to match &mo
and &sl
to
recognized behaviors, and select their parameters. It's not perfect, the
hold-tap behavior expects you to reference exactly two other behaviors in
its bindings
array, and it expects each to take exactly one argument
each. I want to keep things as generic as possible, so while I can try to
express some of this in a declarative manner some amount of deliberate
effort is needed to deal with this.
This also ignores the potential issue of behaviors for functionality that hasn't yet been merged into ZMK core like mouse keys.
One of the most frequent issues I see with people using Kinesis' fork is that users don't understand how to add a modifier to a keycode using ZMK's modifier function syntax and they'll often try to define macros to do this.
The naive implementation of the picker component was based on parsing ZMK
bindings into trees. For example, < 1 LC(A)
is parsed into
value: < (behavior)
params:
- value: 1 (layer)
params: --
- value: LC (code)
params:
- value: A (code)
params: --
It's not much to look at but it honestly helped me a lot with generalizing binding management without locking into overly specific use cases.
A new keycode picker has been implemented to include a modifier selection component, and when editing a bind parameter that expects a "code" value this new picker will be chosen instead.
This is both a convenient way to use &rgb_ug RGB_COLOR_HSB(...)
bindings
and a proof of concept. A long term goal has been to enable the key picker
to select purpose-built components where selecting a value from a pre-defined
list isn't sufficient. To support this I've reworked the code to render
binding values and the value picker so that things like behavior metadata
can provide more appropriate alternatives.
For a long time I had custom labels/symbols/icons for keycodes defined in a single file, and mostly to suit my own use. To try and improve the experience for users on different platforms I've broken this apart into
- basic glyphs
- display symbols like
%
instead of the actual codePERCENT
for simplicity and readability - usually these are widely available characters from the ASCII set, but occasionally this includes suitable Font Awesome icons.
- display symbols like
- unicode glyphs
- a few less-common Unicode symbols like arrows,
⮐
(return),␣
(space)
- a few less-common Unicode symbols like arrows,
- platform-specific glyphs
-
⌥
(alt),⌘
(cmd) for macos - Font Awesome's Windows icon for Windows
-
The extended glyph sets can be disabled if they're causing rendering problems and the platform-specific sets can be chosen manually or automatically based on browser detection.
- Re-enable search on short value picker lists like behaviors
- Fix switching
command
type binding parameters- switching from
BT_NXT
/BT_PRV
toBT_SEL
would fail silently in some cases
- switching from
- Add visual cue to key binds that haven't selected all required values
As features are added and more complex use cases are considered (such as pulling from arbitrary upstream repositories or including shared dtsi files) I want to avoid making unnecessary calls to the GitHub API.
I've added a library to cache HTTP requests made from the backend to the GitHub API that seemed to work in the simple cases I tested, but some issues cropped up around caching URLs that are not obviously specific to the authenticated user. To resolve this, caching is enabled explicitly on resources that are known to support it and with custom defined cache keys where needed.
Available rotary encoders are discovered in the board/shield definition. For now
it is assumed that any listed sensor is compatible = "alps,ec11";
instead of
explicitly checking, and there are the usual limitations about discoverability
(https://github.com/nickcoutsos/keymap-editor/wiki/Limitations-of-the-Keymap-Editor#rotary-encoders).
It also assumes that if a sensor is defined, it is enabled. So keyboards that
define the sensor with status = "disabled";
and explicitly enable it later in
the keymap as needed will have problems.
TBD