Ctrl+H took the pending syllable as the query, but the keys typed after
it started a composition of their own: gk, Ctrl+H, s showed 하ㄴ, and r,
Ctrl+H, k showed ㄱㅏ. transstr now composes from a pending text, so
the search goes on where the syllable left off. Escape ended the search
and dropped the syllable it had taken; it puts it back as pending text.
libhangul, and so fcitx5-hangul, joins two lone consonants into the
compound jong they make (rt → ㄳ, split again by a vowel: rtk → ㄱ사),
and by default reorders a vowel typed before its consonant (kr → 가);
strans committed the first jamo and started over. Backspace on a lone
ㄳ leaves ㄱ, as on a syllable.
The three jamo index tables and their -1 macros were the cho, jung, and
jong arrays inverted by hand, bounded by a Jrange the callers had to
respect; a linear scan of the arrays says the same in ten lines.
server_test, ibus_test and xim_adapter_test each ran their own copy of
the same alt loop that stands in for imthread, and two of them had
private checkstr/checkenginepreedit variants. test_util.c now provides
Pump (trace, optional hold on a chosen op, stop) in its own proc so a
test may block in socket I/O while the engine runs, and test.h declares
the engine hooks once; every .c includes dat.h and fn.h itself as the
rest of the tree does. server_test's three copies of fixture setup and
teardown became serverbegin/serverend.
ko_test and vi_test replayed keys with private copies of transstr's
loop, and test_util reimplemented the shown preedit; the engine exports
impre(Im*, Str*) and transstr() instead, so a change to composition
rules is one edit.