degesch: fix handling of buffer collisions
This commit is contained in:
parent
d2611d3f82
commit
de019e7832
105
degesch.c
105
degesch.c
|
@ -2669,20 +2669,23 @@ buffer_merge (struct app_context *ctx,
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
for (struct buffer_line *iter = start; iter; iter = iter->next)
|
for (struct buffer_line *iter = start; iter; iter = iter->next)
|
||||||
n++;
|
n++;
|
||||||
|
struct buffer_line *tail = merged->lines_tail;
|
||||||
|
|
||||||
// Append the merged part to current lines in the buffer
|
// Cut them from the original buffer
|
||||||
|
if (start == merged->lines)
|
||||||
|
merged->lines = NULL;
|
||||||
|
else if (start->prev)
|
||||||
|
start->prev->next = NULL;
|
||||||
|
if (start == merged->lines_tail)
|
||||||
|
merged->lines_tail = start->prev;
|
||||||
|
merged->lines_count -= n;
|
||||||
|
|
||||||
|
// And append them to current lines in the buffer
|
||||||
buffer->lines_tail->next = start;
|
buffer->lines_tail->next = start;
|
||||||
start->prev = buffer->lines_tail;
|
start->prev = buffer->lines_tail;
|
||||||
|
buffer->lines_tail = tail;
|
||||||
buffer->lines_tail = merged->lines_tail;
|
|
||||||
buffer->lines_count += n;
|
buffer->lines_count += n;
|
||||||
|
|
||||||
// And remove it from the original buffer
|
|
||||||
if (start == merged->lines_tail)
|
|
||||||
if (!(merged->lines_tail = start->prev))
|
|
||||||
merged->lines = NULL;
|
|
||||||
merged->lines_count -= n;
|
|
||||||
|
|
||||||
// XXX: we don't want to log this entry to a file
|
// XXX: we don't want to log this entry to a file
|
||||||
buffer_send_status (ctx, buffer, "End of merged content");
|
buffer_send_status (ctx, buffer, "End of merged content");
|
||||||
}
|
}
|
||||||
|
@ -2691,39 +2694,20 @@ static void
|
||||||
buffer_rename (struct app_context *ctx,
|
buffer_rename (struct app_context *ctx,
|
||||||
struct buffer *buffer, const char *new_name)
|
struct buffer *buffer, const char *new_name)
|
||||||
{
|
{
|
||||||
hard_assert (buffer->type == BUFFER_PM);
|
struct buffer *collision = str_map_find (&ctx->buffers_by_name, new_name);
|
||||||
|
if (collision == buffer)
|
||||||
|
return;
|
||||||
|
|
||||||
// FIXME: this will never find anything as we are being sent
|
hard_assert (!collision);
|
||||||
// the full buffer name, including the server name;
|
|
||||||
// searching in "buffers_by_name" won't do it either,
|
|
||||||
// we seem to need more information to properly handle this
|
|
||||||
struct buffer *collision =
|
|
||||||
str_map_find (&buffer->server->irc_buffer_map, new_name);
|
|
||||||
if (collision)
|
|
||||||
{
|
|
||||||
// TODO: use full weechat-style buffer names
|
|
||||||
// to prevent name collisions with the global buffer
|
|
||||||
hard_assert (collision->type == BUFFER_PM);
|
|
||||||
|
|
||||||
// When there's a collision, there's not much else we can do
|
str_map_set (&ctx->buffers_by_name, buffer->name, NULL);
|
||||||
// other than somehow trying to merge them
|
str_map_set (&ctx->buffers_by_name, new_name, buffer);
|
||||||
buffer_merge (ctx, collision, buffer);
|
|
||||||
if (ctx->current_buffer == buffer)
|
|
||||||
buffer_activate (ctx, collision);
|
|
||||||
buffer_remove (ctx, buffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Otherwise we just rename the buffer and that's it
|
|
||||||
str_map_set (&ctx->buffers_by_name, buffer->name, NULL);
|
|
||||||
str_map_set (&ctx->buffers_by_name, new_name, buffer);
|
|
||||||
|
|
||||||
free (buffer->name);
|
free (buffer->name);
|
||||||
buffer->name = xstrdup (new_name);
|
buffer->name = xstrdup (new_name);
|
||||||
|
|
||||||
// We might have renamed the current buffer
|
// We might have renamed the current buffer
|
||||||
refresh_prompt (ctx);
|
refresh_prompt (ctx);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -4373,6 +4357,27 @@ irc_handle_mode (struct server *s, const struct irc_message *msg)
|
||||||
refresh_prompt (s->ctx);
|
refresh_prompt (s->ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct buffer *
|
||||||
|
irc_handle_buffer_collision (struct server *s,
|
||||||
|
struct buffer *buffer, const char *new_name)
|
||||||
|
{
|
||||||
|
struct buffer *collision = str_map_find (&s->irc_buffer_map, new_name);
|
||||||
|
if (!collision)
|
||||||
|
return buffer;
|
||||||
|
|
||||||
|
// TODO: use full weechat-style buffer names
|
||||||
|
// to prevent name collisions with the global buffer
|
||||||
|
hard_assert (collision->type == buffer->type);
|
||||||
|
|
||||||
|
// When there's a collision, there's not much else we can do
|
||||||
|
// other than somehow try to merge them
|
||||||
|
buffer_merge (s->ctx, collision, buffer);
|
||||||
|
if (s->ctx->current_buffer == buffer)
|
||||||
|
buffer_activate (s->ctx, collision);
|
||||||
|
buffer_remove (s->ctx, buffer);
|
||||||
|
return collision;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
irc_handle_nick (struct server *s, const struct irc_message *msg)
|
irc_handle_nick (struct server *s, const struct irc_message *msg)
|
||||||
{
|
{
|
||||||
|
@ -4402,12 +4407,6 @@ irc_handle_nick (struct server *s, const struct irc_message *msg)
|
||||||
str_map_find (&s->irc_buffer_map, user->nickname);
|
str_map_find (&s->irc_buffer_map, user->nickname);
|
||||||
if (pm_buffer)
|
if (pm_buffer)
|
||||||
{
|
{
|
||||||
if (!lexicographically_identical)
|
|
||||||
{
|
|
||||||
str_map_set (&s->irc_buffer_map, new_nickname, pm_buffer);
|
|
||||||
str_map_set (&s->irc_buffer_map, user->nickname, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *who = irc_is_this_us (s, msg->prefix)
|
char *who = irc_is_this_us (s, msg->prefix)
|
||||||
? irc_to_utf8 (s->ctx, msg->prefix)
|
? irc_to_utf8 (s->ctx, msg->prefix)
|
||||||
: NULL;
|
: NULL;
|
||||||
|
@ -4415,6 +4414,21 @@ irc_handle_nick (struct server *s, const struct irc_message *msg)
|
||||||
.who = who,
|
.who = who,
|
||||||
.object = irc_to_utf8 (s->ctx, new_nickname));
|
.object = irc_to_utf8 (s->ctx, new_nickname));
|
||||||
|
|
||||||
|
if (!lexicographically_identical)
|
||||||
|
{
|
||||||
|
// XXX: this code seems a bit ugly (but also necessary)
|
||||||
|
user = user_ref (user);
|
||||||
|
|
||||||
|
pm_buffer = irc_handle_buffer_collision
|
||||||
|
(s, pm_buffer, new_nickname);
|
||||||
|
|
||||||
|
user_unref (pm_buffer->user);
|
||||||
|
pm_buffer->user = user;
|
||||||
|
|
||||||
|
str_map_set (&s->irc_buffer_map, user->nickname, NULL);
|
||||||
|
str_map_set (&s->irc_buffer_map, new_nickname, pm_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
char *x = xstrdup_printf ("%s.%s", s->name, new_nickname);
|
char *x = xstrdup_printf ("%s.%s", s->name, new_nickname);
|
||||||
buffer_rename (s->ctx, pm_buffer, x);
|
buffer_rename (s->ctx, pm_buffer, x);
|
||||||
free (x);
|
free (x);
|
||||||
|
@ -4453,8 +4467,9 @@ irc_handle_nick (struct server *s, const struct irc_message *msg)
|
||||||
// Finally rename the user
|
// Finally rename the user
|
||||||
if (!lexicographically_identical)
|
if (!lexicographically_identical)
|
||||||
{
|
{
|
||||||
str_map_set (&s->irc_users, new_nickname, user_ref (user));
|
// NOTE: this doesn't dereference anything
|
||||||
str_map_set (&s->irc_users, user->nickname, NULL);
|
str_map_set (&s->irc_users, user->nickname, NULL);
|
||||||
|
str_map_set (&s->irc_users, new_nickname, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (user->nickname);
|
free (user->nickname);
|
||||||
|
|
Loading…
Reference in New Issue