engine: trim the key dispatch

mapget and maplookup were one trie probe with two predicates; mapmatch
returns the match kind and mapget is its exact case. movedelta is a
switch. searchkey's modifier test was unreachable behind transition's,
searchlang's Alt/Super test behind both callers' earlier returns, and
picksearch's range check behind numberedkouho. Korean key folding runs
once at the top of transition. commit() on an empty preedit is a no-op,
so the Ctrl branch and startsearch lose their haspre guards and repeated
commit/reset pairs. Ctrl+language inside a search now commits the shown
query as it does elsewhere instead of dropping it. Language ids are
documented as the Ctrl codes they are; Im parameters no longer shadow
the file's Im.
This commit is contained in:
2026-08-16 16:09:05 +09:00
parent 68869e2589
commit 9080bb833c
3 changed files with 81 additions and 103 deletions

172
strans.c
View File

@@ -9,7 +9,6 @@ static int candidatechosen;
static Drawcmd lastdraw;
static Emit transjp(Im*, Rune);
static void backjp(Im*);
static int maplookup(Trie*, Str*, Str*);
typedef struct Search Search;
struct Search
@@ -31,6 +30,28 @@ Lang langs[] = {
};
int nlang = nelem(langs);
/* Trie match kind for key; on an exact match out holds the value. */
static int
mapmatch(Trie *t, Str *key, Str *out)
{
char *v;
int match, vlen;
sclear(out);
if(key->n == 0)
return TrieMiss;
match = trielookup(t, key, &v, &vlen);
if(match == TrieExact && !sinit(out, v, vlen))
return TrieMiss;
return match;
}
int
mapget(Trie *t, Str *key, Str *out)
{
return mapmatch(t, key, out) == TrieExact;
}
static void
clearkouho(void)
{
@@ -56,18 +77,12 @@ pagefirst(void)
static int
movedelta(u32int ks)
{
static struct {
u32int key;
int delta;
} move[] = {
{Kup, -1}, {Kdown, 1},
{Kpgup, -Maxdisp}, {Kpgdown, Maxdisp},
};
int i;
for(i = 0; i < nelem(move); i++)
if(move[i].key == ks)
return move[i].delta;
switch(ks){
case Kup: return -1;
case Kdown: return 1;
case Kpgup: return -Maxdisp;
case Kpgdown: return Maxdisp;
}
return 0;
}
@@ -271,12 +286,12 @@ commit(Str *com)
}
static void
backjp(Im *im)
backjp(Im *p)
{
if(im->raw.n != 0)
spopr(&im->raw);
if(p->raw.n != 0)
spopr(&p->raw);
else
spopr(&im->pre);
spopr(&p->pre);
}
static int
@@ -314,7 +329,7 @@ transjp(Im *p, Rune c)
}
key = e.raw;
sputr(&key, c);
if(maplookup(p->l->map, &key, &mapped)){
if(mapmatch(p->l->map, &key, &mapped) != TrieMiss){
e.raw = key;
if(issmalltsu(&mapped)){
sappend(&e.next, &mapped);
@@ -327,7 +342,7 @@ transjp(Im *p, Rune c)
sclear(&e.raw);
sclear(&key);
sputr(&key, c);
if(maplookup(p->l->map, &key, &mapped)){
if(mapmatch(p->l->map, &key, &mapped) != TrieMiss){
e.raw = key;
return e;
}
@@ -367,43 +382,30 @@ getlang(int lang)
return nil;
}
static int
maplookup(Trie *t, Str *key, Str *out)
{
char *v;
int match, vlen;
sclear(out);
if(key->n == 0)
return 0;
match = trielookup(t, key, &v, &vlen);
if(match == TrieMiss)
return 0;
if(match == TrieExact && !sinit(out, v, vlen))
return 0;
return 1;
}
/*
* The pending text is the key sequence itself while it is a prefix of some
* map entry; the map value is what gets shown and committed.
*/
Emit
transmap(Im *im, Rune c)
transmap(Im *p, Rune c)
{
Emit e = {0};
Str key, mapped;
Trie *t;
t = im->l->map;
key = im->pre;
t = p->l->map;
key = p->pre;
sputr(&key, c);
if(maplookup(t, &key, &mapped)){
if(mapmatch(t, &key, &mapped) != TrieMiss){
e.eat = 1;
e.next = key;
return e;
}
if(!mapget(t, &im->pre, &e.s))
e.s = im->pre;
if(!mapget(t, &p->pre, &e.s))
e.s = p->pre;
sclear(&key);
sputr(&key, c);
if(!maplookup(t, &key, &mapped))
if(mapmatch(t, &key, &mapped) == TrieMiss)
return e;
e.eat = 1;
sputr(&e.next, c);
@@ -533,13 +535,9 @@ searchquery(void)
}
static int
searchlang(Rune c, u32int mod)
searchlang(Rune c)
{
if(mod & (Malt|Msuper))
return 0;
if(c == LangEMOJI || c == LangHANJA)
return c;
return 0;
return c == LangEMOJI || c == LangHANJA ? c : 0;
}
static void
@@ -551,17 +549,13 @@ endsearch(void)
clearkouho();
}
/* A search commits any pending composition and takes over the keys. */
static void
startsearch(int lang, Str *com)
{
if(haspre(&im))
commit(com);
sclear(&im.pre);
sclear(&im.raw);
clearkouho();
commit(com);
endsearch();
search.lang = lang;
sclear(&search.raw);
sclear(&search.text);
}
static void
@@ -571,14 +565,11 @@ commitsearch(Str *com)
endsearch();
}
static int
static void
picksearch(int n, Str *com)
{
if(n < 0 || n >= im.nkouho)
return 0;
sappend(com, &im.kouho[n]);
endsearch();
return 1;
}
static int
@@ -587,8 +578,6 @@ searchkey(u32int ks, u32int mod, Str *com)
int n;
Rune c;
if(ismodkey(ks))
return 0;
n = movedelta(ks);
if(n != 0){
if(im.nkouho == 0)
@@ -617,8 +606,9 @@ searchkey(u32int ks, u32int mod, Str *com)
}
if(ks == Kret){
if(im.nkouho > 0)
return picksearch(im.sel >= 0 ? im.sel : 0, com);
commitsearch(com);
picksearch(max(im.sel, 0), com);
else
commitsearch(com);
return 1;
}
if(ks == Kback){
@@ -641,25 +631,21 @@ searchkey(u32int ks, u32int mod, Str *com)
}
if(mod & Mctrl){
c = ctrlkey(ks);
n = searchlang(c, mod);
if(n != 0){
if(n == search.lang)
endsearch();
else
startsearch(n, com);
return 1;
n = searchlang(c);
if(n == search.lang)
endsearch();
else if(n != 0)
startsearch(n, com);
else{
commitsearch(com);
return setlang(c);
}
endsearch();
if(setlang(c))
return 1;
return 0;
return 1;
}
if(search.raw.n >= Maxrunes){
commitsearch(com);
return 0;
}
if(im.l->lang == LangKO)
ks = kokey(ks, mod);
sputr(&search.raw, ks);
searchquery();
return 1;
@@ -673,6 +659,8 @@ transition(u32int ks, u32int mod, Str *com)
if(ismodkey(ks))
return 0;
if(im.l->lang == LangKO)
ks = kokey(ks, mod);
if(search.lang)
return searchkey(ks, mod, com);
n = movedelta(ks);
@@ -728,22 +716,14 @@ transition(u32int ks, u32int mod, Str *com)
}
if(mod & Mctrl){
c = ctrlkey(ks);
n = searchlang(c, mod);
n = searchlang(c);
if(n != 0){
startsearch(n, com);
return 1;
}
if(getlang(c) != nil){
if(haspre(&im))
commit(com);
reset();
setlang(c);
return 1;
}
if(haspre(&im))
commit(com);
commit(com);
reset();
return 0;
return setlang(c);
}
if(ks == '0' && im.nkouho > 0){
commit(com);
@@ -768,10 +748,7 @@ transition(u32int ks, u32int mod, Str *com)
reset();
return 0;
}
if(im.l->lang == LangKO)
ks = kokey(ks, mod);
n = dotrans(ks, com);
return n;
return dotrans(ks, com);
}
static void
@@ -871,14 +848,3 @@ imthread(void*)
}
}
int
mapget(Trie *t, Str *key, Str *out)
{
char *v;
int vlen;
sclear(out);
if(key->n == 0 || trielookup(t, key, &v, &vlen) != TrieExact)
return 0;
return sinit(out, v, vlen);
}