diff --git a/strans.c b/strans.c index 40ac3d0..04bfcfc 100644 --- a/strans.c +++ b/strans.c @@ -134,12 +134,13 @@ haspre(Im *p) return p->pre.n != 0 || (isjp(p) && p->raw.n != 0); } +/* The preedit as clients see it: Telex keys read back through the map. */ static void impre(Str *s) { if(isjp(&im)) jpreading(&im, s); - else + else if(!mapget(im.l->map, &im.pre, s)) *s = im.pre; } @@ -167,11 +168,8 @@ snapshot(Drawcmd *dc) pre = search.text; else impre(&pre); - if(!(activecap & Cclientpreedit)){ - if(search.lang || isjp(&im) || im.l->map == nil || - !mapget(im.l->map, &pre, &dc->pre)) - dc->pre = pre; - } + if(!(activecap & Cclientpreedit)) + dc->pre = pre; first = pagefirst(); n = im.nkouho - first; if(n > Maxdisp) n = Maxdisp; @@ -220,10 +218,7 @@ dictsend(Im *im, Str *key) req.key = *key; req.lang = im->l->lang; req.seq = dictseq; - if(isjp(im)) - jpreading(im, &req.pre); - else - req.pre = im->pre; + impre(&req.pre); /* imthread is the sole producer; discard every obsolete queued lookup. */ while(channbrecv(dictreqc, &old) > 0) ; diff --git a/tests/engine_test.c b/tests/engine_test.c index be615ea..eb0b6eb 100644 --- a/tests/engine_test.c +++ b/tests/engine_test.c @@ -417,6 +417,51 @@ engine_active_owner_caret(struct ct *t) CT_CHECK(t, !caret.valid); } +void +engine_vietnamese_client_preedit(struct ct *t) +{ + static const struct { + char *keys; + char *shown; + } cases[] = { + { "as", "á" }, + { "aa", "â" }, + { "ddoong", "đông" }, + { "hoaf", "hoà" }, + { "quas", "quá" }, + }; + Drawcmd dc; + Keyres res; + Str com, shown; + char *k, owner; + int i; + + for(i = 0; i < nelem(cases); i++){ + init(); + im.l = &testvi; + draindraw(nil); + sclear(&com); + for(k = cases[i].keys; *k != '\0'; k++){ + res = ownerrequestcap(&owner, Cclientpreedit, + Keypress, *k, 0); + sappend(&com, &res.commit); + if(!res.eaten) + sputr(&com, *k); + } + /* What the client shows, what the popup shows, and what + * Enter commits are the same composed text. */ + shown = com; + sappend(&shown, &res.preedit); + checkstr(t, "client preedit", cases[i].shown, &shown); + activecap = 0; + redraw(); + if(CT_CHECK(t, draindraw(&dc) > 0)) + CT_EQ_INT(t, 0, scmp(&dc.pre, &res.preedit)); + CT_CHECK(t, keystroke(Kret, 0, &com)); + checkstr(t, "commit", cases[i].shown, &com); + } +} + void engine_commit_contract(struct ct *t) { diff --git a/tests/test.h b/tests/test.h index c4e54ad..06cc2e8 100644 --- a/tests/test.h +++ b/tests/test.h @@ -39,6 +39,7 @@ void engine_active_owner_reset(struct ct*); void engine_rejects_stale_dictionary_results(struct ct*); void engine_active_owner_caret(struct ct*); void engine_popup_preedit_capability(struct ct*); +void engine_vietnamese_client_preedit(struct ct*); void engine_commit_contract(struct ct*); void engine_language_switch_state(struct ct*); void engine_telex_history_bound(struct ct*); diff --git a/tests/unit_test.c b/tests/unit_test.c index 501e41c..e0555e4 100644 --- a/tests/unit_test.c +++ b/tests/unit_test.c @@ -94,6 +94,7 @@ static const struct ct_test tests[] = { { "engine/rejects-stale-dictionary", engine_rejects_stale_dictionary_results }, { "engine/active-owner-caret", engine_active_owner_caret }, { "engine/popup-preedit-capability", engine_popup_preedit_capability }, + { "engine/vietnamese-client-preedit", engine_vietnamese_client_preedit }, { "engine/commit-contract", engine_commit_contract }, { "engine/language-switch-state", engine_language_switch_state }, { "engine/telex-history-bound", engine_telex_history_bound },