Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.

Commit 21fe443

Browse files
committed
feature: nickname disambiguation
1 parent 80319b3 commit 21fe443

8 files changed

Lines changed: 285 additions & 23 deletions

File tree

src/twc-chat.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ twc_chat_new(struct t_twc_profile *profile, const char *name)
5757
chat->profile = profile;
5858
chat->friend_number = chat->group_number = -1;
5959
chat->nicks = NULL;
60+
chat->ids = NULL;
61+
chat->completion = NULL;
62+
chat->last_search = NULL;
63+
chat->prev_comp = NULL;
6064

6165
size_t full_name_size = strlen(profile->name) + 1 + strlen(name) + 1;
6266
char *full_name = malloc(full_name_size);
@@ -137,6 +141,8 @@ twc_chat_new_group(struct t_twc_profile *profile, int32_t group_number)
137141
chat->nicklist_group =
138142
weechat_nicklist_add_group(chat->buffer, NULL, NULL, NULL, true);
139143
chat->nicks = weechat_list_new();
144+
chat->ids = weechat_list_new();
145+
chat->completion = weechat_list_new();
140146

141147
weechat_buffer_set(chat->buffer, "nicklist", "1");
142148
}
@@ -395,6 +401,18 @@ twc_chat_free(struct t_twc_chat *chat)
395401
weechat_list_remove_all(chat->nicks);
396402
weechat_list_free(chat->nicks);
397403
}
404+
if (chat->ids)
405+
{
406+
weechat_list_remove_all(chat->ids);
407+
weechat_list_free(chat->ids);
408+
}
409+
if (chat->completion)
410+
{
411+
weechat_list_remove_all(chat->completion);
412+
weechat_list_free(chat->completion);
413+
}
414+
free(chat->last_search);
415+
free(chat->prev_comp);
398416
free(chat);
399417
}
400418

src/twc-chat.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ struct t_twc_chat
3939

4040
struct t_gui_nick_group *nicklist_group;
4141
struct t_weelist *nicks;
42+
struct t_weelist *ids;
43+
struct t_weelist *completion;
44+
char *last_search;
45+
char *prev_comp;
4246
};
4347

4448
struct t_twc_chat *

src/twc-commands.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,6 +1330,57 @@ twc_cmd_send(const void *pointer, void *data, struct t_gui_buffer *buffer,
13301330
return WEECHAT_RC_OK;
13311331
}
13321332

1333+
/**
1334+
* Custom completion for nicknames in groups.
1335+
*/
1336+
int
1337+
twc_input_complete(const void *pointer, void *data, struct t_gui_buffer *buffer,
1338+
const char *command)
1339+
{
1340+
struct t_twc_chat *chat = twc_chat_search_buffer(buffer);
1341+
if (chat && chat->group_number >= 0)
1342+
{
1343+
const char *input = weechat_buffer_get_string(buffer, "input");
1344+
if (!strcmp(input, ""))
1345+
return WEECHAT_RC_OK;
1346+
size_t last_search_len = chat->last_search ? strlen(chat->last_search) : 0;
1347+
int cmp = strncmp(chat->last_search, input, last_search_len);
1348+
if (cmp || !last_search_len)
1349+
{
1350+
free(chat->last_search);
1351+
chat->last_search = strdup(input);
1352+
free(chat->prev_comp);
1353+
chat->prev_comp = NULL;
1354+
twc_starts_with(chat->nicks, chat->last_search, chat->completion);
1355+
}
1356+
1357+
const char *comp =
1358+
twc_get_next_completion(chat->completion, chat->prev_comp);
1359+
if (!comp)
1360+
return WEECHAT_RC_OK;
1361+
1362+
weechat_buffer_set(buffer, "completion_freeze", "1");
1363+
1364+
char *terminator = ": "; /* Probably put it in a config */
1365+
char temp[strlen(comp) + strlen(terminator) + 1];
1366+
sprintf(temp, "%s%s", comp, terminator);
1367+
weechat_buffer_set(buffer, "input", temp);
1368+
1369+
int input_pos = weechat_buffer_get_integer(buffer, "input_length");
1370+
int input_pos_str_size = snprintf(NULL, 0, "%d", input_pos);
1371+
char input_pos_str[input_pos_str_size + 1];
1372+
snprintf(input_pos_str, input_pos_str_size + 1, "%d", input_pos);
1373+
weechat_buffer_set(buffer, "input_pos", input_pos_str);
1374+
1375+
weechat_buffer_set(buffer, "completion_freeze", "0");
1376+
1377+
free(chat->prev_comp);
1378+
chat->prev_comp = strdup(comp);
1379+
return WEECHAT_RC_OK_EAT;
1380+
}
1381+
return WEECHAT_RC_OK;
1382+
}
1383+
13331384
/**
13341385
* Register Tox-WeeChat commands.
13351386
*/
@@ -1421,6 +1472,9 @@ twc_commands_init()
14211472

14221473
weechat_hook_command_run("/save", twc_cmd_save, NULL, NULL);
14231474

1475+
weechat_hook_command_run("/input complete_next", twc_input_complete, NULL,
1476+
NULL);
1477+
14241478
weechat_hook_command("status", "change your Tox status", "online|busy|away",
14251479
"", NULL, twc_cmd_status, NULL, NULL);
14261480

src/twc-config.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct t_config_section *twc_config_section_profile_default = NULL;
3838

3939
struct t_config_option *twc_config_friend_request_message;
4040
struct t_config_option *twc_config_short_id_size;
41+
struct t_config_option *twc_config_show_id;
4142

4243
char *twc_profile_option_names[TWC_PROFILE_NUM_OPTIONS] = {
4344
"save_file",
@@ -374,6 +375,11 @@ twc_config_init()
374375
NULL, 2, TOX_PUBLIC_KEY_SIZE * 2, "8", NULL, 0,
375376
twc_config_check_value_callback, NULL, NULL, NULL, NULL, NULL, NULL,
376377
NULL, NULL);
378+
twc_config_show_id = weechat_config_new_option(
379+
twc_config_file, twc_config_section_look, "show_id", "boolean",
380+
"show short Tox IDs in message logs and presence logs of group chats",
381+
NULL, 0, 0, "on", NULL, 0, twc_config_check_value_callback, NULL, NULL,
382+
NULL, NULL, NULL, NULL, NULL, NULL);
377383
}
378384

379385
/**

src/twc-config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct t_twc_profile;
2424

2525
extern struct t_config_option *twc_config_friend_request_message;
2626
extern struct t_config_option *twc_config_short_id_size;
27+
extern struct t_config_option *twc_config_show_id;
2728

2829
enum t_twc_proxy
2930
{

src/twc-tox-callbacks.c

Lines changed: 77 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#endif /* TOXAV_ENABLED */
2929

3030
#include "twc-chat.h"
31+
#include "twc-config.h"
3132
#include "twc-friend-request.h"
3233
#include "twc-group-invite.h"
3334
#include "twc-message-queue.h"
@@ -412,6 +413,9 @@ twc_handle_group_message(Tox *tox, int32_t group_number, int32_t peer_number,
412413

413414
char *myname = twc_get_self_name_nt(profile->tox);
414415
char *name = twc_get_peer_name_nt(profile->tox, group_number, peer_number);
416+
char *short_id =
417+
twc_get_peer_id_short(profile->tox, group_number, peer_number);
418+
char *full_name = twc_get_peer_name_prefixed(short_id, name);
415419
char *tags = "notify_message";
416420
char *message_nt = twc_null_terminate(message, length);
417421

@@ -425,10 +429,14 @@ twc_handle_group_message(Tox *tox, int32_t group_number, int32_t peer_number,
425429

426430
if (weechat_string_has_highlight(message_nt, myname))
427431
tags = "notify_highlight";
428-
twc_chat_print_message(chat, tags, nick_color, name, message_nt,
429-
message_type);
432+
twc_chat_print_message(
433+
chat, tags, nick_color,
434+
weechat_config_boolean(twc_config_show_id) ? full_name : name,
435+
message_nt, message_type);
430436

431437
free(name);
438+
free(short_id);
439+
free(full_name);
432440
free(myname);
433441
free(message_nt);
434442
}
@@ -456,58 +464,89 @@ twc_group_peer_list_changed_callback(Tox *tox, uint32_t group_number,
456464

457465
struct t_weelist *new_nicks;
458466
struct t_weelist_item *n;
467+
struct t_weelist *new_ids;
468+
struct t_weelist_item *id;
459469

460470
npeers = tox_conference_peer_count(profile->tox, group_number, &err);
461471

462472
if (err == TOX_ERR_CONFERENCE_PEER_QUERY_OK)
463473
{
464474
new_nicks = weechat_list_new();
475+
new_ids = weechat_list_new();
465476
for (i = 0; i < npeers; i++)
466477
{
467478
char *name = twc_get_peer_name_nt(profile->tox, group_number, i);
479+
char *id = twc_get_peer_id_short(profile->tox, group_number, i);
468480
weechat_list_add(new_nicks, name, WEECHAT_LIST_POS_END, NULL);
481+
weechat_list_add(new_ids, id, WEECHAT_LIST_POS_END, NULL);
469482
free(name);
483+
free(id);
470484
}
471485
}
472486
else
473487
return;
474488

475489
/* searching for exits */
476490
n = weechat_list_get(chat->nicks, 0);
491+
id = weechat_list_get(chat->ids, 0);
477492

478-
while (n)
493+
while (id && n)
479494
{
495+
const char *short_id = weechat_list_string(id);
480496
const char *name = weechat_list_string(n);
481-
if (!weechat_list_search(new_nicks, name))
497+
if (!weechat_list_search(new_ids, short_id))
482498
{
483-
weechat_printf(chat->buffer, "%s%s just left the group chat",
484-
weechat_prefix("quit"), name);
485-
nick = weechat_nicklist_search_nick(chat->buffer,
486-
chat->nicklist_group, name);
499+
char *full_name = twc_get_peer_name_prefixed(short_id, name);
500+
nick = weechat_nicklist_search_nick(
501+
chat->buffer, chat->nicklist_group, full_name);
487502
weechat_nicklist_remove_nick(chat->buffer, nick);
503+
if (!twc_get_peer_name_count(new_nicks, name))
504+
{
505+
nick = weechat_nicklist_search_nick(chat->buffer,
506+
chat->nicklist_group, name);
507+
weechat_nicklist_remove_nick(chat->buffer, nick);
508+
}
509+
weechat_printf(
510+
chat->buffer, "%s%s just left the group chat",
511+
weechat_prefix("quit"),
512+
weechat_config_boolean(twc_config_show_id) ? full_name : name);
513+
free(full_name);
488514
}
489515
n = weechat_list_next(n);
516+
id = weechat_list_next(id);
490517
}
491518

492519
/* searching for joins */
493520
n = weechat_list_get(new_nicks, 0);
521+
id = weechat_list_get(new_ids, 0);
494522

495-
while (n)
523+
while (id && n)
496524
{
525+
const char *short_id = weechat_list_string(id);
497526
const char *name = weechat_list_string(n);
498-
if (!weechat_list_search(chat->nicks, name))
527+
if (!weechat_list_search(chat->ids, short_id))
499528
{
500-
weechat_printf(chat->buffer, "%s%s just joined the group chat",
501-
weechat_prefix("join"), name);
529+
char *full_name = twc_get_peer_name_prefixed(short_id, name);
530+
weechat_nicklist_add_nick(chat->buffer, chat->nicklist_group,
531+
full_name, NULL, NULL, NULL, 1);
502532
weechat_nicklist_add_nick(chat->buffer, chat->nicklist_group, name,
503-
NULL, NULL, NULL, 1);
533+
NULL, NULL, NULL, 0);
534+
weechat_printf(
535+
chat->buffer, "%s%s just joined the group chat",
536+
weechat_prefix("join"),
537+
weechat_config_boolean(twc_config_show_id) ? full_name : name);
538+
free(full_name);
504539
}
505540
n = weechat_list_next(n);
541+
id = weechat_list_next(id);
506542
}
507543

508544
weechat_list_remove_all(chat->nicks);
509545
weechat_list_free(chat->nicks);
546+
weechat_list_remove_all(chat->ids);
547+
weechat_list_free(chat->ids);
510548
chat->nicks = new_nicks;
549+
chat->ids = new_ids;
511550
}
512551

513552
void
@@ -523,10 +562,13 @@ twc_group_peer_name_callback(Tox *tox, uint32_t group_number,
523562
struct t_gui_nick *nick = NULL;
524563
const char *prev_name;
525564
char *name;
565+
const char *short_id;
566+
char *prev_full_name;
567+
char *full_name;
526568
bool rc;
527569
TOX_ERR_CONFERENCE_PEER_QUERY err = TOX_ERR_CONFERENCE_PEER_QUERY_OK;
528570

529-
struct t_weelist_item *n;
571+
struct t_weelist_item *n, *id;
530572

531573
npeers = tox_conference_peer_count(profile->tox, group_number, &err);
532574

@@ -550,27 +592,40 @@ twc_group_peer_name_callback(Tox *tox, uint32_t group_number,
550592
twc_group_peer_list_changed_callback(tox, group_number, data);
551593
return;
552594
}
553-
595+
id = weechat_list_get(chat->ids, peer_number);
596+
short_id = weechat_list_string(id);
554597
prev_name = weechat_list_string(n);
598+
prev_full_name = twc_get_peer_name_prefixed(short_id, prev_name);
599+
555600
name = twc_null_terminate(pname, pname_len);
601+
full_name = twc_get_peer_name_prefixed(short_id, name);
556602

557603
nick = weechat_nicklist_search_nick(chat->buffer, chat->nicklist_group,
558-
prev_name);
559-
604+
prev_full_name);
560605
weechat_nicklist_remove_nick(chat->buffer, nick);
606+
if (!twc_get_peer_name_count(chat->nicks, prev_name))
607+
{
608+
nick = weechat_nicklist_search_nick(chat->buffer, chat->nicklist_group,
609+
prev_name);
610+
weechat_nicklist_remove_nick(chat->buffer, nick);
611+
}
561612

562613
err = TOX_ERR_CONFERENCE_PEER_QUERY_OK;
563614
rc = tox_conference_peer_number_is_ours(tox, group_number, peer_number,
564615
&err);
616+
bool show_id = weechat_config_boolean(twc_config_show_id);
565617
if ((err == TOX_ERR_CONFERENCE_PEER_QUERY_OK) && (!rc))
566-
weechat_printf(chat->buffer, "%s%s is now known as %s",
567-
weechat_prefix("network"), prev_name, name);
568-
618+
weechat_printf(
619+
chat->buffer, "%s%s is now known as %s", weechat_prefix("network"),
620+
show_id ? prev_full_name : prev_name, show_id ? full_name : name);
569621
weechat_list_set(n, name);
570-
622+
weechat_nicklist_add_nick(chat->buffer, chat->nicklist_group, full_name,
623+
NULL, NULL, NULL, 1);
571624
weechat_nicklist_add_nick(chat->buffer, chat->nicklist_group, name, NULL,
572-
NULL, NULL, 1);
625+
NULL, NULL, 0);
573626

627+
free(prev_full_name);
628+
free(full_name);
574629
free(name);
575630
}
576631

0 commit comments

Comments
 (0)