Skip to content

feature: nickname disambiguation #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/twc-chat.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ twc_chat_new(struct t_twc_profile *profile, const char *name)
chat->profile = profile;
chat->friend_number = chat->group_number = -1;
chat->nicks = NULL;
chat->ids = NULL;
chat->completion = NULL;
chat->last_search = NULL;
chat->prev_comp = NULL;

size_t full_name_size = strlen(profile->name) + 1 + strlen(name) + 1;
char *full_name = malloc(full_name_size);
Expand Down Expand Up @@ -137,6 +141,8 @@ twc_chat_new_group(struct t_twc_profile *profile, int32_t group_number)
chat->nicklist_group =
weechat_nicklist_add_group(chat->buffer, NULL, NULL, NULL, true);
chat->nicks = weechat_list_new();
chat->ids = weechat_list_new();
chat->completion = weechat_list_new();

weechat_buffer_set(chat->buffer, "nicklist", "1");
}
Expand Down Expand Up @@ -395,6 +401,18 @@ twc_chat_free(struct t_twc_chat *chat)
weechat_list_remove_all(chat->nicks);
weechat_list_free(chat->nicks);
}
if (chat->ids)
{
weechat_list_remove_all(chat->ids);
weechat_list_free(chat->ids);
}
if (chat->completion)
{
weechat_list_remove_all(chat->completion);
weechat_list_free(chat->completion);
}
free(chat->last_search);
free(chat->prev_comp);
free(chat);
}

Expand Down
4 changes: 4 additions & 0 deletions src/twc-chat.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ struct t_twc_chat

struct t_gui_nick_group *nicklist_group;
struct t_weelist *nicks;
struct t_weelist *ids;
struct t_weelist *completion;
char *last_search;
char *prev_comp;
};

struct t_twc_chat *
Expand Down
55 changes: 55 additions & 0 deletions src/twc-commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -1330,6 +1330,58 @@ twc_cmd_send(const void *pointer, void *data, struct t_gui_buffer *buffer,
return WEECHAT_RC_OK;
}

/**
* Custom completion for nicknames in groups.
*/
int
twc_input_complete(const void *pointer, void *data, struct t_gui_buffer *buffer,
const char *command)
{
struct t_twc_chat *chat = twc_chat_search_buffer(buffer);
if (chat && chat->group_number >= 0)
{
const char *input = weechat_buffer_get_string(buffer, "input");
if (!strcmp(input, ""))
return WEECHAT_RC_OK;
size_t last_search_len =
chat->last_search ? strlen(chat->last_search) : 0;
int cmp = strncmp(chat->last_search, input, last_search_len);
if (cmp || !last_search_len)
{
free(chat->last_search);
chat->last_search = strdup(input);
free(chat->prev_comp);
chat->prev_comp = NULL;
twc_starts_with(chat->nicks, chat->last_search, chat->completion);
}

const char *comp =
twc_get_next_completion(chat->completion, chat->prev_comp);
if (!comp)
return WEECHAT_RC_OK;

weechat_buffer_set(buffer, "completion_freeze", "1");

char *terminator = ": "; /* Probably put it in a config */
char temp[strlen(comp) + strlen(terminator) + 1];
sprintf(temp, "%s%s", comp, terminator);
weechat_buffer_set(buffer, "input", temp);

int input_pos = weechat_buffer_get_integer(buffer, "input_length");
int input_pos_str_size = snprintf(NULL, 0, "%d", input_pos);
char input_pos_str[input_pos_str_size + 1];
snprintf(input_pos_str, input_pos_str_size + 1, "%d", input_pos);
weechat_buffer_set(buffer, "input_pos", input_pos_str);

weechat_buffer_set(buffer, "completion_freeze", "0");

free(chat->prev_comp);
chat->prev_comp = strdup(comp);
return WEECHAT_RC_OK_EAT;
}
return WEECHAT_RC_OK;
}

/**
* Register Tox-WeeChat commands.
*/
Expand Down Expand Up @@ -1421,6 +1473,9 @@ twc_commands_init()

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

weechat_hook_command_run("/input complete_next", twc_input_complete, NULL,
NULL);

weechat_hook_command("status", "change your Tox status", "online|busy|away",
"", NULL, twc_cmd_status, NULL, NULL);

Expand Down
6 changes: 6 additions & 0 deletions src/twc-config.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct t_config_section *twc_config_section_profile_default = NULL;

struct t_config_option *twc_config_friend_request_message;
struct t_config_option *twc_config_short_id_size;
struct t_config_option *twc_config_show_id;

char *twc_profile_option_names[TWC_PROFILE_NUM_OPTIONS] = {
"save_file",
Expand Down Expand Up @@ -374,6 +375,11 @@ twc_config_init()
NULL, 2, TOX_PUBLIC_KEY_SIZE * 2, "8", NULL, 0,
twc_config_check_value_callback, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
twc_config_show_id = weechat_config_new_option(
twc_config_file, twc_config_section_look, "show_id", "boolean",
"show short Tox IDs in message logs and presence logs of group chats",
NULL, 0, 0, "on", NULL, 0, twc_config_check_value_callback, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL);
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/twc-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct t_twc_profile;

extern struct t_config_option *twc_config_friend_request_message;
extern struct t_config_option *twc_config_short_id_size;
extern struct t_config_option *twc_config_show_id;

enum t_twc_proxy
{
Expand Down
106 changes: 80 additions & 26 deletions src/twc-tox-callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#endif /* TOXAV_ENABLED */

#include "twc-chat.h"
#include "twc-config.h"
#include "twc-friend-request.h"
#include "twc-group-invite.h"
#include "twc-message-queue.h"
Expand Down Expand Up @@ -412,6 +413,9 @@ twc_handle_group_message(Tox *tox, int32_t group_number, int32_t peer_number,

char *myname = twc_get_self_name_nt(profile->tox);
char *name = twc_get_peer_name_nt(profile->tox, group_number, peer_number);
char *short_id =
twc_get_peer_id_short(profile->tox, group_number, peer_number);
char *full_name = twc_get_peer_name_prefixed(short_id, name);
char *tags = "notify_message";
char *message_nt = twc_null_terminate(message, length);

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

if (weechat_string_has_highlight(message_nt, myname))
tags = "notify_highlight";
twc_chat_print_message(chat, tags, nick_color, name, message_nt,
message_type);
twc_chat_print_message(
chat, tags, nick_color,
weechat_config_boolean(twc_config_show_id) ? full_name : name,
message_nt, message_type);

free(name);
free(short_id);
free(full_name);
free(myname);
free(message_nt);
}
Expand Down Expand Up @@ -456,58 +464,88 @@ twc_group_peer_list_changed_callback(Tox *tox, uint32_t group_number,

struct t_weelist *new_nicks;
struct t_weelist_item *n;
struct t_weelist *new_ids;
struct t_weelist_item *id;

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

if (err == TOX_ERR_CONFERENCE_PEER_QUERY_OK)
{
new_nicks = weechat_list_new();
new_ids = weechat_list_new();
for (i = 0; i < npeers; i++)
{
char *name = twc_get_peer_name_nt(profile->tox, group_number, i);
char *id = twc_get_peer_id_short(profile->tox, group_number, i);
weechat_list_add(new_nicks, name, WEECHAT_LIST_POS_END, NULL);
weechat_list_add(new_ids, id, WEECHAT_LIST_POS_END, NULL);
free(name);
free(id);
}
}
else
return;

bool changed = false;

/* searching for exits */
n = weechat_list_get(chat->nicks, 0);
id = weechat_list_get(chat->ids, 0);

while (n)
while (id && n)
{
const char *short_id = weechat_list_string(id);
const char *name = weechat_list_string(n);
if (!weechat_list_search(new_nicks, name))
if (!weechat_list_search(new_ids, short_id))
{
weechat_printf(chat->buffer, "%s%s just left the group chat",
weechat_prefix("quit"), name);
nick = weechat_nicklist_search_nick(chat->buffer,
chat->nicklist_group, name);
char *full_name = twc_get_peer_name_prefixed(short_id, name);
nick = weechat_nicklist_search_nick(
chat->buffer, chat->nicklist_group, full_name);
weechat_nicklist_remove_nick(chat->buffer, nick);
weechat_printf(
chat->buffer, "%s%s just left the group chat",
weechat_prefix("quit"),
weechat_config_boolean(twc_config_show_id) ? full_name : name);
changed = true;
free(full_name);
}
n = weechat_list_next(n);
id = weechat_list_next(id);
}

/* searching for joins */
n = weechat_list_get(new_nicks, 0);
id = weechat_list_get(new_ids, 0);

while (n)
while (id && n)
{
const char *short_id = weechat_list_string(id);
const char *name = weechat_list_string(n);
if (!weechat_list_search(chat->nicks, name))
if (!weechat_list_search(chat->ids, short_id))
{
weechat_printf(chat->buffer, "%s%s just joined the group chat",
weechat_prefix("join"), name);
weechat_nicklist_add_nick(chat->buffer, chat->nicklist_group, name,
NULL, NULL, NULL, 1);
char *full_name = twc_get_peer_name_prefixed(short_id, name);
weechat_nicklist_add_nick(chat->buffer, chat->nicklist_group,
full_name, NULL, NULL, NULL, 1);
weechat_printf(
chat->buffer, "%s%s just joined the group chat",
weechat_prefix("join"),
weechat_config_boolean(twc_config_show_id) ? full_name : name);
changed = true;
free(full_name);
}
n = weechat_list_next(n);
id = weechat_list_next(id);
}

weechat_list_remove_all(chat->nicks);
weechat_list_free(chat->nicks);
chat->nicks = new_nicks;
if (changed)
{
weechat_list_remove_all(chat->nicks);
weechat_list_free(chat->nicks);
weechat_list_remove_all(chat->ids);
weechat_list_free(chat->ids);
chat->nicks = new_nicks;
chat->ids = new_ids;
}
}

void
Expand All @@ -523,10 +561,13 @@ twc_group_peer_name_callback(Tox *tox, uint32_t group_number,
struct t_gui_nick *nick = NULL;
const char *prev_name;
char *name;
const char *short_id;
char *prev_full_name;
char *full_name;
bool rc;
TOX_ERR_CONFERENCE_PEER_QUERY err = TOX_ERR_CONFERENCE_PEER_QUERY_OK;

struct t_weelist_item *n;
struct t_weelist_item *n, *id;

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

Expand All @@ -550,27 +591,40 @@ twc_group_peer_name_callback(Tox *tox, uint32_t group_number,
twc_group_peer_list_changed_callback(tox, group_number, data);
return;
}

id = weechat_list_get(chat->ids, peer_number);
short_id = weechat_list_string(id);
prev_name = weechat_list_string(n);
prev_full_name = twc_get_peer_name_prefixed(short_id, prev_name);

name = twc_null_terminate(pname, pname_len);
full_name = twc_get_peer_name_prefixed(short_id, name);

nick = weechat_nicklist_search_nick(chat->buffer, chat->nicklist_group,
prev_name);

prev_full_name);
weechat_nicklist_remove_nick(chat->buffer, nick);
if (!twc_get_peer_name_count(chat->nicks, prev_name))
{
nick = weechat_nicklist_search_nick(chat->buffer, chat->nicklist_group,
prev_name);
weechat_nicklist_remove_nick(chat->buffer, nick);
}

err = TOX_ERR_CONFERENCE_PEER_QUERY_OK;
rc = tox_conference_peer_number_is_ours(tox, group_number, peer_number,
&err);
bool show_id = weechat_config_boolean(twc_config_show_id);
if ((err == TOX_ERR_CONFERENCE_PEER_QUERY_OK) && (!rc))
weechat_printf(chat->buffer, "%s%s is now known as %s",
weechat_prefix("network"), prev_name, name);

weechat_printf(
chat->buffer, "%s%s is now known as %s", weechat_prefix("network"),
show_id ? prev_full_name : prev_name, show_id ? full_name : name);
weechat_list_set(n, name);

weechat_nicklist_add_nick(chat->buffer, chat->nicklist_group, full_name,
NULL, NULL, NULL, 1);
weechat_nicklist_add_nick(chat->buffer, chat->nicklist_group, name, NULL,
NULL, NULL, 1);
NULL, NULL, 0);

free(prev_full_name);
free(full_name);
free(name);
}

Expand Down
Loading