engine: the Hanja search composes from its seed, and Escape gives it back
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.
This commit is contained in:
@@ -38,7 +38,8 @@ syllable and goes on to the application, so it still leaves insert mode.
|
|||||||
Hiragana mode composes a complete reading before offering Kanji candidates.
|
Hiragana mode composes a complete reading before offering Kanji candidates.
|
||||||
Katakana mode does not perform Kanji conversion. Emoji and Hanja searches
|
Katakana mode does not perform Kanji conversion. Emoji and Hanja searches
|
||||||
return to the previous mode after use; switching language during a search
|
return to the previous mode after use; switching language during a search
|
||||||
commits the shown query. The Emoji search matches the typed keys, and what
|
commits the shown query; `Esc` in a Hanja search gives the syllable back
|
||||||
|
to the composition. The Emoji search matches the typed keys, and what
|
||||||
they spell in the current language, against a prefix of every emoji's
|
they spell in the current language, against a prefix of every emoji's
|
||||||
CLDR name and keywords in English, Korean, and Japanese, and against ASCII
|
CLDR name and keywords in English, Korean, and Japanese, and against ASCII
|
||||||
symbol aliases such as `->` and `<=`. `Ctrl+H` takes the syllable being composed as its
|
symbol aliases such as `->` and `<=`. `Ctrl+H` takes the syllable being composed as its
|
||||||
|
|||||||
2
fn.h
2
fn.h
@@ -31,7 +31,7 @@ void popuplayout(Drawcmd*, int, int, Popup*);
|
|||||||
void popupdraw(u32int*, Drawcmd*, Popup*);
|
void popupdraw(u32int*, Drawcmd*, Popup*);
|
||||||
void imthread(void*);
|
void imthread(void*);
|
||||||
void impre(Im*, Str*);
|
void impre(Im*, Str*);
|
||||||
void transstr(Lang*, Str*, Str*);
|
void transstr(Lang*, Str*, Str*, Str*);
|
||||||
Emit transmap(Im*, Rune);
|
Emit transmap(Im*, Rune);
|
||||||
Emit transko(Im*, Rune);
|
Emit transko(Im*, Rune);
|
||||||
Emit transvi(Im*, Rune);
|
Emit transvi(Im*, Rune);
|
||||||
|
|||||||
30
strans.c
30
strans.c
@@ -526,21 +526,27 @@ foldascii(Str *s)
|
|||||||
s->r[i] += 'a' - 'A';
|
s->r[i] += 'a' - 'A';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* What typing raw in language l would produce, composition included. */
|
/*
|
||||||
|
* What typing raw in language l would produce, composition included,
|
||||||
|
* after pre, which may be nil, was already pending.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
transstr(Lang *l, Str *raw, Str *out)
|
transstr(Lang *l, Str *pre, Str *raw, Str *out)
|
||||||
{
|
{
|
||||||
Im q;
|
Im q;
|
||||||
Emit e;
|
Emit e;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
sclear(out);
|
|
||||||
if(l->trans == nil){
|
|
||||||
*out = *raw;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memset(&q, 0, sizeof q);
|
memset(&q, 0, sizeof q);
|
||||||
q.l = l;
|
q.l = l;
|
||||||
|
if(pre != nil)
|
||||||
|
q.pre = *pre;
|
||||||
|
sclear(out);
|
||||||
|
if(l->trans == nil){
|
||||||
|
sappend(out, &q.pre);
|
||||||
|
sappend(out, raw);
|
||||||
|
return;
|
||||||
|
}
|
||||||
for(i = 0; i < raw->n; i++){
|
for(i = 0; i < raw->n; i++){
|
||||||
e = l->trans(&q, raw->r[i]);
|
e = l->trans(&q, raw->r[i]);
|
||||||
sappend(out, &e.s);
|
sappend(out, &e.s);
|
||||||
@@ -561,7 +567,7 @@ emojiquery(void)
|
|||||||
|
|
||||||
raw = search.raw;
|
raw = search.raw;
|
||||||
foldascii(&raw);
|
foldascii(&raw);
|
||||||
transstr(im.l, &search.raw, &local);
|
transstr(im.l, nil, &search.raw, &local);
|
||||||
foldascii(&local);
|
foldascii(&local);
|
||||||
clearkouho();
|
clearkouho();
|
||||||
n = dictlookup(getlang(LangEMOJI), &raw, kouho, Maxkouho);
|
n = dictlookup(getlang(LangEMOJI), &raw, kouho, Maxkouho);
|
||||||
@@ -579,14 +585,11 @@ emojiquery(void)
|
|||||||
selectfirst();
|
selectfirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The keys typed since Ctrl+H go on composing from the seed. */
|
||||||
static void
|
static void
|
||||||
hanjaquery(void)
|
hanjaquery(void)
|
||||||
{
|
{
|
||||||
Str key;
|
transstr(im.l, &search.seed, &search.raw, &search.text);
|
||||||
|
|
||||||
transstr(im.l, &search.raw, &key);
|
|
||||||
search.text = search.seed;
|
|
||||||
sappend(&search.text, &key);
|
|
||||||
clearkouho();
|
clearkouho();
|
||||||
im.nkouho = dictlookup(getlang(LangHANJA), &search.text, im.kouho,
|
im.nkouho = dictlookup(getlang(LangHANJA), &search.text, im.kouho,
|
||||||
Maxkouho);
|
Maxkouho);
|
||||||
@@ -711,6 +714,7 @@ searchkey(u32int ks, u32int mod, Str *com)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(ks == Kesc){
|
if(ks == Kesc){
|
||||||
|
im.pre = search.seed; /* the syllable Ctrl+H took is pending again */
|
||||||
endsearch();
|
endsearch();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1101,7 +1101,7 @@ engine_japanese_readings(struct ct *t)
|
|||||||
}
|
}
|
||||||
for(i = 0; i < nelem(replay); i++){
|
for(i = 0; i < nelem(replay); i++){
|
||||||
raw = mkstr(replay[i].raw);
|
raw = mkstr(replay[i].raw);
|
||||||
transstr(getlang(LangJP), &raw, &shown);
|
transstr(getlang(LangJP), nil, &raw, &shown);
|
||||||
checkstr(t, replay[i].raw, replay[i].want, &shown);
|
checkstr(t, replay[i].raw, replay[i].want, &shown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1891,6 +1891,25 @@ engine_hanja_backspace(struct ct *t)
|
|||||||
CT_CHECK(t, keystroke(Kback, 0, &com));
|
CT_CHECK(t, keystroke(Kback, 0, &com));
|
||||||
CT_EQ_INT(t, 0, search.lang);
|
CT_EQ_INT(t, 0, search.lang);
|
||||||
CT_EQ_INT(t, LangKO, im.l->lang);
|
CT_EQ_INT(t, LangKO, im.l->lang);
|
||||||
|
/* Escape gives the seed back; keys typed compose from it. */
|
||||||
|
if(!typekeys(t, "gks", &com))
|
||||||
|
goto cleanup;
|
||||||
|
CT_CHECK(t, keystroke('h', Mctrl, &com));
|
||||||
|
CT_CHECK(t, keystroke(Kesc, 0, &com));
|
||||||
|
CT_EQ_INT(t, 0, search.lang);
|
||||||
|
checkstr(t, "seed pending again", "한", &im.pre);
|
||||||
|
checkstr(t, "nothing committed", "", &com);
|
||||||
|
CT_CHECK(t, keystroke(Kback, 0, &com));
|
||||||
|
CT_CHECK(t, keystroke('h', Mctrl, &com));
|
||||||
|
checkstr(t, "seed 하", "하", &search.text);
|
||||||
|
CT_CHECK(t, keystroke('s', 0, &com));
|
||||||
|
checkstr(t, "key composes with the seed", "한", &search.text);
|
||||||
|
CT_EQ_INT(t, 2, im.nkouho);
|
||||||
|
CT_CHECK(t, keystroke(Kesc, 0, &com));
|
||||||
|
checkstr(t, "seed alone comes back", "하", &im.pre);
|
||||||
|
CT_CHECK(t, !keystroke(Kesc, 0, &com));
|
||||||
|
checkstr(t, "Korean Escape commits", "하", &com);
|
||||||
|
CT_EQ_INT(t, 0, im.pre.n);
|
||||||
cleanup:
|
cleanup:
|
||||||
searchend(&f);
|
searchend(&f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ kotrans(char *keys)
|
|||||||
Str out, raw;
|
Str out, raw;
|
||||||
|
|
||||||
raw = mkstr(keys);
|
raw = mkstr(keys);
|
||||||
transstr(getlang(LangKO), &raw, &out);
|
transstr(getlang(LangKO), nil, &raw, &out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ typevi(struct ct *t, char *keys, char *want)
|
|||||||
Str out, raw;
|
Str out, raw;
|
||||||
|
|
||||||
raw = mkstr(keys);
|
raw = mkstr(keys);
|
||||||
transstr(&testvi, &raw, &out);
|
transstr(&testvi, nil, &raw, &out);
|
||||||
checkstr(t, keys, want, &out);
|
checkstr(t, keys, want, &out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user