zmk-steno-engine/Kconfig
afiqzudinhadi 9bf21c9db2 v4 union split-section dictionary: both full dicts, zero trimming
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)
2026-07-03 01:28:31 +08:00

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