fix(engine): keep composing when a reading reaches Maxrunes

At the limit the key that did not fit was handed back to the client as
plain ASCII, so a long Japanese reading ended in a Latin letter, and a
pending romaji consonant was flushed as ASCII with it (…あka for か).
Commit the completed kana, keep the pending syllable, and transliterate
the key as usual; other languages commit and go on the same way.
This commit is contained in:
2026-08-16 20:25:38 +09:00
parent cdd3e38195
commit 9853d65d4c
2 changed files with 21 additions and 4 deletions

View File

@@ -751,9 +751,13 @@ transition(u32int ks, u32int mod, Str *com)
return 0; return 0;
if(im.pre.n >= Maxrunes || if(im.pre.n >= Maxrunes ||
(isjp(&im) && im.pre.n + im.raw.n >= Maxrunes)){ (isjp(&im) && im.pre.n + im.raw.n >= Maxrunes)){
commit(com); /* A full reading commits; a pending romaji syllable stays. */
reset(); if(isjp(&im))
return 0; sappend(com, &im.pre);
else
commit(com);
sclear(&im.pre);
clearkouho();
} }
return dotrans(ks, com); return dotrans(ks, com);
} }

View File

@@ -1904,7 +1904,7 @@ engine_randomized_stress(struct ct *t)
void void
engine_full_boundary_passthrough(struct ct *t) engine_full_boundary_passthrough(struct ct *t)
{ {
Str com; Str com, shown;
int i; int i;
init(); init();
@@ -1929,4 +1929,17 @@ engine_full_boundary_passthrough(struct ct *t)
CT_CHECK(t, keystroke(' ', 0, &com)); CT_CHECK(t, keystroke(' ', 0, &com));
CT_EQ_INT(t, Maxrunes, com.n); CT_EQ_INT(t, Maxrunes, com.n);
CT_EQ_UINT(t, ' ', com.r[Maxrunes-1]); CT_EQ_UINT(t, ' ', com.r[Maxrunes-1]);
/* Typing on at the limit commits the kana and keeps the syllable. */
init();
im.l = getlang(LangJP);
for(i = 0; i < Maxrunes-1; i++)
im.pre.r[i] = L'';
im.pre.n = Maxrunes-1;
im.raw = mkstr("k");
sclear(&com);
CT_CHECK(t, keystroke('a', 0, &com));
CT_EQ_INT(t, Maxrunes-1, com.n);
impre(&im, &shown);
checkstr(t, "syllable after the flush", "", &shown);
} }