From a281f89592cf5531ebf53863768fccd054de252c Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Sat, 11 Aug 2018 19:30:30 -0400 Subject: Rework UI code for multi-channel Tags are now permanently assigned (and I'm betting on never needing more than 256 of them) and the UI maps tags to a linked list of views for easy reordering and removal. Currently, views can only be added. Views don't have a topic window until they need one. All UI code wants to be functional reactive. Beeping is temporarily removed until message priorities (status, message, ping) can be added to the UI. At that point spawning notify-send should also be possible. Priorities will also help with unnecessary markers, which will not appear for status messages. The tab system is now used to send QUIT and NICK messages to all the relevant tags. Verbose output now goes to its own tag, and sending to it sends raw IRC. IRC colors are now listed in chat.h and handler functions for numeric replies have real names. The color algorithm now uses a real hash function for hopefully better results. QUIT, PART and KICK messages are scanned for URLs. --- tab.c | 55 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 23 deletions(-) (limited to 'tab.c') diff --git a/tab.c b/tab.c index c0a96a4..87e4f02 100644 --- a/tab.c +++ b/tab.c @@ -22,7 +22,7 @@ #include "chat.h" static struct Entry { - size_t tag; + struct Tag tag; char *word; struct Entry *prev; struct Entry *next; @@ -49,7 +49,7 @@ static void touch(struct Entry *entry) { void tabTouch(struct Tag tag, const char *word) { for (struct Entry *entry = head; entry; entry = entry->next) { - if (entry->tag != tag.id) continue; + if (entry->tag.id != tag.id) continue; if (strcmp(entry->word, word)) continue; touch(entry); return; @@ -58,30 +58,28 @@ void tabTouch(struct Tag tag, const char *word) { struct Entry *entry = malloc(sizeof(*entry)); if (!entry) err(EX_OSERR, "malloc"); - entry->tag = tag.id; + entry->tag = tag; entry->word = strdup(word); if (!entry->word) err(EX_OSERR, "strdup"); prepend(entry); } -void tabReplace(const char *prev, const char *next) { - for (struct Entry *entry = head; entry; entry = entry->next) { - if (strcmp(entry->word, prev)) continue; - free(entry->word); - entry->word = strdup(next); - if (!entry->word) err(EX_OSERR, "strdup"); - } +void tabReplace(struct Tag tag, const char *prev, const char *next) { + tabTouch(tag, prev); + free(head->word); + head->word = strdup(next); + if (!head->word) err(EX_OSERR, "strdup"); } -static struct Entry *match; +static struct Entry *iter; void tabRemove(struct Tag tag, const char *word) { for (struct Entry *entry = head; entry; entry = entry->next) { - if (tag.id != TAG_ALL.id && entry->tag != tag.id) continue; + if (entry->tag.id != tag.id) continue; if (strcmp(entry->word, word)) continue; + if (iter == entry) iter = entry->prev; unlink(entry); - if (match == entry) match = entry->prev; free(entry->word); free(entry); return; @@ -90,33 +88,44 @@ void tabRemove(struct Tag tag, const char *word) { void tabClear(struct Tag tag) { for (struct Entry *entry = head; entry; entry = entry->next) { - if (entry->tag != tag.id) continue; + if (entry->tag.id != tag.id) continue; + if (iter == entry) iter = entry->prev; unlink(entry); - if (match == entry) match = entry->prev; free(entry->word); free(entry); } } +struct Tag tabTag(const char *word) { + struct Entry *start = (iter ? iter->next : head); + for (struct Entry *entry = start; entry; entry = entry->next) { + if (strcmp(entry->word, word)) continue; + iter = entry; + return entry->tag; + } + iter = NULL; + return TAG_NONE; +} + const char *tabNext(struct Tag tag, const char *prefix) { size_t len = strlen(prefix); - struct Entry *start = (match ? match->next : head); + struct Entry *start = (iter ? iter->next : head); for (struct Entry *entry = start; entry; entry = entry->next) { - if (entry->tag != TAG_DEFAULT.id && entry->tag != tag.id) continue; + if (entry->tag.id != TAG_NONE.id && entry->tag.id != tag.id) continue; if (strncasecmp(entry->word, prefix, len)) continue; - match = entry; + iter = entry; return entry->word; } - if (!match) return NULL; - match = NULL; + if (!iter) return NULL; + iter = NULL; return tabNext(tag, prefix); } void tabAccept(void) { - if (match) touch(match); - match = NULL; + if (iter) touch(iter); + iter = NULL; } void tabReject(void) { - match = NULL; + iter = NULL; } -- cgit 1.4.0 > 2020-12-02Fix missing "to" in "hot tips"June McEnroe 2020-12-02Publish "hot tips"June McEnroe 2020-11-26Publish "Inability"June McEnroe I don't know, it's something. 2020-11-26Render content into atom feedJune McEnroe And fix some atom lints. 2020-11-26Update plan with different things I won't doJune McEnroe 2020-11-19Add "Come On Petunia"June McEnroe 2020-11-13Add x4 to LESSJune McEnroe 2020-11-04Remove modified sensitivity settingsJune McEnroe 2020-10-29Remove editJune McEnroe 2020-10-27Switch gr alias back to git rebaseJune McEnroe I always type out git reset and sometimes still expect gr to be rebase... Never got used to it I guess. 2020-10-27Allow cd host: to cd to same path over sshJune McEnroe 2020-10-27Use SendEnv for cd host:pathJune McEnroe Works properly for weird paths, etc. 2020-10-27Allow cd host:path over sshJune McEnroe Requires AcceptEnv SSH_CD in the remote sshd_config. 2020-10-07Use mandoc -T utf8 for text.June McEnroe Don't depend on LANG being set. 2020-09-20Add The Awakened KingdomJune McEnroe A cute extra novella. Finally finished this series. 2020-09-12Move /opt/local back, cheat port select to use system manJune McEnroe This is not really how you're supposed to use the select system, I don't think, since the mandoc package actually creates those files, but it does work. This lets me actually use the git installed by MacPorts. 2020-09-12Move /opt/local behind /usr againJune McEnroe The reason I did this with pkgsrc was because I actually don't want the man(1) from mandoc, since it won't follow MANSECT. Same applies to MacPorts. I wish I could disable its man(1) with a variant or whatever. 2020-09-12Enable toc in cgit renderings of man pagesJune McEnroe But keep it disabled for READMEs since they always use non-standard sections and the TOC is just distracting there, I think. Also add the style so its h1 is the same size as the ones inside sections... 2020-09-11Install mandoc on macOSJune McEnroe 2020-09-11Rewrite install script yet againJune McEnroe 2020-09-11Remove NetBSD from install scriptJune McEnroe I never use it. 2020-09-11Use MacPorts rather than pkgsrcJune McEnroe My system is probably such a mess now... 2020-09-11Add debian VM name to sshJune McEnroe 2020-09-11Add influencer tweetJune McEnroe 2020-09-10Add The Kingdom of GodsJune McEnroe Reading has really slowed down :( 2020-09-07Add SunglassesJune McEnroe An IRC find. 2020-09-06Add Between the BreathsJune McEnroe One of those good songs from a soundtrack of a film that probably isn't? The summary sounds a lot more interesting than the title implies, at least. 2020-09-04Open /dev/tty in nudgeJune McEnroe This makes it work even when it's run connected to a pipe, i.e. as the notify command of catgirl... 2020-09-04Add nudgeJune McEnroe 2020-09-03Build fbclock with -lzJune McEnroe I guess this got lost somewhere, long ago... 2020-08-29Add tweets from retweetsJune McEnroe