Hook up tab-complete
parent
82cf445858
commit
40e362f505
85
edit.c
85
edit.c
|
@ -60,7 +60,78 @@ static void delete(size_t index, size_t count) {
|
||||||
len -= count;
|
len -= count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
size_t pos;
|
||||||
|
size_t pre;
|
||||||
|
size_t len;
|
||||||
|
} tab;
|
||||||
|
|
||||||
|
static void tabComplete(size_t id) {
|
||||||
|
if (!tab.len) {
|
||||||
|
tab.pos = pos;
|
||||||
|
while (tab.pos && buf[tab.pos - 1] != L' ') tab.pos--;
|
||||||
|
if (tab.pos == pos) return;
|
||||||
|
tab.pre = pos - tab.pos;
|
||||||
|
tab.len = tab.pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
char mbs[MB_LEN_MAX * tab.pre + 1];
|
||||||
|
const wchar_t *ptr = &buf[tab.pos];
|
||||||
|
size_t n = wcsnrtombs(mbs, &ptr, tab.pre, sizeof(mbs) - 1, NULL);
|
||||||
|
assert(n != (size_t)-1);
|
||||||
|
mbs[n] = '\0';
|
||||||
|
|
||||||
|
const char *comp = complete(id, mbs);
|
||||||
|
if (!comp) comp = complete(id, mbs);
|
||||||
|
if (!comp) {
|
||||||
|
tab.len = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t wcs[strlen(comp) + 1];
|
||||||
|
n = mbstowcs(wcs, comp, sizeof(wcs));
|
||||||
|
assert(n != (size_t)-1);
|
||||||
|
if (tab.pos + n + 2 > Cap) {
|
||||||
|
completeReject();
|
||||||
|
tab.len = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(tab.pos, tab.len);
|
||||||
|
if (wcs[0] != L'/' && !tab.pos) {
|
||||||
|
tab.len = n + 2;
|
||||||
|
reserve(tab.pos, tab.len);
|
||||||
|
buf[tab.pos + n + 0] = L':';
|
||||||
|
buf[tab.pos + n + 1] = L' ';
|
||||||
|
} else if (
|
||||||
|
tab.pos >= 2 && (buf[tab.pos - 2] == L':' || buf[tab.pos - 2] == L',')
|
||||||
|
) {
|
||||||
|
tab.len = n + 2;
|
||||||
|
reserve(tab.pos, tab.len);
|
||||||
|
buf[tab.pos - 2] = L',';
|
||||||
|
buf[tab.pos + n + 0] = L':';
|
||||||
|
buf[tab.pos + n + 1] = L' ';
|
||||||
|
} else {
|
||||||
|
tab.len = n + 1;
|
||||||
|
reserve(tab.pos, tab.len);
|
||||||
|
buf[tab.pos + n] = L' ';
|
||||||
|
}
|
||||||
|
memcpy(&buf[tab.pos], wcs, sizeof(*wcs) * n);
|
||||||
|
pos = tab.pos + tab.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tabAccept(void) {
|
||||||
|
completeAccept();
|
||||||
|
tab.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tabReject(void) {
|
||||||
|
completeReject();
|
||||||
|
tab.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void edit(size_t id, enum Edit op, wchar_t ch) {
|
void edit(size_t id, enum Edit op, wchar_t ch) {
|
||||||
|
size_t init = pos;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
break; case EditHome: pos = 0;
|
break; case EditHome: pos = 0;
|
||||||
break; case EditEnd: pos = len;
|
break; case EditEnd: pos = len;
|
||||||
|
@ -75,12 +146,20 @@ void edit(size_t id, enum Edit op, wchar_t ch) {
|
||||||
if (pos < Cap) buf[pos++] = ch;
|
if (pos < Cap) buf[pos++] = ch;
|
||||||
}
|
}
|
||||||
break; case EditComplete: {
|
break; case EditComplete: {
|
||||||
// TODO
|
tabComplete(id);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
break; case EditEnter: {
|
break; case EditEnter: {
|
||||||
pos = 0;
|
tabAccept();
|
||||||
command(id, editBuffer(NULL));
|
command(id, editBuffer(NULL));
|
||||||
len = 0;
|
len = pos = 0;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pos < init) {
|
||||||
|
tabReject();
|
||||||
|
} else {
|
||||||
|
tabAccept();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue