fix: correct Katakana composition

This commit is contained in:
2026-08-12 15:29:35 +09:00
parent ec7e6eb992
commit 6dfbc08704
5 changed files with 62 additions and 3 deletions

View File

@@ -33,7 +33,6 @@ sho ショ
syo ショ syo ショ
ja ジャ ja ジャ
ju ジュ ju ジュ
je ジェ
jo ジョ jo ジョ
su ス su ス
zu ズ zu ズ
@@ -119,6 +118,7 @@ xn ン
v ヴ v ヴ
xa ァ xa ァ
xi ィ xi ィ
xu ゥ
xe ェ xe ェ
xo ォ xo ォ
cc ッ cc ッ
@@ -128,7 +128,6 @@ pp ッ
tt ッ tt ッ
tch ッ tch ッ
ss ッ ss ッ
xn ン
di ディ di ディ
fa ファ fa ファ
fi フィ fi フィ
@@ -136,6 +135,7 @@ fe フェ
fo フォ fo フォ
va ヴァ va ヴァ
vi ヴィ vi ヴィ
vu ヴ
ve ヴェ ve ヴェ
vo ヴォ vo ヴォ
. 。 . 。

View File

@@ -27,7 +27,7 @@ backmap(Im *im)
Lang langs[] = { Lang langs[] = {
{LangEN, "english", nil, transmap, backmap, dictqmap, nil, nil}, {LangEN, "english", nil, transmap, backmap, dictqmap, nil, nil},
{LangJP, "hira", "kanji", transmap, backjp, dictqjp, nil, nil}, {LangJP, "hira", "kanji", transmap, backjp, dictqjp, nil, nil},
{LangJPK, "kata", "kanji", transmap, backjp, dictqjp, nil, nil}, {LangJPK, "kata", nil, transmap, backjp, dictqjp, nil, nil},
{LangKO, "hangul", nil, transko, backko, dictqmap, nil, nil}, {LangKO, "hangul", nil, transko, backko, dictqmap, nil, nil},
{LangEMOJI, nil, "emoji", nil, nil, nil, nil, nil}, {LangEMOJI, nil, "emoji", nil, nil, nil, nil, nil},
{LangVI, "telex", nil, transvi, backvi, dictqmap, nil, nil}, {LangVI, "telex", nil, transvi, backvi, dictqmap, nil, nil},
@@ -213,6 +213,23 @@ backjp(Im *im)
spopr(&im->pre); spopr(&im->pre);
} }
static int
issmalltsu(Str *s)
{
return s->n == 1 && (s->r[0] == L'' || s->r[0] == L'');
}
static void
keeptail(Str *s)
{
int i;
for(i = 1; i < s->n; i++)
s->r[i-1] = s->r[i];
if(s->n > 0)
s->n--;
}
static int static int
dotransjp(Rune c, Str *com) dotransjp(Rune c, Str *com)
{ {
@@ -228,8 +245,13 @@ dotransjp(Rune c, Str *com)
key = im.raw; key = im.raw;
if(key.n < Maxrunes) if(key.n < Maxrunes)
sputr(&key, c); sputr(&key, c);
sclear(&mapped);
if(maplookup(im.l->map, &key, &mapped)){ if(maplookup(im.l->map, &key, &mapped)){
im.raw = key; im.raw = key;
if(issmalltsu(&mapped)){
sappend(&im.pre, &mapped);
keeptail(&im.raw);
}
dictqjp(&im); dictqjp(&im);
return 1; return 1;
} }

View File

@@ -481,6 +481,41 @@ engine_japanese_backspace_and_boundaries(struct ct *t)
} }
} }
void
engine_katakana_sequences(struct ct *t)
{
static const struct {
char *keys;
char *want;
} cases[] = {
{ "kitte", "キッテ" },
{ "katta", "カッタ" },
{ "gakkou", "ガッコウ" },
{ "matcha", "マッチャ" },
{ "xu", "" },
{ "vu", "" },
};
Dictreq req;
Str com, shown;
int i;
newestrequest(&req);
for(i = 0; i < nelem(cases); i++){
init();
im.l = getlang(LangJPK);
sclear(&com);
if(!typekeys(t, cases[i].keys, &com))
continue;
checkstr(t, cases[i].keys, "", &com);
shown = shownpre(&im);
checkstr(t, cases[i].keys, cases[i].want, &shown);
CT_CHECK(t, keystroke(Kret, 0, &com));
checkstr(t, "committed Katakana", cases[i].want, &com);
}
CT_EQ_INT(t, 0, newestrequest(&req));
CT_EQ_PTR(t, nil, getlang(LangJPK)->dictname);
}
void void
engine_emoji_single_candidate(struct ct *t) engine_emoji_single_candidate(struct ct *t)
{ {

View File

@@ -36,6 +36,7 @@ void engine_telex_history_bound(struct ct*);
void engine_japanese_readings(struct ct*); void engine_japanese_readings(struct ct*);
void engine_japanese_candidates(struct ct*); void engine_japanese_candidates(struct ct*);
void engine_japanese_backspace_and_boundaries(struct ct*); void engine_japanese_backspace_and_boundaries(struct ct*);
void engine_katakana_sequences(struct ct*);
void engine_emoji_single_candidate(struct ct*); void engine_emoji_single_candidate(struct ct*);
void engine_emoji_queries(struct ct*); void engine_emoji_queries(struct ct*);
void engine_emoji_digit_aliases(struct ct*); void engine_emoji_digit_aliases(struct ct*);

View File

@@ -85,6 +85,7 @@ static const struct ct_test tests[] = {
{ "engine/japanese-readings", engine_japanese_readings }, { "engine/japanese-readings", engine_japanese_readings },
{ "engine/japanese-candidates", engine_japanese_candidates }, { "engine/japanese-candidates", engine_japanese_candidates },
{ "engine/japanese-backspace-boundaries", engine_japanese_backspace_and_boundaries }, { "engine/japanese-backspace-boundaries", engine_japanese_backspace_and_boundaries },
{ "engine/katakana-sequences", engine_katakana_sequences },
{ "engine/emoji-single-candidate", engine_emoji_single_candidate }, { "engine/emoji-single-candidate", engine_emoji_single_candidate },
{ "engine/emoji-queries", engine_emoji_queries }, { "engine/emoji-queries", engine_emoji_queries },
{ "engine/emoji-digit-aliases", engine_emoji_digit_aliases }, { "engine/emoji-digit-aliases", engine_emoji_digit_aliases },