hanja: add one-shot Korean search
This commit is contained in:
@@ -421,10 +421,10 @@ engine_direct_language_modes(struct ct *t)
|
||||
CT_EQ_INT(t, 0, im.pre.n);
|
||||
CT_EQ_INT(t, 0, im.raw.n);
|
||||
CT_CHECK(t, keystroke('e', Mctrl, &com));
|
||||
CT_CHECK(t, search.on);
|
||||
CT_CHECK(t, search.kind);
|
||||
CT_EQ_INT(t, LangEN, im.l->lang);
|
||||
CT_CHECK(t, keystroke(Kesc, 0, &com));
|
||||
CT_CHECK(t, !search.on);
|
||||
CT_CHECK(t, !search.kind);
|
||||
CT_CHECK(t, keystroke('s', Mctrl, &com));
|
||||
CT_EQ_INT(t, LangKO, im.l->lang);
|
||||
CT_EQ_PTR(t, nil, im.l->mapname);
|
||||
@@ -535,7 +535,7 @@ draindraw(Drawcmd *last)
|
||||
}
|
||||
|
||||
static void
|
||||
setemoji(Hmap **dict, char *key, char *val)
|
||||
setdict(Hmap **dict, char *key, char *val)
|
||||
{
|
||||
Str s;
|
||||
|
||||
@@ -556,21 +556,21 @@ emojibegin(Emojifix *f, int showpre)
|
||||
f->visible = visible;
|
||||
draindraw(nil);
|
||||
l->dict = hmapalloc(32);
|
||||
setemoji(&l->dict, "a", "A B");
|
||||
setemoji(&l->dict, "ㅁ", "B C");
|
||||
setemoji(&l->dict, "alpha", "α");
|
||||
setemoji(&l->dict, "smil", "😀 😄");
|
||||
setemoji(&l->dict, "smile", "😀 😄");
|
||||
setemoji(&l->dict, "웃음", "😀 😄 😂");
|
||||
setemoji(&l->dict, "えがお", "😀 😄 😊");
|
||||
setemoji(&l->dict, "エガオ", "😀 😄 😊");
|
||||
setemoji(&l->dict, "heart", "❤️");
|
||||
setemoji(&l->dict, "coffee", "☕️");
|
||||
setemoji(&l->dict, "^", "¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁽");
|
||||
setemoji(&l->dict, "^0", "⁰");
|
||||
setemoji(&l->dict, "_", "₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₍");
|
||||
setemoji(&l->dict, "<", "← ≤ ♥ ≠");
|
||||
setemoji(&l->dict, "many",
|
||||
setdict(&l->dict, "a", "A B");
|
||||
setdict(&l->dict, "ㅁ", "B C");
|
||||
setdict(&l->dict, "alpha", "α");
|
||||
setdict(&l->dict, "smil", "😀 😄");
|
||||
setdict(&l->dict, "smile", "😀 😄");
|
||||
setdict(&l->dict, "웃음", "😀 😄 😂");
|
||||
setdict(&l->dict, "えがお", "😀 😄 😊");
|
||||
setdict(&l->dict, "エガオ", "😀 😄 😊");
|
||||
setdict(&l->dict, "heart", "❤️");
|
||||
setdict(&l->dict, "coffee", "☕️");
|
||||
setdict(&l->dict, "^", "¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁽");
|
||||
setdict(&l->dict, "^0", "⁰");
|
||||
setdict(&l->dict, "_", "₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₍");
|
||||
setdict(&l->dict, "<", "← ≤ ♥ ≠");
|
||||
setdict(&l->dict, "many",
|
||||
"c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12");
|
||||
init();
|
||||
im.l = getlang(LangKO);
|
||||
@@ -594,6 +594,52 @@ emojiend(Emojifix *f)
|
||||
visible = f->visible;
|
||||
}
|
||||
|
||||
typedef struct Hanjafix Hanjafix;
|
||||
struct Hanjafix
|
||||
{
|
||||
Im im;
|
||||
Search search;
|
||||
Hmap *dict;
|
||||
int popup;
|
||||
int visible;
|
||||
};
|
||||
|
||||
static void
|
||||
hanjabegin(Hanjafix *f)
|
||||
{
|
||||
Lang *l;
|
||||
|
||||
l = getlang(LangKO);
|
||||
f->im = im;
|
||||
f->search = search;
|
||||
f->dict = l->dict;
|
||||
f->popup = popup;
|
||||
f->visible = visible;
|
||||
draindraw(nil);
|
||||
l->dict = hmapalloc(8);
|
||||
setdict(&l->dict, "한", "漢 韓");
|
||||
setdict(&l->dict, "가", "家");
|
||||
init();
|
||||
im.l = l;
|
||||
}
|
||||
|
||||
static void
|
||||
hanjaend(Hanjafix *f)
|
||||
{
|
||||
Lang *l;
|
||||
Hmap *dict;
|
||||
|
||||
l = getlang(LangKO);
|
||||
dict = l->dict;
|
||||
l->dict = f->dict;
|
||||
hmapfree(dict);
|
||||
draindraw(nil);
|
||||
im = f->im;
|
||||
search = f->search;
|
||||
popup = f->popup;
|
||||
visible = f->visible;
|
||||
}
|
||||
|
||||
static int
|
||||
typekeys(struct ct *t, char *keys, Str *com)
|
||||
{
|
||||
@@ -779,12 +825,12 @@ engine_emoji_single_candidate(struct ct *t)
|
||||
CT_CHECK(t, keystroke('p', Mctrl, &com));
|
||||
CT_EQ_INT(t, 0, popup);
|
||||
CT_CHECK(t, keystroke('e', Mctrl, &com));
|
||||
CT_CHECK(t, search.on);
|
||||
CT_CHECK(t, search.kind);
|
||||
CT_EQ_INT(t, LangKO, im.l->lang);
|
||||
if(typekeys(t, "alpha", &com)){
|
||||
checkstr(t, "no automatic commit", "", &com);
|
||||
checkstr(t, "raw English query", "alpha", &search.text);
|
||||
CT_CHECK(t, search.on);
|
||||
CT_CHECK(t, search.kind);
|
||||
CT_EQ_INT(t, 1, im.nkouho);
|
||||
checkstr(t, "single candidate", "α", &im.kouho[0]);
|
||||
CT_CHECK(t, draindraw(&dc) > 0);
|
||||
@@ -792,7 +838,7 @@ engine_emoji_single_candidate(struct ct *t)
|
||||
CT_EQ_INT(t, 1, dc.nkouho);
|
||||
CT_CHECK(t, keystroke(Kret, 0, &com));
|
||||
checkstr(t, "explicit candidate commit", "α", &com);
|
||||
CT_CHECK(t, !search.on);
|
||||
CT_CHECK(t, !search.kind);
|
||||
CT_EQ_INT(t, LangKO, im.l->lang);
|
||||
show();
|
||||
CT_CHECK(t, draindraw(&dc) > 0);
|
||||
@@ -854,7 +900,7 @@ engine_emoji_queries(struct ct *t)
|
||||
CT_EQ_INT(t, 3, dc.nkouho);
|
||||
CT_CHECK(t, keystroke(Kesc, 0, &com));
|
||||
checkstr(t, "cancel commit", "", &com);
|
||||
CT_CHECK(t, !search.on);
|
||||
CT_CHECK(t, !search.kind);
|
||||
CT_EQ_INT(t, LangKO, im.l->lang);
|
||||
}
|
||||
emojiend(&f);
|
||||
@@ -932,7 +978,7 @@ engine_emoji_digit_aliases(struct ct *t)
|
||||
CT_CHECK(t, im.nkouho >= cases[i].digit - '0');
|
||||
CT_CHECK(t, keystroke(cases[i].digit, 0, &com));
|
||||
checkstr(t, cases[i].name, cases[i].want, &com);
|
||||
CT_CHECK(t, !search.on);
|
||||
CT_CHECK(t, !search.kind);
|
||||
CT_EQ_INT(t, LangKO, im.l->lang);
|
||||
}
|
||||
|
||||
@@ -952,7 +998,7 @@ engine_emoji_digit_aliases(struct ct *t)
|
||||
CT_CHECK(t, keystroke('9', 0, &com));
|
||||
checkstr(t, "missing number query", "smile9", &search.text);
|
||||
checkstr(t, "missing number commit", "", &com);
|
||||
CT_CHECK(t, search.on);
|
||||
CT_CHECK(t, search.kind);
|
||||
CT_EQ_INT(t, 0, im.nkouho);
|
||||
CT_CHECK(t, keystroke(Kret, 0, &com));
|
||||
checkstr(t, "missing number text", "smile9", &com);
|
||||
@@ -1028,19 +1074,26 @@ engine_emoji_preedit_languages(struct ct *t)
|
||||
checkstr(t, "modifier preserves Japanese", "か", &shown);
|
||||
CT_CHECK(t, keystroke('E', Mctrl|Mshift, &com));
|
||||
checkstr(t, "committed Japanese preedit", "か", &com);
|
||||
CT_CHECK(t, search.on);
|
||||
CT_CHECK(t, search.kind);
|
||||
CT_EQ_INT(t, LangJP, im.l->lang);
|
||||
CT_CHECK(t, keystroke('E', Mctrl|Malt, &com));
|
||||
CT_EQ_INT(t, SearchOff, search.kind);
|
||||
CT_CHECK(t, keystroke('E', Mctrl|Mshift, &com));
|
||||
CT_CHECK(t, keystroke('E', Mctrl|Msuper, &com));
|
||||
CT_EQ_INT(t, SearchOff, search.kind);
|
||||
CT_CHECK(t, keystroke('E', Mctrl|Mshift, &com));
|
||||
CT_EQ_INT(t, LangJP, im.l->lang);
|
||||
CT_CHECK(t, keystroke('a', 0, &com));
|
||||
p = popup;
|
||||
CT_CHECK(t, !keystroke(Kmodfirst+2, 0, &com));
|
||||
CT_CHECK(t, search.on);
|
||||
CT_CHECK(t, search.kind);
|
||||
checkstr(t, "modifier preserves search", "a", &search.text);
|
||||
CT_CHECK(t, keystroke('P', Mctrl|Mshift, &com));
|
||||
CT_EQ_INT(t, !p, popup);
|
||||
CT_CHECK(t, search.on);
|
||||
CT_CHECK(t, search.kind);
|
||||
CT_CHECK(t, !keystroke(Kmodfirst+2, 0, &com));
|
||||
CT_CHECK(t, keystroke('E', Mctrl|Mshift, &com));
|
||||
CT_CHECK(t, !search.on);
|
||||
CT_CHECK(t, !search.kind);
|
||||
sclear(&com);
|
||||
if(typekeys(t, "na", &com)){
|
||||
shown = shownpre(&im);
|
||||
@@ -1070,7 +1123,7 @@ engine_emoji_preedit_languages(struct ct *t)
|
||||
CT_CHECK(t, keystroke('e', Mctrl, &com));
|
||||
checkstr(t, "committed Telex preedit", "á", &com);
|
||||
CT_CHECK(t, keystroke(Kesc, 0, &com));
|
||||
CT_CHECK(t, !search.on);
|
||||
CT_CHECK(t, !search.kind);
|
||||
CT_EQ_PTR(t, &testvi, im.l);
|
||||
sclear(&com);
|
||||
if(typekeys(t, "as", &com)){
|
||||
@@ -1095,14 +1148,14 @@ engine_emoji_start_and_unknown(struct ct *t)
|
||||
if(typekeys(t, "dkssud", &com)){
|
||||
CT_CHECK(t, keystroke('e', Mctrl, &com));
|
||||
checkstr(t, "committed Korean preedit", "안녕", &com);
|
||||
CT_CHECK(t, search.on);
|
||||
CT_CHECK(t, search.kind);
|
||||
CT_EQ_INT(t, LangKO, im.l->lang);
|
||||
if(typekeys(t, "xyz", &com)){
|
||||
checkstr(t, "unknown displayed query", "xyz", &search.text);
|
||||
CT_EQ_INT(t, 0, im.nkouho);
|
||||
CT_CHECK(t, keystroke(Kret, 0, &com));
|
||||
checkstr(t, "unknown query commit", "안녕xyz", &com);
|
||||
CT_CHECK(t, !search.on);
|
||||
CT_CHECK(t, !search.kind);
|
||||
CT_EQ_INT(t, LangKO, im.l->lang);
|
||||
}
|
||||
}
|
||||
@@ -1112,7 +1165,7 @@ engine_emoji_start_and_unknown(struct ct *t)
|
||||
if(typekeys(t, "xyz", &com)){
|
||||
CT_CHECK(t, !keystroke(Kspec|0x51, 0, &com));
|
||||
checkstr(t, "special commits shown query", "xyz", &com);
|
||||
CT_CHECK(t, !search.on);
|
||||
CT_CHECK(t, !search.kind);
|
||||
CT_EQ_INT(t, LangKO, im.l->lang);
|
||||
}
|
||||
|
||||
@@ -1121,12 +1174,12 @@ engine_emoji_start_and_unknown(struct ct *t)
|
||||
for(i = 0; i < Maxrunes; i++)
|
||||
CT_CHECK(t, keystroke('q', 0, &com));
|
||||
CT_EQ_INT(t, Maxrunes, search.raw.n);
|
||||
CT_CHECK(t, search.on);
|
||||
CT_CHECK(t, search.kind);
|
||||
CT_CHECK(t, !keystroke('z', 0, &com));
|
||||
memset(want, 'q', Maxrunes);
|
||||
want[Maxrunes] = '\0';
|
||||
checkstr(t, "bounded query commit", want, &com);
|
||||
CT_CHECK(t, !search.on);
|
||||
CT_CHECK(t, !search.kind);
|
||||
emojiend(&f);
|
||||
}
|
||||
|
||||
@@ -1157,12 +1210,12 @@ engine_emoji_dictionary_identity(struct ct *t)
|
||||
checkstr(t, "wrong preedit ignored", "old", &im.kouho[0]);
|
||||
|
||||
res.key = im.pre;
|
||||
search.on = 1;
|
||||
search.kind = SearchEmoji;
|
||||
dictresult(&res);
|
||||
CT_EQ_INT(t, 1, im.nkouho);
|
||||
checkstr(t, "search response ignored", "old", &im.kouho[0]);
|
||||
|
||||
search.on = 0;
|
||||
search.kind = SearchOff;
|
||||
res.kouho[0] = mkstr("right");
|
||||
dictresult(&res);
|
||||
CT_EQ_INT(t, 1, im.nkouho);
|
||||
@@ -1171,6 +1224,125 @@ engine_emoji_dictionary_identity(struct ct *t)
|
||||
emojiend(&f);
|
||||
}
|
||||
|
||||
void
|
||||
engine_hanja_search(struct ct *t)
|
||||
{
|
||||
Hanjafix f;
|
||||
Str com;
|
||||
|
||||
hanjabegin(&f);
|
||||
sclear(&com);
|
||||
if(!CT_CHECK(t, keystroke('h', Mctrl, &com)))
|
||||
goto cleanup;
|
||||
CT_EQ_INT(t, SearchHanja, search.kind);
|
||||
CT_EQ_INT(t, LangKO, im.l->lang);
|
||||
if(!typekeys(t, "gks", &com))
|
||||
goto cleanup;
|
||||
checkstr(t, "Hanja reading", "한", &search.text);
|
||||
CT_EQ_INT(t, 2, im.nkouho);
|
||||
CT_CHECK(t, keystroke(Kdown, 0, &com));
|
||||
CT_CHECK(t, keystroke(Kdown, 0, &com));
|
||||
CT_CHECK(t, keystroke(Kret, 0, &com));
|
||||
checkstr(t, "navigated Hanja", "韓", &com);
|
||||
CT_EQ_INT(t, SearchOff, search.kind);
|
||||
CT_EQ_INT(t, LangKO, im.l->lang);
|
||||
cleanup:
|
||||
hanjaend(&f);
|
||||
}
|
||||
|
||||
void
|
||||
engine_hanja_unknown_and_cancel(struct ct *t)
|
||||
{
|
||||
Hanjafix f;
|
||||
Str com;
|
||||
|
||||
hanjabegin(&f);
|
||||
sclear(&com);
|
||||
if(!CT_CHECK(t, keystroke('h', Mctrl, &com)))
|
||||
goto cleanup;
|
||||
if(!typekeys(t, "rmf", &com))
|
||||
goto cleanup;
|
||||
checkstr(t, "unknown Hanja reading", "글", &search.text);
|
||||
CT_EQ_INT(t, 0, im.nkouho);
|
||||
CT_CHECK(t, keystroke(Kret, 0, &com));
|
||||
checkstr(t, "unknown Hanja commit", "글", &com);
|
||||
CT_EQ_INT(t, SearchOff, search.kind);
|
||||
CT_EQ_INT(t, LangKO, im.l->lang);
|
||||
|
||||
sclear(&com);
|
||||
if(!CT_CHECK(t, keystroke('h', Mctrl, &com)))
|
||||
goto cleanup;
|
||||
if(!typekeys(t, "gks", &com))
|
||||
goto cleanup;
|
||||
CT_EQ_INT(t, 2, im.nkouho);
|
||||
CT_CHECK(t, keystroke(Kesc, 0, &com));
|
||||
checkstr(t, "cancelled Hanja", "", &com);
|
||||
CT_EQ_INT(t, SearchOff, search.kind);
|
||||
CT_EQ_INT(t, LangKO, im.l->lang);
|
||||
|
||||
sclear(&com);
|
||||
CT_CHECK(t, keystroke('h', Mctrl, &com));
|
||||
CT_EQ_INT(t, SearchHanja, search.kind);
|
||||
CT_CHECK(t, keystroke('h', Mctrl, &com));
|
||||
CT_EQ_INT(t, SearchOff, search.kind);
|
||||
cleanup:
|
||||
hanjaend(&f);
|
||||
}
|
||||
|
||||
void
|
||||
engine_hanja_korean_keys(struct ct *t)
|
||||
{
|
||||
Hanjafix f;
|
||||
Str com;
|
||||
|
||||
hanjabegin(&f);
|
||||
sclear(&com);
|
||||
CT_CHECK(t, keystroke('h', Mctrl, &com));
|
||||
CT_CHECK(t, keystroke('r', Mshift, &com));
|
||||
CT_CHECK(t, keystroke('k', 0, &com));
|
||||
checkstr(t, "shifted Hanja reading", "까", &search.text);
|
||||
CT_CHECK(t, keystroke(Kesc, 0, &com));
|
||||
|
||||
CT_CHECK(t, keystroke('h', Mctrl, &com));
|
||||
CT_CHECK(t, keystroke('R', 0, &com));
|
||||
CT_CHECK(t, keystroke('k', 0, &com));
|
||||
checkstr(t, "Caps Lock Hanja reading", "가", &search.text);
|
||||
CT_EQ_INT(t, 1, im.nkouho);
|
||||
CT_CHECK(t, keystroke(Kesc, 0, &com));
|
||||
hanjaend(&f);
|
||||
}
|
||||
|
||||
void
|
||||
engine_hanja_korean_only(struct ct *t)
|
||||
{
|
||||
Hmap *dict;
|
||||
Lang *l;
|
||||
Str com, shown;
|
||||
|
||||
init();
|
||||
im.l = getlang(LangJP);
|
||||
sclear(&com);
|
||||
if(typekeys(t, "ka", &com)){
|
||||
CT_CHECK(t, !keystroke('h', Mctrl, &com));
|
||||
CT_CHECK(t, !search.kind);
|
||||
CT_EQ_INT(t, LangJP, im.l->lang);
|
||||
shown = shownpre(&im);
|
||||
checkstr(t, "non-Korean Ctrl-H reset", "", &shown);
|
||||
checkstr(t, "non-Korean Ctrl-H commit", "", &com);
|
||||
}
|
||||
|
||||
l = getlang(LangKO);
|
||||
dict = l->dict;
|
||||
l->dict = nil;
|
||||
init();
|
||||
im.l = l;
|
||||
sclear(&com);
|
||||
CT_CHECK(t, keystroke('h', Mctrl, &com));
|
||||
CT_EQ_INT(t, SearchHanja, search.kind);
|
||||
CT_CHECK(t, keystroke(Kesc, 0, &com));
|
||||
l->dict = dict;
|
||||
}
|
||||
|
||||
static u32int
|
||||
stressrand(u32int *state)
|
||||
{
|
||||
|
||||
@@ -54,6 +54,10 @@ void engine_emoji_navigation(struct ct*);
|
||||
void engine_emoji_preedit_languages(struct ct*);
|
||||
void engine_emoji_start_and_unknown(struct ct*);
|
||||
void engine_emoji_dictionary_identity(struct ct*);
|
||||
void engine_hanja_search(struct ct*);
|
||||
void engine_hanja_unknown_and_cancel(struct ct*);
|
||||
void engine_hanja_korean_keys(struct ct*);
|
||||
void engine_hanja_korean_only(struct ct*);
|
||||
void engine_randomized_stress(struct ct*);
|
||||
void engine_full_boundary_passthrough(struct ct*);
|
||||
void dictionary_candidates(struct ct*);
|
||||
|
||||
@@ -108,6 +108,10 @@ static const struct ct_test tests[] = {
|
||||
{ "engine/emoji-preedit-languages", engine_emoji_preedit_languages },
|
||||
{ "engine/emoji-start-and-unknown", engine_emoji_start_and_unknown },
|
||||
{ "engine/emoji-dictionary-identity", engine_emoji_dictionary_identity },
|
||||
{ "engine/hanja-search", engine_hanja_search },
|
||||
{ "engine/hanja-unknown-cancel", engine_hanja_unknown_and_cancel },
|
||||
{ "engine/hanja-korean-keys", engine_hanja_korean_keys },
|
||||
{ "engine/hanja-korean-only", engine_hanja_korean_only },
|
||||
{ "engine/randomized-stress", engine_randomized_stress },
|
||||
{ "engine/full-boundary-passthrough", engine_full_boundary_passthrough },
|
||||
{ "dict/candidates", dictionary_candidates },
|
||||
|
||||
Reference in New Issue
Block a user