Format v4 (docs/FORMAT_V4.md): one union CHD MPHF over 226,791 stroke keys from Plover (147,424) + Lapwing (114,885), sections distributed across halves. Left blob 387KB (displacements log-class Huffman 59KB, membership 57KB, fingerprints 113KB, conflicts 9.6KB, value-index slice 157KB); right blob 515KB (strings front-coded+deflate 193KB, value-index remainder 324KB, conflicts dup). Shared string table: 73,464 unique translations, Lapwing 93% subset of Plover. - tools/compile_v4.py: encoder + full verification (all 262,309 entries byte-exact through cold decode path; hard error if either blob exceeds budget — never trims) - src/dict_v4.c/.h: decoder — canonical Huffman displacement decode, conflict binary search, FC block walk, 2-block LRU cache - src/behavior_steno.c: Plover-style sliding longest-match with retrace replaces multi-stroke timeout + prefix checks - src/split_dict.c/.h: protocol v4 — GET_STRING(string_id) / RESOLVE(slot, dict); decisions are 100% left-local, BLE only for translation text - CMake/Kconfig: STENO_DICT_BOTH default, one compiler run emits both half blobs; legacy MPHF path kept behind STENO_DICT_V4=n - Host round-trip test: 42,000 vectors left→right split path, 0 mismatches (tests/test_dict_v4.c)
150 lines
3.6 KiB
Text
150 lines
3.6 KiB
Text
# Copyright (c) 2024 Afiq Zudin Hadi
|
|
# SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
|
|
|
|
menuconfig STENO_ENGINE
|
|
bool "Steno Engine"
|
|
default n
|
|
help
|
|
Enable the stenography engine for ZMK.
|
|
|
|
if STENO_ENGINE
|
|
|
|
choice STENO_DICT
|
|
prompt "Steno dictionary"
|
|
default STENO_DICT_BOTH
|
|
|
|
config STENO_DICT_BOTH
|
|
bool "Plover + Lapwing"
|
|
help
|
|
Compile both full dictionaries into the v4 union format.
|
|
The active dictionary is selected at runtime.
|
|
|
|
config STENO_DICT_PLOVER
|
|
bool "Plover main dictionary"
|
|
help
|
|
Compile only the Plover main dictionary.
|
|
|
|
config STENO_DICT_LAPWING
|
|
bool "Lapwing dictionary"
|
|
help
|
|
Compile only the Lapwing dictionary.
|
|
|
|
endchoice
|
|
|
|
config STENO_DICT_V4
|
|
bool "v4 union split-section dictionary format"
|
|
default y
|
|
select ZLIB
|
|
help
|
|
Compile the dictionary into the v4 union split-section format
|
|
(docs/FORMAT_V4.md): two half blobs, left (central) holds the
|
|
lookup structures, right (peripheral) holds the string table.
|
|
Requires STENO_SPLIT_DICT. Disable to fall back to the legacy
|
|
single-dictionary MPHF format.
|
|
|
|
config STENO_DICT_MPHF
|
|
bool
|
|
default y if !STENO_DICT_V4
|
|
select ZLIB
|
|
help
|
|
Legacy MPHF (minimal perfect hash) dictionary format.
|
|
Selects ZLIB for block-compressed string table decompression.
|
|
|
|
config STENO_CUSTOM_KEYMAP
|
|
bool "Custom steno keymap"
|
|
default n
|
|
|
|
choice STENO_UNICODE_MODE
|
|
prompt "Unicode output mode"
|
|
default STENO_UNICODE_MODE_NONE
|
|
|
|
config STENO_UNICODE_MODE_NONE
|
|
bool "None (HID only)"
|
|
|
|
config STENO_UNICODE_MODE_LINUX
|
|
bool "Linux (IBus)"
|
|
|
|
config STENO_UNICODE_MODE_MACOS
|
|
bool "macOS"
|
|
|
|
config STENO_UNICODE_MODE_WINC
|
|
bool "Windows (WinCompose)"
|
|
|
|
endchoice
|
|
|
|
config STENO_HISTORY_SIZE
|
|
int "Stroke history size (undo depth)"
|
|
default 100
|
|
range 10 500
|
|
|
|
config STENO_KEY_DELAY_MS
|
|
int "Key output delay (ms)"
|
|
default 0
|
|
range 0 50
|
|
|
|
config STENO_MULTI_STROKE_TIMEOUT_MS
|
|
int "Multi-stroke timeout (ms)"
|
|
default 500
|
|
range 100 5000
|
|
|
|
config STENO_DICT_MAX_SIZE
|
|
int "Max dictionary binary size (bytes)"
|
|
depends on !STENO_DICT_V4
|
|
default 473088
|
|
help
|
|
Max compiled dict size for legacy MPHF single-blob builds.
|
|
473088 = 462KB. Build FAILS if the dict exceeds this —
|
|
entries are never trimmed.
|
|
|
|
menuconfig STENO_SPLIT_DICT
|
|
bool "Split dictionary across both halves"
|
|
default n
|
|
help
|
|
Store the steno dictionary across both keyboard halves.
|
|
v4 format: left (central) holds the lookup structures
|
|
(displacements, membership, fingerprints, conflicts, part of
|
|
the value index); right (peripheral) holds the string table,
|
|
queried over BLE. Legacy MPHF format: entries partitioned by
|
|
importance, right half queried over BLE on local miss.
|
|
Build FAILS if either half exceeds its budget — entries are
|
|
never trimmed.
|
|
|
|
if STENO_SPLIT_DICT
|
|
|
|
config STENO_DICT_LEFT_MAX_SIZE
|
|
int "Left half dict budget (bytes)"
|
|
default 440320
|
|
help
|
|
Flash budget for the left (central) half blob. Default
|
|
440320 = 430KB. Build FAILS if the compiled blob exceeds
|
|
this — entries are never trimmed.
|
|
|
|
config STENO_DICT_RIGHT_MAX_SIZE
|
|
int "Right half dict budget (bytes)"
|
|
default 527360
|
|
help
|
|
Flash budget for the right (peripheral) half blob. Default
|
|
527360 = 515KB. Build FAILS if the compiled blob exceeds
|
|
this — entries are never trimmed.
|
|
|
|
config STENO_SPLIT_CACHE_SIZE
|
|
int "LRU cache entries on central side"
|
|
default 64
|
|
range 16 512
|
|
|
|
config STENO_SPLIT_PREFETCH
|
|
bool "Prefetch common follow-up strokes"
|
|
default y
|
|
|
|
config STENO_SPLIT_TIMEOUT_MS
|
|
int "BLE lookup timeout (ms)"
|
|
default 50
|
|
range 10 500
|
|
|
|
config STENO_SPLIT_LOG_LEVEL
|
|
int "Split dict log level"
|
|
default 3
|
|
|
|
endif # STENO_SPLIT_DICT
|
|
|
|
endif # STENO_ENGINE
|