diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | README.7 | 14 | ||||
-rw-r--r-- | chat.c | 2 | ||||
-rw-r--r-- | chat.h | 16 | ||||
-rw-r--r-- | command.c | 19 | ||||
-rw-r--r-- | complete.c | 187 | ||||
-rw-r--r-- | handle.c | 86 | ||||
-rw-r--r-- | input.c | 13 | ||||
-rw-r--r-- | window.c | 6 |
9 files changed, 75 insertions, 269 deletions
diff --git a/Makefile b/Makefile index 39b15b2..e8ef63a 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,6 @@ OBJS += buffer.o OBJS += cache.o OBJS += chat.o OBJS += command.o -OBJS += complete.o OBJS += config.o OBJS += edit.o OBJS += filter.o diff --git a/README.7 b/README.7 index d10d5f6..64024ab 100644 --- a/README.7 +++ b/README.7 @@ -1,5 +1,5 @@ -.\" To view this file, run: man ./README.7 -.Dd March 31, 2022 +.\" To view this file: $ man ./README.7 +.Dd July 30, 2022 .Dt README 7 .Os "Causal Agency" . @@ -9,7 +9,7 @@ . .Sh DESCRIPTION .Xr catgirl 1 -is a TLS-only terminal IRC client. +is a terminal IRC client. . .Pp Screenshot: @@ -180,7 +180,7 @@ $ make -C scripts sandman .Ed . .Sh FILES -.Bl -tag -width "complete.c" -compact +.Bl -tag -width "command.c" -compact .It Pa chat.h global state and declarations .It Pa chat.c @@ -201,8 +201,8 @@ command handling line wrapping .It Pa edit.c line editing -.It Pa complete.c -tab complete +.It Pa cache.c +ordered cache .It Pa url.c URL detection .It Pa filter.c @@ -270,4 +270,4 @@ IRC bouncer: .%D June 19, 2020 .Re . -.\" To view this file, run: man ./README.7 +.\" To view this file: $ man ./README.7 diff --git a/chat.c b/chat.c index 2d35771..39b1a93 100644 --- a/chat.c +++ b/chat.c @@ -374,7 +374,7 @@ int main(int argc, char *argv[]) { set(&network.name, host); set(&self.nick, "*"); - inputCompleteAdd(); + inputCache(); ircConfig(insecure, trust, cert, priv); diff --git a/chat.h b/chat.h index b7de9ac..ea4ece3 100644 --- a/chat.h +++ b/chat.h @@ -292,7 +292,7 @@ const char *commandIsPrivmsg(uint id, const char *input); const char *commandIsNotice(uint id, const char *input); const char *commandIsAction(uint id, const char *input); size_t commandWillSplit(uint id, const char *input); -void commandCompleteAdd(void); +void commandCache(void); enum Heat { Ice, @@ -334,7 +334,7 @@ void inputWait(void); void inputUpdate(void); bool inputPending(uint id); void inputRead(void); -void inputCompleteAdd(void); +void inputCache(void); int inputSave(FILE *file); void inputLoad(FILE *file, size_t version); @@ -412,18 +412,6 @@ void cacheReject(struct Cursor *curs); void cacheRemove(uint id, const char *key); void cacheClear(uint id); -const char *complete(uint id, const char *prefix); -const char *completeSubstr(uint id, const char *substr); -void completeAccept(void); -void completeReject(void); -void completeAdd(uint id, const char *str, enum Color color); -void completeTouch(uint id, const char *str, enum Color color); -void completeReplace(uint id, const char *old, const char *new); -void completeRemove(uint id, const char *str); -void completeClear(uint id); -uint completeID(const char *str); -enum Color completeColor(uint id, const char *str); - extern struct Util urlOpenUtil; extern struct Util urlCopyUtil; void urlScan(uint id, const char *nick, const char *mesg); diff --git a/command.c b/command.c index dcd0e22..f5d9dbf 100644 --- a/command.c +++ b/command.c @@ -139,7 +139,7 @@ static void commandMsg(uint id, char *params) { char *nick = strsep(¶ms, " "); uint msg = idFor(nick); if (idColors[msg] == Default) { - idColors[msg] = completeColor(id, nick); + idColors[msg] = cacheColor(id, nick); } if (params) { splitMessage("PRIVMSG", msg, params); @@ -380,7 +380,7 @@ static void commandQuery(uint id, char *params) { if (!params) return; uint query = idFor(params); if (idColors[query] == Default) { - idColors[query] = completeColor(id, params); + idColors[query] = cacheColor(id, params); } windowShow(windowFor(query)); } @@ -396,10 +396,11 @@ static void commandWindow(uint id, char *params) { windowShow(windowFor(id)); return; } - for (const char *match; (match = completeSubstr(None, params));) { + struct Cursor curs = {0}; + for (const char *match; (match = cacheSubstr(&curs, None, params));) { id = idFind(match); if (!id) continue; - completeAccept(); + cacheAccept(&curs); windowShow(windowFor(id)); break; } @@ -669,11 +670,11 @@ void command(uint id, char *input) { return; } + struct Cursor curs = {0}; const char *cmd = strsep(&input, " "); - const char *unique = complete(None, cmd); - if (unique && !complete(None, cmd)) { + const char *unique = cachePrefix(&curs, None, cmd); + if (unique && !cachePrefix(&curs, None, cmd)) { cmd = unique; - completeReject(); } const struct Handler *handler = bsearch( @@ -700,9 +701,9 @@ void command(uint id, char *input) { handler->fn(id, input); } -void commandCompleteAdd(void) { +void commandCache(void) { for (size_t i = 0; i < ARRAY_LEN(Commands); ++i) { if (!commandAvailable(&Commands[i])) continue; - completeAdd(None, Commands[i].cmd, Default); + cacheInsert(false, None, Commands[i].cmd); } } diff --git a/complete.c b/complete.c deleted file mode 100644 index e8ea3fe..0000000 --- a/complete.c +++ /dev/null @@ -1,187 +0,0 @@ -/* Copyright (C) 2020 June McEnroe <june@causal.agency> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - * Additional permission under GNU GPL version 3 section 7: - * - * If you modify this Program, or any covered work, by linking or - * combining it with OpenSSL (or a modified version of that library), - * containing parts covered by the terms of the OpenSSL License and the - * original SSLeay license, the licensors of this Program grant you - * additional permission to convey the resulting work. Corresponding - * Source for a non-source form of such a combination shall include the - * source code for the parts of OpenSSL used as well as that of the - * covered work. - */ - -#include <err.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sysexits.h> - -#include "chat.h" - -struct Node { - uint id; - char *str; - enum Color color; - struct Node *prev; - struct Node *next; -}; - -static struct Node *alloc(uint id, const char *str, enum Color color) { - struct Node *node = malloc(sizeof(*node)); - if (!node) err(EX_OSERR, "malloc"); - node->id = id; - node->str = strdup(str); - node->color = color; - node->prev = NULL; - node->next = NULL; - if (!node->str) err(EX_OSERR, "strdup"); - return node; -} - -static struct Node *head; -static struct Node *tail; - -static struct Node *detach(struct Node *node) { - if (node->prev) node->prev->next = node->next; - if (node->next) node->next->prev = node->prev; - if (head == node) head = node->next; - if (tail == node) tail = node->prev; - node->prev = NULL; - node->next = NULL; - return node; -} - -static struct Node *prepend(struct Node *node) { - node->prev = NULL; - node->next = head; - if (head) head->prev = node; - head = node; - tail = (tail ?: node); - return node; -} - -static struct Node *append(struct Node *node) { - node->next = NULL; - node->prev = tail; - if (tail) tail->next = node; - tail = node; - head = (head ?: node); - return node; -} - -static struct Node *find(uint id, const char *str) { - for (struct Node *node = head; node; node = node->next) { - if (node->id != id) continue; - if (strcmp(node->str, str)) continue; - return node; - } - return NULL; -} - -void completeAdd(uint id, const char *str, enum Color color) { - if (!find(id, str)) append(alloc(id, str, color)); -} - -void completeTouch(uint id, const char *str, enum Color color) { - struct Node *node = find(id, str); - if (node) node->color = color; - prepend(node ? detach(node) : alloc(id, str, color)); -} - -enum Color completeColor(uint id, const char *str) { - struct Node *node = find(id, str); - return (node ? node->color : Default); -} - -static struct Node *match; - -const char *complete(uint id, const char *prefix) { - for (match = (match ? match->next : head); match; match = match->next) { - if (match->id && match->id != id) continue; - if (strncasecmp(match->str, prefix, strlen(prefix))) continue; - return match->str; - } - return NULL; -} - -const char *completeSubstr(uint id, const char *substr) { - for (match = (match ? match->next : head); match; match = match->next) { - if (match->id && match->id != id) continue; - if (!strstr(match->str, substr)) continue; - return match->str; - } - return NULL; -} - -void completeAccept(void) { - if (match) prepend(detach(match)); - match = NULL; -} - -void completeReject(void) { - match = NULL; -} - -static struct Node *iter; - -uint completeID(const char *str) { - for (iter = (iter ? iter->next : head); iter; iter = iter->next) { - if (iter->id && !strcmp(iter->str, str)) return iter->id; - } - return None; -} - -void completeReplace(uint id, const char *old, const char *new) { - struct Node *next = NULL; - for (struct Node *node = head; node; node = next) { - next = node->next; - if (id && node->id != id) continue; - if (strcmp(node->str, old)) continue; - free(node->str); - node->str = strdup(new); - prepend(detach(node)); - if (!node->str) err(EX_OSERR, "strdup"); - } -} - -void completeRemove(uint id, const char *str) { - struct Node *next = NULL; - for (struct Node *node = head; node; node = next) { - next = node->next; - if (id && node->id != id) continue; - if (strcmp(node->str, str)) continue; - if (match == node) match = NULL; - if (iter == node) iter = NULL; - detach(node); - free(node->str); - free(node); - } -} - -void completeClear(uint id) { - struct Node *next = NULL; - for (struct Node *node = head; node; node = next) { - next = node->next; - if (node->id != id) continue; - if (match == node) match = NULL; - if (iter == node) iter = NULL; - detach(node); - free(node->str); - free(node); - } -} diff --git a/handle.c b/handle.c index d98a72c..8034957 100644 --- a/handle.c +++ b/handle.c @@ -266,7 +266,7 @@ static void handleErrorSASLFail(struct Message *msg) { static void handleReplyWelcome(struct Message *msg) { require(msg, false, 1); set(&self.nick, msg->params[0]); - completeTouch(Network, self.nick, Default); + cacheInsert(true, Network, self.nick); if (self.mode) ircFormat("MODE %s %s\r\n", self.nick, self.mode); if (self.join) { uint count = 1; @@ -278,7 +278,7 @@ static void handleReplyWelcome(struct Message *msg) { replies[ReplyTopicAuto] += count; replies[ReplyNamesAuto] += count; } - commandCompleteAdd(); + commandCache(); handleReplyGeneric(msg); } @@ -372,13 +372,13 @@ static void handleJoin(struct Message *msg) { set(&self.host, msg->host); } idColors[id] = hash(msg->params[0]); - completeTouch(None, msg->params[0], idColors[id]); + cacheInsertColor(true, None, msg->params[0], idColors[id]); if (replies[ReplyJoin]) { windowShow(windowFor(id)); replies[ReplyJoin]--; } } - completeTouch(id, msg->nick, hash(msg->user)); + cacheInsertColor(true, id, msg->nick, hash(msg->user)); if (msg->params[2] && !strcasecmp(msg->params[2], msg->nick)) { msg->params[2] = NULL; } @@ -410,9 +410,9 @@ static void handlePart(struct Message *msg) { require(msg, true, 1); uint id = idFor(msg->params[0]); if (!strcmp(msg->nick, self.nick)) { - completeClear(id); + cacheClear(id); } - completeRemove(id, msg->nick); + cacheRemove(id, msg->nick); enum Heat heat = filterCheck(Cold, id, msg); if (heat > Ice) urlScan(id, msg->nick, msg->params[1]); uiFormat( @@ -432,14 +432,14 @@ static void handleKick(struct Message *msg) { require(msg, true, 2); uint id = idFor(msg->params[0]); bool kicked = !strcmp(msg->params[1], self.nick); - completeTouch(id, msg->nick, hash(msg->user)); + cacheInsertColor(true, id, msg->nick, hash(msg->user)); urlScan(id, msg->nick, msg->params[2]); uiFormat( id, (kicked ? Hot : Cold), tagTime(msg), "%s\3%02d%s\17\tkicks \3%02d%s\3 out of \3%02d%s\3%s%s", (kicked ? "\26" : ""), hash(msg->user), msg->nick, - completeColor(id, msg->params[1]), msg->params[1], + cacheColor(id, msg->params[1]), msg->params[1], hash(msg->params[0]), msg->params[0], (msg->params[2] ? ": " : ""), (msg->params[2] ?: "") ); @@ -448,8 +448,8 @@ static void handleKick(struct Message *msg) { msg->nick, msg->params[1], msg->params[0], (msg->params[2] ? ": " : ""), (msg->params[2] ?: "") ); - completeRemove(id, msg->params[1]); - if (kicked) completeClear(id); + cacheRemove(id, msg->params[1]); + if (kicked) cacheClear(id); } static void handleNick(struct Message *msg) { @@ -458,7 +458,8 @@ static void handleNick(struct Message *msg) { set(&self.nick, msg->params[0]); inputUpdate(); } - for (uint id; (id = completeID(msg->nick));) { + struct Cursor curs = {0}; + for (uint id; (id = cacheID(&curs, msg->nick));) { if (!strcmp(idNames[id], msg->nick)) { set(&idNames[id], msg->params[0]); } @@ -473,12 +474,13 @@ static void handleNick(struct Message *msg) { msg->nick, msg->params[0] ); } - completeReplace(None, msg->nick, msg->params[0]); + cacheReplace(true, msg->nick, msg->params[0]); } static void handleSetname(struct Message *msg) { require(msg, true, 1); - for (uint id; (id = completeID(msg->nick));) { + struct Cursor curs = {0}; + for (uint id; (id = cacheID(&curs, msg->nick));) { uiFormat( id, filterCheck(Cold, id, msg), tagTime(msg), "\3%02d%s\3\tis now known as \3%02d%s\3 (%s\17)", @@ -490,7 +492,8 @@ static void handleSetname(struct Message *msg) { static void handleQuit(struct Message *msg) { require(msg, true, 0); - for (uint id; (id = completeID(msg->nick));) { + struct Cursor curs = {0}; + for (uint id; (id = cacheID(&curs, msg->nick));) { enum Heat heat = filterCheck(Cold, id, msg); if (heat > Ice) urlScan(id, msg->nick, msg->params[0]); uiFormat( @@ -506,7 +509,7 @@ static void handleQuit(struct Message *msg) { (msg->params[0] ? ": " : ""), (msg->params[0] ?: "") ); } - completeRemove(None, msg->nick); + cacheRemove(None, msg->nick); } static void handleInvite(struct Message *msg) { @@ -552,7 +555,7 @@ static void handleErrorUserOnChannel(struct Message *msg) { uiFormat( id, Warm, tagTime(msg), "\3%02d%s\3 is already in \3%02d%s\3", - completeColor(id, msg->params[1]), msg->params[1], + cacheColor(id, msg->params[1]), msg->params[1], hash(msg->params[2]), msg->params[2] ); } @@ -568,7 +571,7 @@ static void handleReplyNames(struct Message *msg) { char *nick = &prefixes[strspn(prefixes, network.prefixes)]; char *user = strsep(&name, "@"); enum Color color = (user ? hash(user) : Default); - completeAdd(id, nick, color); + cacheInsertColor(false, id, nick, color); if (!replies[ReplyNames] && !replies[ReplyNamesAuto]) continue; ptr = seprintf( ptr, end, "%s\3%02d%s\3", (ptr > buf ? ", " : ""), color, prefixes @@ -635,23 +638,24 @@ static void handleReplyNoTopic(struct Message *msg) { ); } -static void topicComplete(uint id, const char *topic) { +static void topicCache(uint id, const char *topic) { char buf[512]; - const char *prev = complete(id, "/topic "); + struct Cursor curs = {0}; + const char *prev = cachePrefix(&curs, id, "/topic "); if (prev) { snprintf(buf, sizeof(buf), "%s", prev); - completeRemove(id, buf); + cacheRemove(id, buf); } if (topic) { snprintf(buf, sizeof(buf), "/topic %s", topic); - completeAdd(id, buf, Default); + cacheInsert(false, id, buf); } } static void handleReplyTopic(struct Message *msg) { require(msg, false, 3); uint id = idFor(msg->params[1]); - topicComplete(id, msg->params[2]); + topicCache(id, msg->params[2]); if (!replies[ReplyTopic] && !replies[ReplyTopicAuto]) return; urlScan(id, NULL, msg->params[2]); uiFormat( @@ -702,7 +706,7 @@ static void handleTopic(struct Message *msg) { require(msg, true, 2); uint id = idFor(msg->params[0]); if (!msg->params[1][0]) { - topicComplete(id, NULL); + topicCache(id, NULL); uiFormat( id, Warm, tagTime(msg), "\3%02d%s\3\tremoves the sign in \3%02d%s\3", @@ -715,8 +719,8 @@ static void handleTopic(struct Message *msg) { return; } - const char *prev = complete(id, "/topic "); - completeReject(); + struct Cursor curs = {0}; + const char *prev = cachePrefix(&curs, id, "/topic "); if (prev) { prev += 7; } else { @@ -766,7 +770,7 @@ log: id, tagTime(msg), "%s places a new sign in %s: %s", msg->nick, msg->params[0], msg->params[1] ); - topicComplete(id, msg->params[1]); + topicCache(id, msg->params[1]); urlScan(id, msg->nick, msg->params[1]); } @@ -893,7 +897,7 @@ static void handleMode(struct Message *msg) { id, Cold, tagTime(msg), "\3%02d%s\3\t%s \3%02d%c%s\3 %s%s in \3%02d%s\3", hash(msg->user), msg->nick, verb, - completeColor(id, nick), prefix, nick, + cacheColor(id, nick), prefix, nick, mode, name, hash(msg->params[0]), msg->params[0] ); logFormat( @@ -1031,7 +1035,7 @@ static void handleReplyBanList(struct Message *msg) { id, Warm, tagTime(msg), "Banned from \3%02d%s\3 since %s by \3%02d%s\3: %s", hash(msg->params[1]), msg->params[1], - since, completeColor(id, msg->params[3]), msg->params[3], + since, cacheColor(id, msg->params[3]), msg->params[3], msg->params[2] ); } else { @@ -1054,7 +1058,7 @@ static void onList(const char *list, struct Message *msg) { id, Warm, tagTime(msg), "On the \3%02d%s\3 %s list since %s by \3%02d%s\3: %s", hash(msg->params[1]), msg->params[1], list, - since, completeColor(id, msg->params[3]), msg->params[3], + since, cacheColor(id, msg->params[3]), msg->params[3], msg->params[2] ); } else { @@ -1087,7 +1091,7 @@ static void handleReplyList(struct Message *msg) { static void handleReplyWhoisUser(struct Message *msg) { require(msg, false, 6); - completeTouch(Network, msg->params[1], hash(msg->params[2])); + cacheInsertColor(true, Network, msg->params[1], hash(msg->params[2])); uiFormat( Network, Warm, tagTime(msg), "\3%02d%s\3\tis %s!%s@%s (%s\17)", @@ -1102,7 +1106,7 @@ static void handleReplyWhoisServer(struct Message *msg) { uiFormat( Network, Warm, tagTime(msg), "\3%02d%s\3\t%s connected to %s (%s)", - completeColor(Network, msg->params[1]), msg->params[1], + cacheColor(Network, msg->params[1]), msg->params[1], (replies[ReplyWhowas] ? "was" : "is"), msg->params[2], msg->params[3] ); } @@ -1126,7 +1130,7 @@ static void handleReplyWhoisIdle(struct Message *msg) { uiFormat( Network, Warm, tagTime(msg), "\3%02d%s\3\tis idle for %lu %s%s%s%s", - completeColor(Network, msg->params[1]), msg->params[1], + cacheColor(Network, msg->params[1]), msg->params[1], idle, unit, (idle != 1 ? "s" : ""), (msg->params[3] ? ", signed on " : ""), (msg->params[3] ? signon : "") ); @@ -1148,7 +1152,7 @@ static void handleReplyWhoisChannels(struct Message *msg) { uiFormat( Network, Warm, tagTime(msg), "\3%02d%s\3\tis in %s", - completeColor(Network, msg->params[1]), msg->params[1], buf + cacheColor(Network, msg->params[1]), msg->params[1], buf ); } @@ -1162,7 +1166,7 @@ static void handleReplyWhoisGeneric(struct Message *msg) { uiFormat( Network, Warm, tagTime(msg), "\3%02d%s\3\t%s%s%s", - completeColor(Network, msg->params[1]), msg->params[1], + cacheColor(Network, msg->params[1]), msg->params[1], msg->params[2], (msg->params[3] ? " " : ""), (msg->params[3] ?: "") ); } @@ -1170,13 +1174,13 @@ static void handleReplyWhoisGeneric(struct Message *msg) { static void handleReplyEndOfWhois(struct Message *msg) { require(msg, false, 2); if (strcmp(msg->params[1], self.nick)) { - completeRemove(Network, msg->params[1]); + cacheRemove(Network, msg->params[1]); } } static void handleReplyWhowasUser(struct Message *msg) { require(msg, false, 6); - completeTouch(Network, msg->params[1], hash(msg->params[2])); + cacheInsertColor(true, Network, msg->params[1], hash(msg->params[2])); uiFormat( Network, Warm, tagTime(msg), "\3%02d%s\3\twas %s!%s@%s (%s)", @@ -1188,7 +1192,7 @@ static void handleReplyWhowasUser(struct Message *msg) { static void handleReplyEndOfWhowas(struct Message *msg) { require(msg, false, 2); if (strcmp(msg->params[1], self.nick)) { - completeRemove(Network, msg->params[1]); + cacheRemove(Network, msg->params[1]); } } @@ -1196,7 +1200,7 @@ static void handleReplyAway(struct Message *msg) { require(msg, false, 3); // Might be part of a WHOIS response. uint id; - if (completeColor(Network, msg->params[1]) != Default) { + if (cacheColor(Network, msg->params[1]) != Default) { id = Network; } else { id = idFor(msg->params[1]); @@ -1204,7 +1208,7 @@ static void handleReplyAway(struct Message *msg) { uiFormat( id, (id == Network ? Warm : Cold), tagTime(msg), "\3%02d%s\3\tis away: %s", - completeColor(id, msg->params[1]), msg->params[1], msg->params[2] + cacheColor(id, msg->params[1]), msg->params[1], msg->params[2] ); logFormat( id, tagTime(msg), "%s is away: %s", @@ -1275,7 +1279,7 @@ static char *colorMentions(char *ptr, char *end, uint id, const char *msg) { size_t len = strcspn(msg, ",:<> "); char *p = seprintf(ptr, end, "%.*s", (int)len, msg); - enum Color color = completeColor(id, ptr); + enum Color color = cacheColor(id, ptr); if (color != Default) { ptr = seprintf(ptr, end, "\3%02d%.*s\3", color, (int)len, msg); } else { @@ -1315,7 +1319,7 @@ static void handlePrivmsg(struct Message *msg) { heat = filterCheck(heat, id, msg); if (heat > Warm && !mine && !query) highlight = true; if (!notice && !mine && heat > Ice) { - completeTouch(id, msg->nick, hash(msg->user)); + cacheInsertColor(true, id, msg->nick, hash(msg->user)); } if (heat > Ice) urlScan(id, msg->nick, msg->params[1]); diff --git a/input.c b/input.c index 87a4eb9..739d889 100644 --- a/input.c +++ b/input.c @@ -261,12 +261,12 @@ static const struct { { L"\\wave", L"ヾ(^∇^)" }, }; -void inputCompleteAdd(void) { +void inputCache(void) { char mbs[256]; for (size_t i = 0; i < ARRAY_LEN(Macros); ++i) { size_t n = wcstombs(mbs, Macros[i].name, sizeof(mbs)); assert(n != (size_t)-1); - completeAdd(None, mbs, Default); + cacheInsert(false, None, mbs); } } @@ -296,15 +296,16 @@ static struct { size_t pos; size_t len; bool suffix; + struct Cursor curs; } tab; static void tabAccept(void) { - completeAccept(); + cacheAccept(&tab.curs); tab.len = 0; } static void tabReject(void) { - completeReject(); + cacheReject(&tab.curs); tab.len = 0; } @@ -332,9 +333,9 @@ static int tabComplete(struct Edit *e, uint id) { tab.suffix = true; } - const char *comp = complete(id, tab.pre); + const char *comp = cachePrefix(&tab.curs, id, tab.pre); if (!comp) { - comp = complete(id, tab.pre); + comp = cachePrefix(&tab.curs, id, tab.pre); tab.suffix ^= true; } if (!comp) { diff --git a/window.c b/window.c index ee0911f..72a3571 100644 --- a/window.c +++ b/window.c @@ -93,7 +93,7 @@ static struct Window *windowRemove(uint num) { } static void windowFree(struct Window *window) { - completeRemove(None, idNames[window->id]); + cacheRemove(None, idNames[window->id]); bufferFree(window->buffer); free(window); } @@ -118,7 +118,7 @@ uint windowFor(uint id) { window->thresh = windowThreshold; } window->buffer = bufferAlloc(); - completeAdd(None, idNames[id], idColors[id]); + cacheInsertColor(false, None, idNames[id], idColors[id]); return windowPush(window); } @@ -477,7 +477,7 @@ void windowClose(uint num) { if (num >= count) return; if (windows[num]->id == Network) return; struct Window *window = windowRemove(num); - completeClear(window->id); + cacheClear(window->id); windowFree(window); if (swap >= num) swap--; if (show == num) { |