engine: one trans contract for every language
Japanese was never dispatched through the Lang table: dotrans and transstr both special-cased it into transjp, which edited Im in place and wrote commits through a side argument, while transko popped and cleared a pre that every caller overwrote anyway, and Vietnamese kept its key history in dotrans. Emit now carries the new raw state next to the new pre; transjp, transko and transvi are pure functions of (Im, key), and dotrans and transstr have a single path. Vietnamese history bookkeeping lives in vi.c, where the full-history flush no longer resets the caret as a side effect; istone was toneidx() >= 0.
This commit is contained in:
69
vi.c
69
vi.c
@@ -31,12 +31,6 @@ static struct {
|
||||
{L'Y', {L'Ý', L'Ỳ', L'Ỷ', L'Ỹ', L'Ỵ'}},
|
||||
};
|
||||
|
||||
static int
|
||||
istone(Rune c)
|
||||
{
|
||||
return c == 's' || c == 'f' || c == 'r' || c == 'x' || c == 'j';
|
||||
}
|
||||
|
||||
static int
|
||||
toneidx(Rune c)
|
||||
{
|
||||
@@ -114,20 +108,44 @@ onsetglide(Str *m)
|
||||
return -1;
|
||||
}
|
||||
|
||||
Emit
|
||||
transvi(Im *im, Rune c)
|
||||
/*
|
||||
* The pending text is the key sequence itself, read through the map for
|
||||
* display; raw keeps every key of it so Backspace can replay one fewer.
|
||||
*/
|
||||
static Emit
|
||||
history(Im *im, Rune c, Emit e)
|
||||
{
|
||||
Emit e, mappedkey;
|
||||
Str mapped;
|
||||
|
||||
e.raw = im->raw;
|
||||
if(e.s.n > 0 || !e.eat)
|
||||
sclear(&e.raw);
|
||||
if(!e.eat || e.next.n == 0)
|
||||
return e;
|
||||
if(e.raw.n < Maxrunes){
|
||||
sputr(&e.raw, c);
|
||||
return e;
|
||||
}
|
||||
/* The history is full: flush the composed text as it stands. */
|
||||
if(!mapget(im->l->map, &e.next, &mapped))
|
||||
mapped = e.next;
|
||||
sappend(&e.s, &mapped);
|
||||
sclear(&e.next);
|
||||
sclear(&e.raw);
|
||||
return e;
|
||||
}
|
||||
|
||||
static Emit
|
||||
tone(Im *im, Rune c)
|
||||
{
|
||||
Emit e;
|
||||
Str mapped, pre;
|
||||
int i, tidx, vi, last, penult, glide;
|
||||
Rune v, b1, b2;
|
||||
|
||||
if(!istone(c) && c != 'z')
|
||||
return transmap(im, c);
|
||||
mappedkey = transmap(im, c);
|
||||
if(mappedkey.eat)
|
||||
return mappedkey;
|
||||
|
||||
e = transmap(im, c);
|
||||
if(e.eat)
|
||||
return e;
|
||||
memset(&e, 0, sizeof e);
|
||||
if(im->pre.n == 0)
|
||||
return e;
|
||||
@@ -175,17 +193,24 @@ transvi(Im *im, Rune c)
|
||||
return e;
|
||||
}
|
||||
|
||||
if(c == 'z')
|
||||
tidx = toneidx(c);
|
||||
if(tidx < 0)
|
||||
mapped.r[vi] = removetone(mapped.r[vi]);
|
||||
else{
|
||||
tidx = toneidx(c);
|
||||
else
|
||||
mapped.r[vi] = applytone(mapped.r[vi], tidx);
|
||||
}
|
||||
e.eat = 1;
|
||||
e.next = mapped;
|
||||
return e;
|
||||
}
|
||||
|
||||
Emit
|
||||
transvi(Im *im, Rune c)
|
||||
{
|
||||
if(toneidx(c) < 0 && c != 'z')
|
||||
return history(im, c, transmap(im, c));
|
||||
return history(im, c, tone(im, c));
|
||||
}
|
||||
|
||||
void
|
||||
backvi(Im *im)
|
||||
{
|
||||
@@ -200,10 +225,10 @@ backvi(Im *im)
|
||||
raw = im->raw;
|
||||
spopr(&raw);
|
||||
sclear(&im->pre);
|
||||
sclear(&im->raw);
|
||||
for(i = 0; i < raw.n; i++){
|
||||
e = transvi(im, raw.r[i]);
|
||||
sclear(&im->pre);
|
||||
sappend(&im->pre, &e.next);
|
||||
im->pre = e.next;
|
||||
im->raw = e.raw;
|
||||
}
|
||||
im->raw = raw;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user