Moved lastmsgs variables from irc-server and channel structures to

irc-completion.

/MSG nick completion now gives the nicks in right time order when using
multiple irc networks.


git-svn-id: http://svn.irssi.org/repos/irssi/trunk@568 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
Timo Sirainen 2000-07-31 23:09:39 +00:00 committed by cras
parent b26ea5d4e7
commit ce821e96a1
4 changed files with 181 additions and 59 deletions

View File

@ -96,8 +96,48 @@ static void nick_completion_remove_old(GSList **list, int timeout, time_t now)
} }
} }
static void last_msg_add(MODULE_SERVER_REC *mserver, const char *nick)
{
LAST_MSG_REC *rec;
rec = g_new(LAST_MSG_REC, 1);
rec->time = time(NULL);
rec->nick = g_strdup(nick);
mserver->lastmsgs = g_slist_append(mserver->lastmsgs, rec);
}
static void last_msg_free(MODULE_SERVER_REC *mserver, LAST_MSG_REC *rec)
{
mserver->lastmsgs = g_slist_remove(mserver->lastmsgs, rec);
g_free(rec->nick);
g_free(rec);
}
static LAST_MSG_REC *last_msg_find(MODULE_SERVER_REC *mserver, const char *nick)
{
GSList *tmp;
for (tmp = mserver->lastmsgs; tmp != NULL; tmp = tmp->next) {
LAST_MSG_REC *rec = tmp->data;
if (g_strcasecmp(rec->nick, nick) == 0)
return rec;
}
return NULL;
}
static int last_msg_cmp(LAST_MSG_REC *m1, LAST_MSG_REC *m2)
{
return m1->time < m2->time ? 1 : -1;
}
static int nick_completion_timeout(void) static int nick_completion_timeout(void)
{ {
MODULE_SERVER_REC *mserver;
MODULE_CHANNEL_REC *mchannel;
GSList *tmp, *link; GSList *tmp, *link;
time_t now; time_t now;
int len; int len;
@ -109,19 +149,20 @@ static int nick_completion_timeout(void)
if (!irc_server_check(rec)) if (!irc_server_check(rec))
continue; continue;
len = g_slist_length(rec->lastmsgs); mserver = MODULE_DATA(rec);
len = g_slist_length(mserver->lastmsgs);
if (len > 0 && len >= settings_get_int("completion_keep_privates")) { if (len > 0 && len >= settings_get_int("completion_keep_privates")) {
link = g_slist_last(rec->lastmsgs); link = g_slist_last(mserver->lastmsgs);
g_free(link->data); last_msg_free(mserver, link->data);
rec->lastmsgs = g_slist_remove(rec->lastmsgs, link->data);
} }
} }
for (tmp = channels; tmp != NULL; tmp = tmp->next) { for (tmp = channels; tmp != NULL; tmp = tmp->next) {
CHANNEL_REC *rec = tmp->data; CHANNEL_REC *rec = tmp->data;
nick_completion_remove_old(&rec->lastownmsgs, settings_get_int("completion_keep_ownpublics"), now); mchannel = MODULE_DATA(rec);
nick_completion_remove_old(&rec->lastmsgs, settings_get_int("completion_keep_publics"), now); nick_completion_remove_old(&mchannel->lastownmsgs, settings_get_int("completion_keep_ownpublics"), now);
nick_completion_remove_old(&mchannel->lastmsgs, settings_get_int("completion_keep_publics"), now);
} }
return 1; return 1;
@ -161,14 +202,15 @@ static NICK_COMPLETION_REC *nick_completion_create(GSList **list, time_t time, c
static void add_private_msg(IRC_SERVER_REC *server, const char *nick) static void add_private_msg(IRC_SERVER_REC *server, const char *nick)
{ {
GSList *link; MODULE_SERVER_REC *mserver;
LAST_MSG_REC *msg;
link = gslist_find_icase_string(server->lastmsgs, nick); mserver = MODULE_DATA(server);
if (link != NULL) { msg = last_msg_find(mserver, nick);
g_free(link->data); if (msg != NULL)
server->lastmsgs = g_slist_remove(server->lastmsgs, link->data); msg->time = time(NULL);
} else
server->lastmsgs = g_slist_prepend(server->lastmsgs, g_strdup(nick)); last_msg_add(mserver, nick);
} }
static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char *nick) static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char *nick)
@ -183,6 +225,7 @@ static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char *
if (ischannel(*target)) { if (ischannel(*target)) {
/* channel message */ /* channel message */
MODULE_CHANNEL_REC *mchannel;
CHANNEL_REC *channel; CHANNEL_REC *channel;
channel = channel_find(server, target); channel = channel_find(server, target);
@ -191,9 +234,10 @@ static void event_privmsg(const char *data, IRC_SERVER_REC *server, const char *
return; return;
} }
mchannel = MODULE_DATA(channel);
list = irc_nick_match(server->nick, msg) ? list = irc_nick_match(server->nick, msg) ?
&channel->lastownmsgs : &mchannel->lastownmsgs :
&channel->lastmsgs; &mchannel->lastmsgs;
nick_completion_create(list, time(NULL), nick); nick_completion_create(list, time(NULL), nick);
} else { } else {
/* private message */ /* private message */
@ -228,25 +272,31 @@ static void cmd_msg(const char *data, IRC_SERVER_REC *server)
static void sig_nick_removed(CHANNEL_REC *channel, NICK_REC *nick) static void sig_nick_removed(CHANNEL_REC *channel, NICK_REC *nick)
{ {
NICK_COMPLETION_REC *rec; NICK_COMPLETION_REC *rec;
MODULE_CHANNEL_REC *mchannel;
rec = nick_completion_find(channel->lastownmsgs, nick->nick); mchannel = MODULE_DATA(channel);
if (rec != NULL) nick_completion_destroy(&channel->lastownmsgs, rec);
rec = nick_completion_find(channel->lastmsgs, nick->nick); rec = nick_completion_find(mchannel->lastownmsgs, nick->nick);
if (rec != NULL) nick_completion_destroy(&channel->lastmsgs, rec); if (rec != NULL) nick_completion_destroy(&mchannel->lastownmsgs, rec);
rec = nick_completion_find(mchannel->lastmsgs, nick->nick);
if (rec != NULL) nick_completion_destroy(&mchannel->lastmsgs, rec);
} }
static void sig_nick_changed(CHANNEL_REC *channel, NICK_REC *nick, const char *oldnick) static void sig_nick_changed(CHANNEL_REC *channel, NICK_REC *nick, const char *oldnick)
{ {
NICK_COMPLETION_REC *rec; NICK_COMPLETION_REC *rec;
MODULE_CHANNEL_REC *mchannel;
rec = nick_completion_find(channel->lastownmsgs, oldnick); mchannel = MODULE_DATA(channel);
rec = nick_completion_find(mchannel->lastownmsgs, oldnick);
if (rec != NULL) { if (rec != NULL) {
g_free(rec->nick); g_free(rec->nick);
rec->nick = g_strdup(nick->nick); rec->nick = g_strdup(nick->nick);
} }
rec = nick_completion_find(channel->lastmsgs, oldnick); rec = nick_completion_find(mchannel->lastmsgs, oldnick);
if (rec != NULL) { if (rec != NULL) {
g_free(rec->nick); g_free(rec->nick);
rec->nick = g_strdup(nick->nick); rec->nick = g_strdup(nick->nick);
@ -254,42 +304,69 @@ static void sig_nick_changed(CHANNEL_REC *channel, NICK_REC *nick, const char *o
} }
/* Complete /MSG from specified server */ /* Complete /MSG from specified server */
static GList *completion_msg_server(IRC_SERVER_REC *server, const char *nick, const char *prefix) static void completion_msg_server(GSList **list, IRC_SERVER_REC *server,
const char *nick, const char *prefix)
{ {
MODULE_SERVER_REC *mserver;
LAST_MSG_REC *msg;
GSList *tmp; GSList *tmp;
GList *list;
int len; int len;
g_return_val_if_fail(nick != NULL, NULL); g_return_if_fail(nick != NULL);
list = NULL; len = strlen(nick); mserver = MODULE_DATA(server);
for (tmp = server->lastmsgs; tmp != NULL; tmp = tmp->next) { len = strlen(nick);
if (len == 0 || g_strncasecmp(tmp->data, nick, len) == 0) { for (tmp = mserver->lastmsgs; tmp != NULL; tmp = tmp->next) {
if (prefix == NULL || *prefix == '\0') LAST_MSG_REC *rec = tmp->data;
list = g_list_append(list, g_strdup(tmp->data));
else if (len != 0 && g_strncasecmp(rec->nick, nick, len) != 0)
list = g_list_append(list, g_strconcat(prefix, " ", tmp->data, NULL)); continue;
}
msg = g_new(LAST_MSG_REC, 1);
msg->time = rec->time;
msg->nick = prefix == NULL || *prefix == '\0' ?
g_strdup(rec->nick) :
g_strconcat(prefix, " ", rec->nick, NULL);
*list = g_slist_insert_sorted(*list, msg,
(GCompareFunc) last_msg_cmp);
}
}
static GList *convert_msglist(GSList *msglist)
{
GList *list;
list = NULL;
while (msglist != NULL) {
LAST_MSG_REC *rec = msglist->data;
list = g_list_append(list, g_strdup(rec->nick));
msglist = g_slist_remove(msglist, rec);
g_free(rec->nick);
g_free(rec);
} }
return list; return list;
} }
/* Complete /MSG - if `server' is NULL, complete nicks from all servers */ /* Complete /MSG - if `find_server' is NULL, complete nicks from all servers */
static GList *completion_msg(IRC_SERVER_REC *win_server, IRC_SERVER_REC *find_server, static GList *completion_msg(IRC_SERVER_REC *win_server,
IRC_SERVER_REC *find_server,
const char *nick, const char *prefix) const char *nick, const char *prefix)
{ {
GSList *tmp; GSList *tmp, *list;
GList *list, *tmplist;
char *newprefix; char *newprefix;
g_return_val_if_fail(nick != NULL, NULL); g_return_val_if_fail(nick != NULL, NULL);
if (servers == NULL) return NULL; if (servers == NULL) return NULL;
if (find_server != NULL)
return completion_msg_server(find_server, nick, prefix);
list = NULL; list = NULL;
if (find_server != NULL) {
completion_msg_server(&list, find_server, nick, prefix);
return convert_msglist(list);
}
for (tmp = servers; tmp != NULL; tmp = tmp->next) { for (tmp = servers; tmp != NULL; tmp = tmp->next) {
IRC_SERVER_REC *rec = tmp->data; IRC_SERVER_REC *rec = tmp->data;
@ -301,13 +378,11 @@ static GList *completion_msg(IRC_SERVER_REC *win_server, IRC_SERVER_REC *find_se
g_strdup_printf("%s -%s", prefix, rec->tag); g_strdup_printf("%s -%s", prefix, rec->tag);
} }
tmplist = completion_msg_server(rec, nick, newprefix); completion_msg_server(&list, rec, nick, newprefix);
list = g_list_concat(list, tmplist);
g_free_not_null(newprefix); g_free_not_null(newprefix);
} }
return list; return convert_msglist(list);
} }
static void complete_from_nicklist(GList **outlist, GSList *list, static void complete_from_nicklist(GList **outlist, GSList *list,
@ -332,6 +407,7 @@ static void complete_from_nicklist(GList **outlist, GSList *list,
static GList *completion_channel_nicks(CHANNEL_REC *channel, const char *nick, const char *prefix) static GList *completion_channel_nicks(CHANNEL_REC *channel, const char *nick, const char *prefix)
{ {
MODULE_CHANNEL_REC *mchannel;
GSList *nicks, *tmp; GSList *nicks, *tmp;
GList *list; GList *list;
int len; int len;
@ -342,8 +418,9 @@ static GList *completion_channel_nicks(CHANNEL_REC *channel, const char *nick, c
/* put first the nicks who have recently said something [to you] */ /* put first the nicks who have recently said something [to you] */
list = NULL; list = NULL;
complete_from_nicklist(&list, channel->lastownmsgs, nick, prefix); mchannel = MODULE_DATA(channel);
complete_from_nicklist(&list, channel->lastmsgs, nick, prefix); complete_from_nicklist(&list, mchannel->lastownmsgs, nick, prefix);
complete_from_nicklist(&list, mchannel->lastmsgs, nick, prefix);
/* and add the rest of the nicks too */ /* and add the rest of the nicks too */
len = strlen(nick); len = strlen(nick);
@ -570,28 +647,59 @@ static void event_text(gchar *line, IRC_SERVER_REC *server, WI_IRC_REC *item)
signal_stop(); signal_stop();
} }
static void completion_deinit_server(IRC_SERVER_REC *server) static void completion_init_server(IRC_SERVER_REC *server)
{ {
MODULE_SERVER_REC *rec;
g_return_if_fail(server != NULL); g_return_if_fail(server != NULL);
if (!irc_server_check(server)) if (!irc_server_check(server))
return; return;
g_slist_foreach(server->lastmsgs, (GFunc) g_free, NULL); rec = g_new0(MODULE_SERVER_REC, 1);
g_slist_free(server->lastmsgs); MODULE_DATA_SET(server, rec);
}
static void completion_deinit_server(IRC_SERVER_REC *server)
{
MODULE_SERVER_REC *mserver;
g_return_if_fail(server != NULL);
if (!irc_server_check(server))
return;
mserver = MODULE_DATA(server);
while (mserver->lastmsgs)
last_msg_free(mserver, mserver->lastmsgs->data);
g_free(mserver);
}
static void completion_init_channel(CHANNEL_REC *channel)
{
MODULE_CHANNEL_REC *rec;
g_return_if_fail(channel != NULL);
rec = g_new0(MODULE_CHANNEL_REC, 1);
MODULE_DATA_SET(channel, rec);
} }
static void completion_deinit_channel(CHANNEL_REC *channel) static void completion_deinit_channel(CHANNEL_REC *channel)
{ {
MODULE_CHANNEL_REC *mchannel;
g_return_if_fail(channel != NULL); g_return_if_fail(channel != NULL);
while (channel->lastmsgs != NULL) mchannel = MODULE_DATA(channel);
nick_completion_destroy(&channel->lastmsgs, channel->lastmsgs->data); while (mchannel->lastmsgs != NULL)
while (channel->lastownmsgs != NULL) nick_completion_destroy(&mchannel->lastmsgs, mchannel->lastmsgs->data);
nick_completion_destroy(&channel->lastownmsgs, channel->lastownmsgs->data); while (mchannel->lastownmsgs != NULL)
nick_completion_destroy(&mchannel->lastownmsgs, mchannel->lastownmsgs->data);
g_slist_free(channel->lastmsgs); g_slist_free(mchannel->lastmsgs);
g_slist_free(channel->lastownmsgs); g_slist_free(mchannel->lastownmsgs);
g_free(mchannel);
} }
void irc_completion_init(void) void irc_completion_init(void)
@ -612,8 +720,10 @@ void irc_completion_init(void)
signal_add("nicklist remove", (SIGNAL_FUNC) sig_nick_removed); signal_add("nicklist remove", (SIGNAL_FUNC) sig_nick_removed);
signal_add("nicklist changed", (SIGNAL_FUNC) sig_nick_changed); signal_add("nicklist changed", (SIGNAL_FUNC) sig_nick_changed);
signal_add("send text", (SIGNAL_FUNC) event_text); signal_add("send text", (SIGNAL_FUNC) event_text);
signal_add("server connected", (SIGNAL_FUNC) completion_init_server);
signal_add("server disconnected", (SIGNAL_FUNC) completion_deinit_server); signal_add("server disconnected", (SIGNAL_FUNC) completion_deinit_server);
signal_add("channel destroyed", (SIGNAL_FUNC) completion_deinit_channel); signal_add("channel created", (SIGNAL_FUNC) completion_init_channel);
signal_add_last("channel destroyed", (SIGNAL_FUNC) completion_deinit_channel);
} }
void irc_completion_deinit(void) void irc_completion_deinit(void)
@ -627,6 +737,8 @@ void irc_completion_deinit(void)
signal_remove("nicklist remove", (SIGNAL_FUNC) sig_nick_removed); signal_remove("nicklist remove", (SIGNAL_FUNC) sig_nick_removed);
signal_remove("nicklist changed", (SIGNAL_FUNC) sig_nick_changed); signal_remove("nicklist changed", (SIGNAL_FUNC) sig_nick_changed);
signal_remove("send text", (SIGNAL_FUNC) event_text); signal_remove("send text", (SIGNAL_FUNC) event_text);
signal_remove("server connected", (SIGNAL_FUNC) completion_init_server);
signal_remove("server disconnected", (SIGNAL_FUNC) completion_deinit_server); signal_remove("server disconnected", (SIGNAL_FUNC) completion_deinit_server);
signal_remove("channel created", (SIGNAL_FUNC) completion_init_channel);
signal_remove("channel destroyed", (SIGNAL_FUNC) completion_deinit_channel); signal_remove("channel destroyed", (SIGNAL_FUNC) completion_deinit_channel);
} }

View File

@ -1,3 +1,17 @@
#include "common.h" #include "common.h"
#define MODULE_NAME "fe-common/irc" #define MODULE_NAME "fe-common/irc"
typedef struct {
time_t time;
char *nick;
} LAST_MSG_REC;
typedef struct {
GSList *lastmsgs; /* List of nicks who last send you msg */
} MODULE_SERVER_REC;
typedef struct {
GSList *lastmsgs; /* List of nicks who last send message */
GSList *lastownmsgs; /* List of nicks who last send message to you */
} MODULE_CHANNEL_REC;

View File

@ -50,9 +50,6 @@ typedef struct {
time_t massjoin_start; /* Massjoin start time */ time_t massjoin_start; /* Massjoin start time */
int massjoins; /* Number of nicks waiting for massjoin signal.. */ int massjoins; /* Number of nicks waiting for massjoin signal.. */
int last_massjoins; /* Massjoins when last checked in timeout function */ int last_massjoins; /* Massjoins when last checked in timeout function */
GSList *lastmsgs; /* List of nicks who last send message */
GSList *lastownmsgs; /* List of nicks who last send message to you */
} CHANNEL_REC; } CHANNEL_REC;
extern GSList *channels; extern GSList *channels;

View File

@ -125,7 +125,6 @@ typedef struct {
GSList *knockoutlist; GSList *knockoutlist;
time_t knockout_lastcheck; time_t knockout_lastcheck;
GSList *lastmsgs; /* List of nicks who last send you msg */
GHashTable *splits; /* For keeping track of netsplits */ GHashTable *splits; /* For keeping track of netsplits */
GSList *split_servers; /* Servers that are currently in split */ GSList *split_servers; /* Servers that are currently in split */