Clean-room ZMK steno engine with trie/DAWG dictionary
Find a file
afiqzudinhadi c0756e6428 Peripheral: handle dict requests on a dedicated worker thread
Inflating a 16KB string block inside the BT RX thread overflowed its
stack and froze the peripheral on the first steno stroke. The GATT
write callback now only copies the request (<= 7 bytes) and submits
to a 4KB-stack work queue; the worker resolves and notifies. Single
request in flight, busy requests dropped (central times out and
retries). GATT service + handlers now compile on the peripheral
only. Inflate Huffman tables made static (single-context) to cut
per-call stack use ~2KB. Host round-trip re-verified: 42,000
vectors, 0 mismatches.
2026-07-03 15:27:27 +08:00
dicts Scaffolding: ZMK module structure, Kconfig, DTS, behavior driver 2026-07-02 02:04:28 +08:00
dts Scaffolding: ZMK module structure, Kconfig, DTS, behavior driver 2026-07-02 02:04:28 +08:00
include/dt-bindings/zmk Scaffolding: ZMK module structure, Kconfig, DTS, behavior driver 2026-07-02 02:04:28 +08:00
src Peripheral: handle dict requests on a dedicated worker thread 2026-07-03 15:27:27 +08:00
tests v4 union split-section dictionary: both full dicts, zero trimming 2026-07-03 01:28:31 +08:00
tools v4 union split-section dictionary: both full dicts, zero trimming 2026-07-03 01:28:31 +08:00
zephyr Scaffolding: ZMK module structure, Kconfig, DTS, behavior driver 2026-07-02 02:04:28 +08:00
.gitignore Scaffolding: ZMK module structure, Kconfig, DTS, behavior driver 2026-07-02 02:04:28 +08:00
CMakeLists.txt Own DEFLATE decoder replaces zlib dependency 2026-07-03 11:37:19 +08:00
Kconfig Own DEFLATE decoder replaces zlib dependency 2026-07-03 11:37:19 +08:00
LICENSE Scaffolding: ZMK module structure, Kconfig, DTS, behavior driver 2026-07-02 02:04:28 +08:00
README.md Scaffolding: ZMK module structure, Kconfig, DTS, behavior driver 2026-07-02 02:04:28 +08:00

zmk-steno-engine

Clean-room stenography engine for ZMK Firmware. Dictionary-based lookup with multi-stroke support, optimized for nRF52840 flash constraints.

Status: Early development — basic single/multi-stroke lookup works, formatter not yet implemented.

Features

  • Standard 23-key steno layout
  • Sorted-array dictionary with binary search lookup
  • Multi-stroke support with configurable timeout
  • All-up chord detection
  • HID keyboard output (ASCII)
  • Build-time dictionary compilation from Plover JSON
  • Test dictionary included for development

Building

Add as a ZMK module in your west.yml:

manifest:
  remotes:
    - name: zmk-steno-engine
      url-base: https://github.com/afiqzudinhadi
  projects:
    - name: zmk-steno-engine
      remote: zmk-steno-engine
      revision: optimize-dict

Enable in your .conf:

CONFIG_STENO_ENGINE=y

Use in your keymap:

#include <dt-bindings/zmk/steno_keys.h>

/ {
    keymap {
        steno_layer {
            bindings = <
                &steno STENO_SL  &steno STENO_TL  &steno STENO_PL  ...
            >;
        };
    };
};

Dictionary Compiler

# Compile test dictionary
python3 tools/compile_simple.py dicts/test.json -o steno_dict.bin --stats

# Compile Plover dictionary (trimmed)
python3 tools/compile_simple.py plover-main.json -o steno_dict.bin --max-entries 120000 --stats

License

PolyForm Noncommercial 1.0.0