engine: Shift on the okurigana asks for that reading, as SKK does
kaku offers the twenty-two readings of かく before 書く, because the SKK dictionary keys a verb by its stem and gives no frequency to rank the two lists by. SKK's own answer is the shift key: kaKu says where the okurigana starts, and that split now comes first — the reading's own candidates still follow it. Caps Lock sends no Shift, so it marks nothing, and a word typed without Shift is unchanged.
This commit is contained in:
@@ -39,6 +39,10 @@ current page; before that the digits type. `Enter` commits the chosen candidate,
|
|||||||
reading when none is chosen, as `0` always does; so does typing on, or any
|
reading when none is chosen, as `0` always does; so does typing on, or any
|
||||||
key that ends the composition. `Backspace` deletes the last kana shown;
|
key that ends the composition. `Backspace` deletes the last kana shown;
|
||||||
romaji that made no kana stays in the reading as typed until it is mended.
|
romaji that made no kana stays in the reading as typed until it is mended.
|
||||||
|
The dictionary keys a verb or adjective by its stem, so `kaku` offers the
|
||||||
|
readings of かく and then 書く and its kin; typing the okurigana with
|
||||||
|
`Shift`, as SKK does — `kaKu` — asks for that split first. Caps Lock is
|
||||||
|
not `Shift` and marks nothing.
|
||||||
`Backspace` and `Esc` on a chosen candidate go back to the reading, and
|
`Backspace` and `Esc` on a chosen candidate go back to the reading, and
|
||||||
`Esc` on the reading cancels it. Katakana mode does not perform Kanji
|
`Esc` on the reading cancels it. Katakana mode does not perform Kanji
|
||||||
conversion.
|
conversion.
|
||||||
|
|||||||
36
strans.c
36
strans.c
@@ -8,6 +8,7 @@ static Str lost;
|
|||||||
static int clientpre; /* the owner draws its own preedit */
|
static int clientpre; /* the owner draws its own preedit */
|
||||||
static Caret caret;
|
static Caret caret;
|
||||||
static Rune modemark; /* the mode the last key switched to */
|
static Rune modemark; /* the mode the last key switched to */
|
||||||
|
static int okuriat = -1; /* where Shift marked the okurigana, or -1 */
|
||||||
static Drawcmd lastdraw;
|
static Drawcmd lastdraw;
|
||||||
static Emit transjp(Im*, Rune);
|
static Emit transjp(Im*, Rune);
|
||||||
static void backjp(Im*);
|
static void backjp(Im*);
|
||||||
@@ -279,21 +280,22 @@ okuriletter(Rune r)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* SKK keys a verb or adjective by its stem and the letter of the
|
* SKK keys a verb or adjective by its stem and the letter of the
|
||||||
* okurigana that follows (かk: 書, 描, ...). Every split of the reading
|
* okurigana that follows (かk: 書, 描, ...). The split the user marked
|
||||||
* is tried, longest stem first, and the okurigana is put back; a っ
|
* is tried alone; otherwise every split is, longest stem first. The
|
||||||
* ending the stem (いっt: 言, 行) is written in kana too.
|
* okurigana is put back, and a っ ending the stem (いっt: 言, 行) is
|
||||||
|
* written in kana too.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
dictqokuri(Str *reading)
|
dictqokuri(Str *reading, int split)
|
||||||
{
|
{
|
||||||
Str key, okuri, kouho[Maxkouho];
|
Str key, okuri, kouho[Maxkouho];
|
||||||
Rune c;
|
Rune c;
|
||||||
int i, j, n;
|
int i, j, n;
|
||||||
|
|
||||||
for(i = reading->n - 1; i > 0; i--){
|
for(i = split >= 0 ? split : reading->n - 1; i > 0; i--){
|
||||||
c = okuriletter(reading->r[i]);
|
c = okuriletter(reading->r[i]);
|
||||||
if(c == 0)
|
if(c == 0)
|
||||||
continue;
|
break;
|
||||||
key = *reading;
|
key = *reading;
|
||||||
key.n = i;
|
key.n = i;
|
||||||
sputr(&key, c);
|
sputr(&key, c);
|
||||||
@@ -305,6 +307,8 @@ dictqokuri(Str *reading)
|
|||||||
sappend(&kouho[j], &okuri);
|
sappend(&kouho[j], &okuri);
|
||||||
addkouho(&kouho[j]);
|
addkouho(&kouho[j]);
|
||||||
}
|
}
|
||||||
|
if(split >= 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,14 +316,20 @@ dictqokuri(Str *reading)
|
|||||||
static void
|
static void
|
||||||
dictqjp(void)
|
dictqjp(void)
|
||||||
{
|
{
|
||||||
Str reading;
|
Str reading, exact[Maxkouho];
|
||||||
|
int i, n;
|
||||||
|
|
||||||
clearkouho();
|
clearkouho();
|
||||||
if(!isjp(&im) || !jpreading(im.l->map, &im.pre, &im.raw, &reading) ||
|
if(!isjp(&im) || !jpreading(im.l->map, &im.pre, &im.raw, &reading) ||
|
||||||
reading.n == 0)
|
reading.n == 0)
|
||||||
return;
|
return;
|
||||||
im.nkouho = dictlookup(im.l->dict, &reading, im.kouho, Maxkouho);
|
/* What Shift marked comes first; the dictionary's own readings next. */
|
||||||
dictqokuri(&reading);
|
if(okuriat > 0 && okuriat < reading.n)
|
||||||
|
dictqokuri(&reading, okuriat);
|
||||||
|
n = dictlookup(im.l->dict, &reading, exact, Maxkouho);
|
||||||
|
for(i = 0; i < n; i++)
|
||||||
|
addkouho(&exact[i]);
|
||||||
|
dictqokuri(&reading, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The reading in Katakana is the last candidate, as in every IME. */
|
/* The reading in Katakana is the last candidate, as in every IME. */
|
||||||
@@ -663,6 +673,7 @@ reset(void)
|
|||||||
{
|
{
|
||||||
sclear(&im.pre);
|
sclear(&im.pre);
|
||||||
sclear(&im.raw);
|
sclear(&im.raw);
|
||||||
|
okuriat = -1;
|
||||||
endsearch();
|
endsearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -798,10 +809,16 @@ searchkey(u32int ks, u32int mod, Str *com)
|
|||||||
static int
|
static int
|
||||||
transition(u32int ks, u32int mod, Str *com)
|
transition(u32int ks, u32int mod, Str *com)
|
||||||
{
|
{
|
||||||
|
Str mark;
|
||||||
int n;
|
int n;
|
||||||
Rune c;
|
Rune c;
|
||||||
|
|
||||||
modemark = 0; /* any key after the switch takes its mark away */
|
modemark = 0; /* any key after the switch takes its mark away */
|
||||||
|
/* Shift on a romaji letter marks the okurigana, as SKK's capital does. */
|
||||||
|
if(isjp(&im) && (mod & Mshift) && ks >= 'A' && ks <= 'Z' && haspre(&im)){
|
||||||
|
impre(&im, &mark);
|
||||||
|
okuriat = mark.n;
|
||||||
|
}
|
||||||
if(im.l->lang == LangKO)
|
if(im.l->lang == LangKO)
|
||||||
ks = kokey(ks, mod);
|
ks = kokey(ks, mod);
|
||||||
else if(isjp(&im))
|
else if(isjp(&im))
|
||||||
@@ -917,6 +934,7 @@ init(void)
|
|||||||
memset(&search, 0, sizeof search);
|
memset(&search, 0, sizeof search);
|
||||||
memset(&caret, 0, sizeof caret);
|
memset(&caret, 0, sizeof caret);
|
||||||
modemark = 0;
|
modemark = 0;
|
||||||
|
okuriat = -1;
|
||||||
activeowner = nil;
|
activeowner = nil;
|
||||||
lostowner = nil;
|
lostowner = nil;
|
||||||
clientpre = 0;
|
clientpre = 0;
|
||||||
|
|||||||
@@ -1223,6 +1223,18 @@ engine_japanese_candidates(struct ct *t)
|
|||||||
if(CT_EQ_INT(t, 1, im.nkouho))
|
if(CT_EQ_INT(t, 1, im.nkouho))
|
||||||
checkstr(t, "two-kana okurigana", "大きい", &im.kouho[0]);
|
checkstr(t, "two-kana okurigana", "大きい", &im.kouho[0]);
|
||||||
CT_CHECK(t, keystroke(Kesc, 0, &com));
|
CT_CHECK(t, keystroke(Kesc, 0, &com));
|
||||||
|
/* Shift on the okurigana asks for that split alone, first. */
|
||||||
|
sclear(&com);
|
||||||
|
if(!typekeys(t, "ka", &com))
|
||||||
|
goto cleanup;
|
||||||
|
CT_CHECK(t, keystroke('K', Mshift, &com));
|
||||||
|
CT_CHECK(t, keystroke('u', 0, &com));
|
||||||
|
if(CT_EQ_INT(t, 3, im.nkouho)){
|
||||||
|
checkstr(t, "marked okurigana first", "書く", &im.kouho[0]);
|
||||||
|
checkstr(t, "then the second", "描く", &im.kouho[1]);
|
||||||
|
checkstr(t, "then the reading's own", "確", &im.kouho[2]);
|
||||||
|
}
|
||||||
|
CT_CHECK(t, keystroke(Kesc, 0, &com));
|
||||||
setdict(jp->dict, "いt", "言 行");
|
setdict(jp->dict, "いt", "言 行");
|
||||||
setdict(jp->dict, "いっt", "言 行");
|
setdict(jp->dict, "いっt", "言 行");
|
||||||
if(!typekeys(t, "itta", &com))
|
if(!typekeys(t, "itta", &com))
|
||||||
|
|||||||
Reference in New Issue
Block a user