Populate tab-complete list

master
Curtis McEnroe 2018-08-07 14:58:32 -04:00
parent 9ccb25a1a5
commit 5d2b5cd51e
No known key found for this signature in database
GPG Key ID: CEA2F97ADCFCD77C
5 changed files with 86 additions and 1 deletions

View File

@ -3,7 +3,7 @@ CFLAGS += -Wall -Wextra -Wpedantic
CFLAGS += -I/usr/local/include CFLAGS += -I/usr/local/include
LDFLAGS += -L/usr/local/lib LDFLAGS += -L/usr/local/lib
LDLIBS = -lcursesw -ltls LDLIBS = -lcursesw -ltls
OBJS = chat.o handle.o input.o irc.o pls.o ui.o OBJS = chat.o handle.o input.o irc.o pls.o tab.o ui.o
all: tags chat all: tags chat

1
README
View File

@ -8,4 +8,5 @@ This software targets FreeBSD and requires LibreSSL.
irc.c TLS client connection irc.c TLS client connection
input.c Input command handling input.c Input command handling
handle.c Incoming command handling handle.c Incoming command handling
tab.c Tab-complete
pls.c Functions which should not have to be written pls.c Functions which should not have to be written

4
chat.h
View File

@ -60,5 +60,9 @@ void uiFmt(const wchar_t *format, ...);
void handle(char *line); void handle(char *line);
void input(wchar_t *line); void input(wchar_t *line);
void tabTouch(const char *word);
void tabRemove(const char *word);
void tabReplace(const char *prev, const char *next);
wchar_t *wcssep(wchar_t **stringp, const wchar_t *delim); wchar_t *wcssep(wchar_t **stringp, const wchar_t *delim);
int vaswprintf(wchar_t **ret, const wchar_t *format, va_list ap); int vaswprintf(wchar_t **ret, const wchar_t *format, va_list ap);

View File

@ -81,6 +81,7 @@ static void handleJoin(char *prefix, char *params) {
free(chat.user); free(chat.user);
chat.user = strdup(user); chat.user = strdup(user);
} }
tabTouch(nick);
uiFmt( uiFmt(
"\3%d%s\3 arrives in \3%d%s\3", "\3%d%s\3 arrives in \3%d%s\3",
color(user), nick, color(chan), chan color(user), nick, color(chan), chan
@ -91,6 +92,7 @@ static void handlePart(char *prefix, char *params) {
char *nick = prift(&prefix); char *nick = prift(&prefix);
char *user = prift(&prefix); char *user = prift(&prefix);
char *chan = shift(&params); char *chan = shift(&params);
tabRemove(nick);
if (params) { if (params) {
char *mesg = shift(&params); char *mesg = shift(&params);
uiFmt( uiFmt(
@ -108,6 +110,7 @@ static void handlePart(char *prefix, char *params) {
static void handleQuit(char *prefix, char *params) { static void handleQuit(char *prefix, char *params) {
char *nick = prift(&prefix); char *nick = prift(&prefix);
char *user = prift(&prefix); char *user = prift(&prefix);
tabRemove(nick);
if (params) { if (params) {
char *mesg = shift(&params); char *mesg = shift(&params);
char *quot = (mesg[0] == '"') ? "" : "\""; char *quot = (mesg[0] == '"') ? "" : "\"";
@ -126,6 +129,7 @@ static void handleKick(char *prefix, char *params) {
char *chan = shift(&params); char *chan = shift(&params);
char *kick = shift(&params); char *kick = shift(&params);
char *mesg = shift(&params); char *mesg = shift(&params);
tabRemove(nick);
uiFmt( uiFmt(
"\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3, \"%s\"", "\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3, \"%s\"",
color(user), nick, color(kick), kick, color(chan), chan, mesg color(user), nick, color(kick), kick, color(chan), chan, mesg
@ -176,6 +180,7 @@ static void handle352(char *prefix, char *params) {
shift(&params); shift(&params);
shift(&params); shift(&params);
char *nick = shift(&params); char *nick = shift(&params);
tabTouch(nick);
size_t cap = sizeof(who.buf) - who.len; size_t cap = sizeof(who.buf) - who.len;
int len = snprintf( int len = snprintf(
&who.buf[who.len], cap, &who.buf[who.len], cap,
@ -204,6 +209,7 @@ static void handleNick(char *prefix, char *params) {
free(chat.nick); free(chat.nick);
chat.nick = strdup(next); chat.nick = strdup(next);
} }
tabReplace(prev, next);
uiFmt( uiFmt(
"\3%d%s\3 is now known as \3%d%s\3", "\3%d%s\3 is now known as \3%d%s\3",
color(user), prev, color(user), next color(user), prev, color(user), next
@ -215,6 +221,7 @@ static void handlePrivmsg(char *prefix, char *params) {
char *user = prift(&prefix); char *user = prift(&prefix);
shift(&params); shift(&params);
char *mesg = shift(&params); char *mesg = shift(&params);
tabTouch(nick);
if (mesg[0] == '\1') { if (mesg[0] == '\1') {
strsep(&mesg, " "); strsep(&mesg, " ");
char *action = strsep(&mesg, "\1"); char *action = strsep(&mesg, "\1");
@ -230,6 +237,7 @@ static void handleNotice(char *prefix, char *params) {
char *chan = shift(&params); char *chan = shift(&params);
char *mesg = shift(&params); char *mesg = shift(&params);
if (strcmp(chat.chan, chan)) return; if (strcmp(chat.chan, chan)) return;
tabTouch(nick);
uiFmt("-\3%d%s\3- %s", color(user), nick, mesg); uiFmt("-\3%d%s\3- %s", color(user), nick, mesg);
} }

72
tab.c 100644
View File

@ -0,0 +1,72 @@
/* Copyright (C) 2018 Curtis McEnroe <june@causal.agency>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <err.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include "chat.h"
static struct Entry {
char *word;
struct Entry *prev;
struct Entry *next;
} *head;
static void prepend(struct Entry *entry) {
entry->prev = NULL;
entry->next = head;
if (head) head->prev = entry;
head = entry;
}
static void remove(struct Entry *entry) {
if (entry->prev) entry->prev->next = entry->next;
if (entry->next) entry->next->prev = entry->prev;
if (head == entry) head = entry->next;
}
void tabTouch(const char *word) {
for (struct Entry *entry = head; entry; entry = entry->next) {
if (strcmp(entry->word, word)) continue;
if (head == entry) return;
remove(entry);
prepend(entry);
return;
}
struct Entry *entry = malloc(sizeof(*entry));
if (!entry) err(EX_OSERR, "malloc");
entry->word = strdup(word);
prepend(entry);
}
void tabRemove(const char *word) {
for (struct Entry *entry = head; entry; entry = entry->next) {
if (strcmp(entry->word, word)) continue;
remove(entry);
free(entry->word);
free(entry);
return;
}
}
void tabReplace(const char *prev, const char *next) {
tabTouch(prev);
free(head->word);
head->word = strdup(next);
}