1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-29 14:26:39 +02:00

Improved nick completion: completes with last speakers first (task #5896), fixed nick completion (bugs #19590 and #19589)

This commit is contained in:
Sebastien Helleu
2007-04-14 13:14:05 +00:00
parent a89ca83306
commit f30fb21175
38 changed files with 8304 additions and 7766 deletions
+6 -1
View File
@@ -1,10 +1,15 @@
WeeChat - Wee Enhanced Environment for Chat
===========================================
ChangeLog - 2007-04-04
ChangeLog - 2007-04-14
Version 0.2.5 (under dev!):
* improved nick completion: added option look_nick_completion_smart,
enabled by default (task #5896)
* fixed nick completion in command arguments (bug #19590)
* fixed possible crash with nick completion when a nick leaves channel
(bug #19589)
* added color for input text not found in buffer history
* fixed USER message when connecting to IRC server (patch #5835)
+542 -533
View File
File diff suppressed because it is too large Load Diff
+542 -533
View File
File diff suppressed because it is too large Load Diff
+542 -533
View File
File diff suppressed because it is too large Load Diff
+544 -534
View File
File diff suppressed because it is too large Load Diff
+542 -533
View File
File diff suppressed because it is too large Load Diff
+542 -533
View File
File diff suppressed because it is too large Load Diff
+541 -533
View File
File diff suppressed because it is too large Load Diff
+6 -3
View File
@@ -251,7 +251,8 @@ command_index_build ()
while (weechat_commands[i].command_name)
{
(void) weelist_add (&index_commands, &last_index_command,
weechat_commands[i].command_name);
weechat_commands[i].command_name,
WEELIST_POS_SORT);
i++;
}
i = 0;
@@ -259,7 +260,8 @@ command_index_build ()
{
if (irc_commands[i].cmd_function_args || irc_commands[i].cmd_function_1arg)
(void) weelist_add (&index_commands, &last_index_command,
irc_commands[i].command_name);
irc_commands[i].command_name,
WEELIST_POS_SORT);
i++;
}
}
@@ -945,7 +947,8 @@ weechat_cmd_alias (t_irc_server *server, t_irc_channel *channel,
}
if (!alias_new (arguments, pos))
return -1;
if (weelist_add (&index_commands, &last_index_command, arguments))
if (weelist_add (&index_commands, &last_index_command, arguments,
WEELIST_POS_SORT))
{
irc_display_prefix (NULL, NULL, PREFIX_INFO);
gui_printf (NULL, _("Alias \"%s\" => \"%s\" created\n"),
+212 -135
View File
@@ -95,12 +95,14 @@ completion_free (t_completion *completion)
free (completion->args);
completion->args = NULL;
while (completion->completion_list)
weelist_remove (&completion->completion_list,
&completion->last_completion,
completion->completion_list);
weelist_remove_all (&completion->completion_list,
&completion->last_completion);
completion->completion_list = NULL;
completion->last_completion = NULL;
if (completion->word_found)
free (completion->word_found);
completion->word_found = NULL;
}
/*
@@ -203,20 +205,95 @@ completion_get_command_infos (t_completion *completion,
return;
}
/*
* completion_is_only_alphanum: return 1 if there is only alpha/num chars
* in a string
*/
int
completion_is_only_alphanum (char *string)
{
while (string[0])
{
if (strchr (cfg_look_nick_completion_ignore, string[0]))
return 0;
string++;
}
return 1;
}
/*
* completion_strdup_alphanum: duplicate alpha/num chars in a string
*/
char *
completion_strdup_alphanum (char *string)
{
char *result, *pos;
result = (char *)malloc (strlen (string) + 1);
pos = result;
while (string[0])
{
if (!strchr (cfg_look_nick_completion_ignore, string[0]))
{
pos[0] = string[0];
pos++;
}
string++;
}
pos[0] = '\0';
return result;
}
/*
* completion_nickncmp: locale and case independent string comparison
* with max length for nicks (alpha or digits only)
*/
int
completion_nickncmp (char *base_word, char *nick, int max)
{
char *base_word2, *nick2;
int return_cmp;
if (!cfg_look_nick_completion_ignore
|| !cfg_look_nick_completion_ignore[0]
|| !base_word || !nick || !base_word[0] || !nick[0]
|| (!completion_is_only_alphanum (base_word)))
return ascii_strncasecmp (base_word, nick, max);
base_word2 = completion_strdup_alphanum (base_word);
nick2 = completion_strdup_alphanum (nick);
return_cmp = ascii_strncasecmp (base_word2, nick2, strlen (base_word2));
free (base_word2);
free (nick2);
return return_cmp;
}
/*
* completion_list_add: add a word to completion word list
* if nick_completion != 0, then add as a nick
* if nick_completion < 0, then add at beginning of list
*/
void
completion_list_add (t_completion *completion, char *word)
completion_list_add (t_completion *completion, char *word, int nick_completion)
{
if (!completion->base_word || !completion->base_word[0]
|| (ascii_strncasecmp (completion->base_word, word,
strlen (completion->base_word)) == 0))
|| ((nick_completion != 0) && (completion_nickncmp (completion->base_word, word,
strlen (completion->base_word)) == 0))
|| ((nick_completion == 0) && (ascii_strncasecmp (completion->base_word, word,
strlen (completion->base_word)) == 0)))
{
weelist_add (&completion->completion_list,
&completion->last_completion,
word);
word,
(nick_completion < 0) ?
WEELIST_POS_BEGINNING : WEELIST_POS_SORT);
}
}
@@ -231,7 +308,7 @@ completion_list_add_alias (t_completion *completion)
for (ptr_alias = weechat_alias; ptr_alias; ptr_alias = ptr_alias->next_alias)
{
completion_list_add (completion, ptr_alias->alias_name);
completion_list_add (completion, ptr_alias->alias_name, 0);
}
}
@@ -246,7 +323,7 @@ completion_list_add_alias_cmd (t_completion *completion)
for (ptr_list = index_commands; ptr_list; ptr_list = ptr_list->next_weelist)
{
completion_list_add (completion, ptr_list->data);
completion_list_add (completion, ptr_list->data, 0);
}
}
@@ -259,7 +336,7 @@ completion_list_add_channel (t_completion *completion)
{
if (completion->channel)
completion_list_add (completion,
((t_irc_channel *)(completion->channel))->name);
((t_irc_channel *)(completion->channel))->name, 0);
}
/*
@@ -276,7 +353,7 @@ completion_list_add_server_channels (t_completion *completion)
for (ptr_channel = ((t_irc_server *)(completion->server))->channels;
ptr_channel; ptr_channel = ptr_channel->next_channel)
{
completion_list_add (completion, ptr_channel->name);
completion_list_add (completion, ptr_channel->name, 0);
}
}
}
@@ -361,7 +438,7 @@ completion_list_add_filename (t_completion *completion)
entry->d_name,
S_ISDIR(statbuf.st_mode) ? DIR_SEPARATOR : "");
completion_list_add (completion, buffer);
completion_list_add (completion, buffer, 0);
}
}
}
@@ -392,7 +469,7 @@ completion_list_add_plugin_cmd (t_completion *completion)
ptr_handler; ptr_handler = ptr_handler->next_handler)
{
if (ptr_handler->type == PLUGIN_HANDLER_COMMAND)
completion_list_add (completion, ptr_handler->command);
completion_list_add (completion, ptr_handler->command, 0);
}
}
#else
@@ -413,7 +490,7 @@ completion_list_add_irc_cmd_sent (t_completion *completion)
for (i = 0; irc_commands[i].command_name; i++)
{
if (irc_commands[i].cmd_function_args || irc_commands[i].cmd_function_1arg)
completion_list_add (completion, irc_commands[i].command_name);
completion_list_add (completion, irc_commands[i].command_name, 0);
}
}
@@ -429,7 +506,7 @@ completion_list_add_irc_cmd_recv (t_completion *completion)
for (i = 0; irc_commands[i].command_name; i++)
{
if (irc_commands[i].recv_function)
completion_list_add(completion, irc_commands[i].command_name);
completion_list_add(completion, irc_commands[i].command_name, 0);
}
}
@@ -444,7 +521,7 @@ completion_list_add_key_cmd (t_completion *completion)
for (i = 0; gui_key_functions[i].function_name; i++)
{
completion_list_add (completion, gui_key_functions[i].function_name);
completion_list_add (completion, gui_key_functions[i].function_name, 0);
}
}
@@ -457,7 +534,8 @@ completion_list_add_self_nick (t_completion *completion)
{
if (completion->server)
{
completion_list_add (completion, ((t_irc_server *)(completion->server))->nick);
completion_list_add (completion,
((t_irc_server *)(completion->server))->nick, 0);
}
}
@@ -469,22 +547,34 @@ void
completion_list_add_channel_nicks (t_completion *completion)
{
t_irc_nick *ptr_nick;
t_weelist *ptr_weelist;
if (completion->channel)
{
if (((t_irc_channel *)(completion->channel))->type == CHANNEL_TYPE_CHANNEL)
{
/* add channel nicks */
for (ptr_nick = ((t_irc_channel *)(completion->channel))->nicks;
ptr_nick; ptr_nick = ptr_nick->next_nick)
{
completion_list_add (completion, ptr_nick->nick);
completion_list_add (completion, ptr_nick->nick, 1);
}
/* add nicks speaking recently on this channel */
if (cfg_look_nick_completion_smart)
{
for (ptr_weelist = ((t_irc_channel *)(completion->channel))->nicks_speaking;
ptr_weelist; ptr_weelist = ptr_weelist->next_weelist)
{
if (nick_search ((t_irc_channel *)(completion->channel), ptr_weelist->data))
completion_list_add (completion, ptr_weelist->data, -1);
}
}
}
if ((((t_irc_channel *)(completion->channel))->type == CHANNEL_TYPE_PRIVATE)
|| (((t_irc_channel *)(completion->channel))->type == CHANNEL_TYPE_DCC_CHAT))
{
completion_list_add (completion,
((t_irc_channel *)(completion->channel))->name);
((t_irc_channel *)(completion->channel))->name, 1);
}
completion->arg_is_nick = 1;
}
@@ -508,7 +598,7 @@ completion_list_add_channel_nicks_hosts (t_completion *completion)
for (ptr_nick = ((t_irc_channel *)(completion->channel))->nicks;
ptr_nick; ptr_nick = ptr_nick->next_nick)
{
completion_list_add (completion, ptr_nick->nick);
completion_list_add (completion, ptr_nick->nick, 1);
if (ptr_nick->host)
{
length = strlen (ptr_nick->nick) + 1 +
@@ -518,7 +608,7 @@ completion_list_add_channel_nicks_hosts (t_completion *completion)
{
snprintf (buf, length, "%s!%s",
ptr_nick->nick, ptr_nick->host);
completion_list_add (completion, buf);
completion_list_add (completion, buf, 1);
free (buf);
}
}
@@ -528,7 +618,7 @@ completion_list_add_channel_nicks_hosts (t_completion *completion)
|| (((t_irc_channel *)(completion->channel))->type == CHANNEL_TYPE_PRIVATE))
{
completion_list_add (completion,
((t_irc_channel *)(completion->channel))->name);
((t_irc_channel *)(completion->channel))->name, 1);
}
completion->arg_is_nick = 1;
}
@@ -553,7 +643,7 @@ completion_list_add_option (t_completion *completion)
for (j = 0; weechat_options[i][j].option_name; j++)
{
completion_list_add (completion,
weechat_options[i][j].option_name);
weechat_options[i][j].option_name, 0);
}
}
}
@@ -565,7 +655,7 @@ completion_list_add_option (t_completion *completion)
snprintf (option_name, sizeof (option_name), "%s.%s",
ptr_server->name,
weechat_options[CONFIG_SECTION_SERVER][i].option_name);
completion_list_add (completion, option_name);
completion_list_add (completion, option_name, 0);
}
}
}
@@ -583,7 +673,7 @@ completion_list_add_plugin_option (t_completion *completion)
for (ptr_option = plugin_options; ptr_option;
ptr_option = ptr_option->next_option)
{
completion_list_add (completion, ptr_option->name);
completion_list_add (completion, ptr_option->name, 0);
}
#else
/* make C compiler happy */
@@ -599,7 +689,7 @@ void
completion_list_add_part (t_completion *completion)
{
if (cfg_irc_default_msg_part && cfg_irc_default_msg_part[0])
completion_list_add (completion, cfg_irc_default_msg_part);
completion_list_add (completion, cfg_irc_default_msg_part, 0);
}
/*
@@ -615,7 +705,7 @@ completion_list_add_plugin (t_completion *completion)
for (ptr_plugin = weechat_plugins; ptr_plugin;
ptr_plugin = ptr_plugin->next_plugin)
{
completion_list_add (completion, ptr_plugin->name);
completion_list_add (completion, ptr_plugin->name, 0);
}
#else
/* make C compiler happy */
@@ -631,7 +721,7 @@ void
completion_list_add_quit (t_completion *completion)
{
if (cfg_irc_default_msg_quit && cfg_irc_default_msg_quit[0])
completion_list_add (completion, cfg_irc_default_msg_quit);
completion_list_add (completion, cfg_irc_default_msg_quit, 0);
}
/*
@@ -643,7 +733,7 @@ completion_list_add_server (t_completion *completion)
{
if (completion->server)
completion_list_add (completion,
((t_irc_server *)(completion->server))->name);
((t_irc_server *)(completion->server))->name, 0);
}
/*
@@ -658,7 +748,7 @@ completion_list_add_servers (t_completion *completion)
for (ptr_server = irc_servers; ptr_server;
ptr_server = ptr_server->next_server)
{
completion_list_add (completion, ptr_server->name);
completion_list_add (completion, ptr_server->name, 0);
}
}
@@ -681,7 +771,7 @@ completion_list_add_topic (t_completion *completion)
string = (char *)gui_color_decode ((unsigned char *)((t_irc_channel *)(completion->channel))->topic, 0);
completion_list_add (completion,
(string) ?
string : ((t_irc_channel *)(completion->channel))->topic);
string : ((t_irc_channel *)(completion->channel))->topic, 0);
if (string)
free (string);
}
@@ -713,26 +803,26 @@ completion_list_add_option_value (t_completion *completion)
{
case OPTION_TYPE_BOOLEAN:
if (option_value && (*((int *)(option_value))))
completion_list_add (completion, "on");
completion_list_add (completion, "on", 0);
else
completion_list_add (completion, "off");
completion_list_add (completion, "off", 0);
break;
case OPTION_TYPE_INT:
snprintf (option_string, sizeof (option_string) - 1,
"%d", (option_value) ? *((int *)(option_value)) : option->default_int);
completion_list_add (completion, option_string);
completion_list_add (completion, option_string, 0);
break;
case OPTION_TYPE_INT_WITH_STRING:
completion_list_add (completion,
(option_value) ?
option->array_values[*((int *)(option_value))] :
option->array_values[option->default_int]);
option->array_values[option->default_int], 0);
break;
case OPTION_TYPE_COLOR:
completion_list_add (completion,
(option_value) ?
gui_color_get_name (*((int *)(option_value))) :
option->default_string);
option->default_string, 0);
break;
case OPTION_TYPE_STRING:
snprintf (option_string, sizeof (option_string) - 1,
@@ -740,7 +830,7 @@ completion_list_add_option_value (t_completion *completion)
((option_value) && (*((char **)(option_value)))) ?
*((char **)(option_value)) :
option->default_string);
completion_list_add (completion, option_string);
completion_list_add (completion, option_string, 0);
break;
}
}
@@ -768,7 +858,7 @@ completion_list_add_plugin_option_value (t_completion *completion)
ptr_option = plugin_config_search_internal (completion->args);
if (ptr_option)
completion_list_add (completion, ptr_option->value);
completion_list_add (completion, ptr_option->value, 0);
if (pos)
pos[0] = ' ';
@@ -790,7 +880,7 @@ completion_list_add_weechat_cmd (t_completion *completion)
for (i = 0; weechat_commands[i].command_name; i++)
{
completion_list_add (completion, weechat_commands[i].command_name);
completion_list_add (completion, weechat_commands[i].command_name, 0);
}
}
@@ -819,7 +909,8 @@ completion_build_list_template (t_completion *completion, char *template)
word[word_offset] = '\0';
weelist_add (&completion->completion_list,
&completion->last_completion,
word);
word,
WEELIST_POS_SORT);
}
word_offset = 0;
break;
@@ -1105,7 +1196,9 @@ completion_command (t_completion *completion)
{
if ((!completion->word_found) || word_found_seen)
{
completion->word_found = ptr_weelist->data;
if (completion->word_found)
free (completion->word_found);
completion->word_found = strdup (ptr_weelist->data);
if (completion->direction < 0)
ptr_weelist2 = ptr_weelist->prev_weelist;
@@ -1144,80 +1237,12 @@ completion_command (t_completion *completion)
}
if (completion->word_found)
{
free (completion->word_found);
completion->word_found = NULL;
completion_command (completion);
}
}
/*
* completion_is_only_alphanum: return 1 if there is only alpha/num chars
* in a string
*/
int
completion_is_only_alphanum (char *string)
{
while (string[0])
{
if (strchr (cfg_look_nick_completion_ignore, string[0]))
return 0;
string++;
}
return 1;
}
/*
* completion_strdup_alphanum: duplicate alpha/num chars in a string
*/
char *
completion_strdup_alphanum (char *string)
{
char *result, *pos;
result = (char *)malloc (strlen (string) + 1);
pos = result;
while (string[0])
{
if (!strchr (cfg_look_nick_completion_ignore, string[0]))
{
pos[0] = string[0];
pos++;
}
string++;
}
pos[0] = '\0';
return result;
}
/*
* completion_nickncmp: locale and case independent string comparison
* with max length for nicks (alpha or digits only)
*/
int
completion_nickncmp (char *base_word, char *nick, int max)
{
char *base_word2, *nick2;
int return_cmp;
if (!cfg_look_nick_completion_ignore
|| !cfg_look_nick_completion_ignore[0]
|| !base_word || !nick || !base_word[0] || !nick[0]
|| (!completion_is_only_alphanum (base_word)))
return ascii_strncasecmp (base_word, nick, max);
base_word2 = completion_strdup_alphanum (base_word);
nick2 = completion_strdup_alphanum (nick);
return_cmp = ascii_strncasecmp (base_word2, nick2, strlen (base_word2));
free (base_word2);
free (nick2);
return return_cmp;
}
/*
* completion_command_arg: complete a command argument
*/
@@ -1243,7 +1268,9 @@ completion_command_arg (t_completion *completion, int nick_completion)
{
if ((!completion->word_found) || word_found_seen)
{
completion->word_found = ptr_weelist->data;
if (completion->word_found)
free (completion->word_found);
completion->word_found = strdup (ptr_weelist->data);
if (completion->direction < 0)
ptr_weelist2 = ptr_weelist->prev_weelist;
@@ -1284,6 +1311,7 @@ completion_command_arg (t_completion *completion, int nick_completion)
}
if (completion->word_found)
{
free (completion->word_found);
completion->word_found = NULL;
completion_command_arg (completion, nick_completion);
}
@@ -1297,7 +1325,8 @@ void
completion_nick (t_completion *completion)
{
int length, word_found_seen, other_completion;
t_irc_nick *ptr_nick, *ptr_nick2;
t_irc_nick *ptr_nick;
t_weelist *ptr_weelist, *ptr_weelist2;
if (!completion->channel)
return;
@@ -1311,31 +1340,73 @@ completion_nick (t_completion *completion)
{
weelist_add (&completion->completion_list,
&completion->last_completion,
((t_irc_channel *)(completion->channel))->name);
((t_irc_channel *)(completion->channel))->name,
WEELIST_POS_SORT);
weelist_add (&completion->completion_list,
&completion->last_completion,
((t_irc_server *)(completion->server))->nick);
((t_irc_server *)(completion->server))->nick,
WEELIST_POS_SORT);
}
completion_command_arg (completion, 1);
return;
}
/* rebuild nick list for completion, with nicks speaking at beginning of list */
if ((((t_irc_channel *)(completion->channel))->nick_completion_reset)
|| (!(completion->completion_list)))
{
/* empty completion list */
if (completion->completion_list)
{
weelist_remove_all (&(completion->completion_list),
&(completion->last_completion));
completion->completion_list = NULL;
completion->last_completion = NULL;
}
/* add channel nicks */
for (ptr_nick = ((t_irc_channel *)(completion->channel))->nicks;
ptr_nick; ptr_nick = ptr_nick->next_nick)
{
weelist_add (&(completion->completion_list),
&(completion->last_completion),
ptr_nick->nick,
WEELIST_POS_SORT);
}
/* add nicks speaking recently on this channel */
if (cfg_look_nick_completion_smart)
{
for (ptr_weelist = ((t_irc_channel *)(completion->channel))->nicks_speaking;
ptr_weelist; ptr_weelist = ptr_weelist->next_weelist)
{
if (nick_search ((t_irc_channel *)(completion->channel), ptr_weelist->data))
weelist_add (&(completion->completion_list),
&(completion->last_completion),
ptr_weelist->data,
WEELIST_POS_BEGINNING);
}
}
((t_irc_channel *)(completion->channel))->nick_completion_reset = 0;
}
length = strlen (completion->base_word);
word_found_seen = 0;
other_completion = 0;
if (completion->direction < 0)
ptr_nick = ((t_irc_channel *)(completion->channel))->last_nick;
else
ptr_nick = ((t_irc_channel *)(completion->channel))->nicks;
while (ptr_nick)
if (completion->direction < 0)
ptr_weelist = completion->last_completion;
else
ptr_weelist = completion->completion_list;
while (ptr_weelist)
{
if (completion_nickncmp (completion->base_word, ptr_nick->nick, length) == 0)
if (completion_nickncmp (completion->base_word, ptr_weelist->data, length) == 0)
{
if ((!completion->word_found) || word_found_seen)
{
completion->word_found = ptr_nick->nick;
if (completion->word_found)
free (completion->word_found);
completion->word_found = strdup (ptr_weelist->data);
if (cfg_look_nick_complete_first)
{
completion->position = -1;
@@ -1343,21 +1414,21 @@ completion_nick (t_completion *completion)
}
if (completion->direction < 0)
ptr_nick2 = ptr_nick->prev_nick;
ptr_weelist2 = ptr_weelist->prev_weelist;
else
ptr_nick2 = ptr_nick->next_nick;
ptr_weelist2 = ptr_weelist->next_weelist;
while (ptr_nick2)
while (ptr_weelist2)
{
if (completion_nickncmp (completion->base_word,
ptr_nick2->nick,
ptr_weelist2->data,
length) == 0)
other_completion++;
if (completion->direction < 0)
ptr_nick2 = ptr_nick2->prev_nick;
ptr_weelist2 = ptr_weelist2->prev_weelist;
else
ptr_nick2 = ptr_nick2->next_nick;
ptr_weelist2 = ptr_weelist2->next_weelist;
}
if (other_completion == 0)
@@ -1372,16 +1443,17 @@ completion_nick (t_completion *completion)
other_completion++;
}
if (completion->word_found &&
(ascii_strcasecmp (ptr_nick->nick, completion->word_found) == 0))
(ascii_strcasecmp (ptr_weelist->data, completion->word_found) == 0))
word_found_seen = 1;
if (completion->direction < 0)
ptr_nick = ptr_nick->prev_nick;
ptr_weelist = ptr_weelist->prev_weelist;
else
ptr_nick = ptr_nick->next_nick;
ptr_weelist = ptr_weelist->next_weelist;
}
if (completion->word_found)
{
free (completion->word_found);
completion->word_found = NULL;
completion_nick (completion);
}
@@ -1435,12 +1507,15 @@ completion_search (t_completion *completion, int direction,
/* if new completion => look for base word */
if (pos != completion->position)
{
if (completion->word_found)
free (completion->word_found);
completion->word_found = NULL;
completion_find_context (completion, buffer, size, pos);
}
/* completion */
old_word_found = completion->word_found;
old_word_found = (completion->word_found) ?
strdup (completion->word_found) : NULL;
switch (completion->context)
{
case COMPLETION_NULL:
@@ -1487,6 +1562,8 @@ completion_search (t_completion *completion, int direction,
}
}
}
if (old_word_found)
free (old_word_found);
}
/*
+7 -1
View File
@@ -97,6 +97,7 @@ int cfg_look_align_size;
int cfg_look_align_size_max;
char *cfg_look_nick_completor;
char *cfg_look_nick_completion_ignore;
int cfg_look_nick_completion_smart;
int cfg_look_nick_complete_first;
int cfg_look_infobar;
char *cfg_look_infobar_timestamp;
@@ -222,6 +223,10 @@ t_config_option weechat_options_look[] =
N_("chars ignored for nick completion"),
OPTION_TYPE_STRING, 0, 0, 0,
"[]-^", NULL, NULL, &cfg_look_nick_completion_ignore, config_change_noop },
{ "look_nick_completion_smart", N_("smart completion for nicks"),
N_("smart completion for nicks (completes with last speakers first)"),
OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE,
NULL, NULL, &cfg_look_nick_completion_smart, NULL, config_change_noop },
{ "look_nick_complete_first", N_("complete only with first nick found"),
N_("complete only with first nick found"),
OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_FALSE,
@@ -2024,7 +2029,8 @@ config_read ()
{
/* create new alias */
if (alias_new (line, pos))
weelist_add (&index_commands, &last_index_command, line);
weelist_add (&index_commands, &last_index_command,
line, WEELIST_POS_SORT);
}
else if (section == CONFIG_SECTION_IGNORE)
{
+1
View File
@@ -114,6 +114,7 @@ extern int cfg_look_align_size;
extern int cfg_look_align_size_max;
extern char *cfg_look_nick_completor;
extern char *cfg_look_nick_completion_ignore;
extern int cfg_look_nick_completion_smart;
extern int cfg_look_nick_complete_first;
extern int cfg_look_infobar;
extern char *cfg_look_infobar_timestamp;
+63 -7
View File
@@ -33,6 +33,26 @@
#include "util.h"
/*
* weelist_get_size: get list size (number of elements)
*/
int
weelist_get_size (t_weelist *weelist)
{
t_weelist *ptr_weelist;
int count;
count = 0;
for (ptr_weelist = weelist; ptr_weelist; ptr_weelist = ptr_weelist->next_weelist)
{
count++;
}
return count;
}
/*
* weelist_search: search date in a list
*/
@@ -74,14 +94,36 @@ weelist_find_pos (t_weelist *weelist, char *data)
*/
void
weelist_insert (t_weelist **weelist, t_weelist **last_weelist, t_weelist *element)
weelist_insert (t_weelist **weelist, t_weelist **last_weelist, t_weelist *element,
int position)
{
t_weelist *pos_weelist;
pos_weelist = weelist_find_pos (*weelist, element->data);
if (*weelist)
{
/* remove element if already in list */
pos_weelist = weelist_search (*weelist, element->data);
if (pos_weelist)
weelist_remove (weelist, last_weelist, pos_weelist);
}
if (*weelist)
{
/* search position for new element, according to pos asked */
pos_weelist = NULL;
switch (position)
{
case WEELIST_POS_SORT:
pos_weelist = weelist_find_pos (*weelist, element->data);
break;
case WEELIST_POS_BEGINNING:
pos_weelist = *weelist;
break;
case WEELIST_POS_END:
pos_weelist = NULL;
break;
}
if (pos_weelist)
{
/* insert data into the list (before position found) */
@@ -116,7 +158,8 @@ weelist_insert (t_weelist **weelist, t_weelist **last_weelist, t_weelist *elemen
*/
t_weelist *
weelist_add (t_weelist **weelist, t_weelist **last_weelist, char *data)
weelist_add (t_weelist **weelist, t_weelist **last_weelist, char *data,
int position)
{
t_weelist *new_weelist;
@@ -126,7 +169,7 @@ weelist_add (t_weelist **weelist, t_weelist **last_weelist, char *data)
if ((new_weelist = ((t_weelist *) malloc (sizeof (t_weelist)))))
{
new_weelist->data = strdup (data);
weelist_insert (weelist, last_weelist, new_weelist);
weelist_insert (weelist, last_weelist, new_weelist, position);
return new_weelist;
}
/* failed to allocate new element */
@@ -134,7 +177,7 @@ weelist_add (t_weelist **weelist, t_weelist **last_weelist, char *data)
}
/*
* weelist_remove: free an element in a list
* weelist_remove: remove an element from a list
*/
void
@@ -142,7 +185,7 @@ weelist_remove (t_weelist **weelist, t_weelist **last_weelist, t_weelist *elemen
{
t_weelist *new_weelist;
if (!element)
if (!element || !(*weelist))
return;
/* remove element from list */
@@ -166,6 +209,19 @@ weelist_remove (t_weelist **weelist, t_weelist **last_weelist, t_weelist *elemen
*weelist = new_weelist;
}
/*
* weelist_remove_all: remove all elements from a list
*/
void
weelist_remove_all (t_weelist **weelist, t_weelist **last_weelist)
{
while (*weelist)
{
weelist_remove (weelist, last_weelist, *weelist);
}
}
/*
* weelist_print_log: print weelist in log (usually for crash dump)
*/
+7 -1
View File
@@ -21,6 +21,10 @@
#ifndef __WEECHAT_LIST_H
#define __WEECHAT_LIST_H 1
#define WEELIST_POS_SORT 0
#define WEELIST_POS_BEGINNING 1
#define WEELIST_POS_END 2
typedef struct t_weelist t_weelist;
struct t_weelist
@@ -30,9 +34,11 @@ struct t_weelist
t_weelist *next_weelist;
};
extern int weelist_get_size (t_weelist *);
extern t_weelist *weelist_search (t_weelist *, char *);
extern t_weelist *weelist_add (t_weelist **, t_weelist **, char *);
extern t_weelist *weelist_add (t_weelist **, t_weelist **, char *, int);
extern void weelist_remove (t_weelist **, t_weelist **, t_weelist *);
extern void weelist_remove_all (t_weelist **, t_weelist **);
extern void weelist_print_log (t_weelist *, char *);
#endif /* weelist.h */
+39
View File
@@ -70,9 +70,12 @@ channel_new (t_irc_server *server, int channel_type, char *channel_name)
new_channel->cycle = 0;
new_channel->close = 0;
new_channel->display_creation_date = 0;
new_channel->nick_completion_reset = 0;
new_channel->nicks = NULL;
new_channel->last_nick = NULL;
new_channel->buffer = NULL;
new_channel->nicks_speaking = NULL;
new_channel->last_nick_speaking = NULL;
/* add new channel to queue */
new_channel->prev_channel = server->last_channel;
@@ -136,6 +139,9 @@ channel_free (t_irc_server *server, t_irc_channel *channel)
nick_free_all (channel);
if (channel->away_message)
free (channel->away_message);
if (channel->nicks_speaking)
weelist_remove_all (&(channel->nicks_speaking),
&(channel->last_nick_speaking));
free (channel);
server->channels = new_channels;
}
@@ -404,6 +410,31 @@ channel_set_notify_level (t_irc_server *server, t_irc_channel *channel, int noti
config_option_list_set (&(server->notify_levels), channel->name, level_string);
}
/*
* channel_add_nick_speaking: add a nick speaking on a channel
*/
void
channel_add_nick_speaking (t_irc_channel *channel, char *nick)
{
int size, to_remove, i;
weelist_add (&(channel->nicks_speaking), &(channel->last_nick_speaking),
nick, WEELIST_POS_END);
size = weelist_get_size (channel->nicks_speaking);
if (size > CHANNEL_NICKS_SPEAKING_LIMIT)
{
to_remove = size - CHANNEL_NICKS_SPEAKING_LIMIT;
for (i = 0; i < to_remove; i++)
{
weelist_remove (&(channel->nicks_speaking),
&(channel->last_nick_speaking),
channel->nicks_speaking);
}
}
}
/*
* channel_print_log: print channel infos in log (usually for crash dump)
*/
@@ -426,6 +457,14 @@ channel_print_log (t_irc_channel *channel)
weechat_log_printf (" nicks. . . . . . . . : 0x%X\n", channel->nicks);
weechat_log_printf (" last_nick. . . . . . : 0x%X\n", channel->last_nick);
weechat_log_printf (" buffer . . . . . . . : 0x%X\n", channel->buffer);
weechat_log_printf (" nicks_speaking . . . : 0x%X\n", channel->nicks_speaking);
weechat_log_printf (" last_nick_speaking . : 0x%X\n", channel->last_nick_speaking);
weechat_log_printf (" prev_channel . . . . : 0x%X\n", channel->prev_channel);
weechat_log_printf (" next_channel . . . . : 0x%X\n", channel->next_channel);
if (channel->nicks_speaking)
{
weechat_log_printf ("\n");
weelist_print_log (channel->nicks_speaking,
"channel nick speaking element");
}
}
+4
View File
@@ -232,6 +232,8 @@ nick_new (t_irc_server *server, t_irc_channel *channel, char *nick_name,
nick_insert_sorted (channel, new_nick);
channel->nicks_count++;
channel->nick_completion_reset = 1;
/* all is ok, return address of new nick */
return new_nick;
@@ -296,6 +298,8 @@ nick_free (t_irc_channel *channel, t_irc_nick *nick)
free (nick->host);
free (nick);
channel->nicks = new_nicks;
channel->nick_completion_reset = 1;
}
/*
+2
View File
@@ -1392,6 +1392,7 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *nick, char *argume
gui_printf (ptr_channel->buffer, " %s%s\n",
GUI_COLOR(COLOR_WIN_CHAT), pos);
}
channel_add_nick_speaking (ptr_channel, nick);
}
return 0;
}
@@ -1520,6 +1521,7 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *nick, char *argume
gui_printf_type (ptr_channel->buffer, MSG_TYPE_MSG,
"%s\n", pos);
}
channel_add_nick_speaking (ptr_channel, nick);
}
}
else
+8 -2
View File
@@ -90,15 +90,16 @@ struct t_irc_nick
t_irc_nick *next_nick; /* link to next nick on the channel */
};
/* channel types */
#define CHANNEL_PREFIX "#&+!"
/* channel types */
#define CHANNEL_TYPE_UNKNOWN -1
#define CHANNEL_TYPE_CHANNEL 0
#define CHANNEL_TYPE_PRIVATE 1
#define CHANNEL_TYPE_DCC_CHAT 2
#define CHANNEL_NICKS_SPEAKING_LIMIT 32
typedef struct t_irc_channel t_irc_channel;
struct t_irc_channel
@@ -116,8 +117,12 @@ struct t_irc_channel
int cycle; /* currently cycling (/part then /join) */
int close; /* close request (/buffer close) */
int display_creation_date; /* 1 if creation date should be displayed */
int nick_completion_reset; /* 1 if nick completion should be rebuilt */
/* there was some join/part on channel */
t_irc_nick *nicks; /* nicks on the channel */
t_irc_nick *last_nick; /* last nick on the channel */
t_weelist *nicks_speaking; /* nicks speaking (for smart completion) */
t_weelist *last_nick_speaking; /* last nick speaking */
t_gui_buffer *buffer; /* GUI buffer allocated for channel */
t_irc_channel *prev_channel; /* link to previous channel */
t_irc_channel *next_channel; /* link to next channel */
@@ -415,6 +420,7 @@ extern void channel_set_away (t_irc_channel *, char *, int);
extern int channel_create_dcc (t_irc_dcc *);
extern int channel_get_notify_level (t_irc_server *, t_irc_channel *);
extern void channel_set_notify_level (t_irc_server *, t_irc_channel *, int);
extern void channel_add_nick_speaking (t_irc_channel *, char *);
extern void channel_print_log (t_irc_channel *);
/* nick functions (irc-nick.c) */
+2 -1
View File
@@ -322,7 +322,8 @@ plugin_cmd_handler_add (t_weechat_plugin *plugin, char *command,
/* add command to WeeChat commands list */
if (!weelist_search (index_commands, command))
weelist_add (&index_commands, &last_index_command, command);
weelist_add (&index_commands, &last_index_command, command,
WEELIST_POS_SORT);
}
else
{
+6 -1
View File
@@ -1,10 +1,15 @@
WeeChat - Wee Enhanced Environment for Chat
===========================================
ChangeLog - 2007-04-04
ChangeLog - 2007-04-14
Version 0.2.5 (under dev!):
* improved nick completion: added option look_nick_completion_smart,
enabled by default (task #5896)
* fixed nick completion in command arguments (bug #19590)
* fixed possible crash with nick completion when a nick leaves channel
(bug #19589)
* added color for input text not found in buffer history
* fixed USER message when connecting to IRC server (patch #5835)
+542 -533
View File
File diff suppressed because it is too large Load Diff
+542 -533
View File
File diff suppressed because it is too large Load Diff
+542 -533
View File
File diff suppressed because it is too large Load Diff
+544 -534
View File
File diff suppressed because it is too large Load Diff
+542 -533
View File
File diff suppressed because it is too large Load Diff
+542 -533
View File
File diff suppressed because it is too large Load Diff
+541 -533
View File
File diff suppressed because it is too large Load Diff
+6 -3
View File
@@ -251,7 +251,8 @@ command_index_build ()
while (weechat_commands[i].command_name)
{
(void) weelist_add (&index_commands, &last_index_command,
weechat_commands[i].command_name);
weechat_commands[i].command_name,
WEELIST_POS_SORT);
i++;
}
i = 0;
@@ -259,7 +260,8 @@ command_index_build ()
{
if (irc_commands[i].cmd_function_args || irc_commands[i].cmd_function_1arg)
(void) weelist_add (&index_commands, &last_index_command,
irc_commands[i].command_name);
irc_commands[i].command_name,
WEELIST_POS_SORT);
i++;
}
}
@@ -945,7 +947,8 @@ weechat_cmd_alias (t_irc_server *server, t_irc_channel *channel,
}
if (!alias_new (arguments, pos))
return -1;
if (weelist_add (&index_commands, &last_index_command, arguments))
if (weelist_add (&index_commands, &last_index_command, arguments,
WEELIST_POS_SORT))
{
irc_display_prefix (NULL, NULL, PREFIX_INFO);
gui_printf (NULL, _("Alias \"%s\" => \"%s\" created\n"),
+212 -135
View File
@@ -95,12 +95,14 @@ completion_free (t_completion *completion)
free (completion->args);
completion->args = NULL;
while (completion->completion_list)
weelist_remove (&completion->completion_list,
&completion->last_completion,
completion->completion_list);
weelist_remove_all (&completion->completion_list,
&completion->last_completion);
completion->completion_list = NULL;
completion->last_completion = NULL;
if (completion->word_found)
free (completion->word_found);
completion->word_found = NULL;
}
/*
@@ -203,20 +205,95 @@ completion_get_command_infos (t_completion *completion,
return;
}
/*
* completion_is_only_alphanum: return 1 if there is only alpha/num chars
* in a string
*/
int
completion_is_only_alphanum (char *string)
{
while (string[0])
{
if (strchr (cfg_look_nick_completion_ignore, string[0]))
return 0;
string++;
}
return 1;
}
/*
* completion_strdup_alphanum: duplicate alpha/num chars in a string
*/
char *
completion_strdup_alphanum (char *string)
{
char *result, *pos;
result = (char *)malloc (strlen (string) + 1);
pos = result;
while (string[0])
{
if (!strchr (cfg_look_nick_completion_ignore, string[0]))
{
pos[0] = string[0];
pos++;
}
string++;
}
pos[0] = '\0';
return result;
}
/*
* completion_nickncmp: locale and case independent string comparison
* with max length for nicks (alpha or digits only)
*/
int
completion_nickncmp (char *base_word, char *nick, int max)
{
char *base_word2, *nick2;
int return_cmp;
if (!cfg_look_nick_completion_ignore
|| !cfg_look_nick_completion_ignore[0]
|| !base_word || !nick || !base_word[0] || !nick[0]
|| (!completion_is_only_alphanum (base_word)))
return ascii_strncasecmp (base_word, nick, max);
base_word2 = completion_strdup_alphanum (base_word);
nick2 = completion_strdup_alphanum (nick);
return_cmp = ascii_strncasecmp (base_word2, nick2, strlen (base_word2));
free (base_word2);
free (nick2);
return return_cmp;
}
/*
* completion_list_add: add a word to completion word list
* if nick_completion != 0, then add as a nick
* if nick_completion < 0, then add at beginning of list
*/
void
completion_list_add (t_completion *completion, char *word)
completion_list_add (t_completion *completion, char *word, int nick_completion)
{
if (!completion->base_word || !completion->base_word[0]
|| (ascii_strncasecmp (completion->base_word, word,
strlen (completion->base_word)) == 0))
|| ((nick_completion != 0) && (completion_nickncmp (completion->base_word, word,
strlen (completion->base_word)) == 0))
|| ((nick_completion == 0) && (ascii_strncasecmp (completion->base_word, word,
strlen (completion->base_word)) == 0)))
{
weelist_add (&completion->completion_list,
&completion->last_completion,
word);
word,
(nick_completion < 0) ?
WEELIST_POS_BEGINNING : WEELIST_POS_SORT);
}
}
@@ -231,7 +308,7 @@ completion_list_add_alias (t_completion *completion)
for (ptr_alias = weechat_alias; ptr_alias; ptr_alias = ptr_alias->next_alias)
{
completion_list_add (completion, ptr_alias->alias_name);
completion_list_add (completion, ptr_alias->alias_name, 0);
}
}
@@ -246,7 +323,7 @@ completion_list_add_alias_cmd (t_completion *completion)
for (ptr_list = index_commands; ptr_list; ptr_list = ptr_list->next_weelist)
{
completion_list_add (completion, ptr_list->data);
completion_list_add (completion, ptr_list->data, 0);
}
}
@@ -259,7 +336,7 @@ completion_list_add_channel (t_completion *completion)
{
if (completion->channel)
completion_list_add (completion,
((t_irc_channel *)(completion->channel))->name);
((t_irc_channel *)(completion->channel))->name, 0);
}
/*
@@ -276,7 +353,7 @@ completion_list_add_server_channels (t_completion *completion)
for (ptr_channel = ((t_irc_server *)(completion->server))->channels;
ptr_channel; ptr_channel = ptr_channel->next_channel)
{
completion_list_add (completion, ptr_channel->name);
completion_list_add (completion, ptr_channel->name, 0);
}
}
}
@@ -361,7 +438,7 @@ completion_list_add_filename (t_completion *completion)
entry->d_name,
S_ISDIR(statbuf.st_mode) ? DIR_SEPARATOR : "");
completion_list_add (completion, buffer);
completion_list_add (completion, buffer, 0);
}
}
}
@@ -392,7 +469,7 @@ completion_list_add_plugin_cmd (t_completion *completion)
ptr_handler; ptr_handler = ptr_handler->next_handler)
{
if (ptr_handler->type == PLUGIN_HANDLER_COMMAND)
completion_list_add (completion, ptr_handler->command);
completion_list_add (completion, ptr_handler->command, 0);
}
}
#else
@@ -413,7 +490,7 @@ completion_list_add_irc_cmd_sent (t_completion *completion)
for (i = 0; irc_commands[i].command_name; i++)
{
if (irc_commands[i].cmd_function_args || irc_commands[i].cmd_function_1arg)
completion_list_add (completion, irc_commands[i].command_name);
completion_list_add (completion, irc_commands[i].command_name, 0);
}
}
@@ -429,7 +506,7 @@ completion_list_add_irc_cmd_recv (t_completion *completion)
for (i = 0; irc_commands[i].command_name; i++)
{
if (irc_commands[i].recv_function)
completion_list_add(completion, irc_commands[i].command_name);
completion_list_add(completion, irc_commands[i].command_name, 0);
}
}
@@ -444,7 +521,7 @@ completion_list_add_key_cmd (t_completion *completion)
for (i = 0; gui_key_functions[i].function_name; i++)
{
completion_list_add (completion, gui_key_functions[i].function_name);
completion_list_add (completion, gui_key_functions[i].function_name, 0);
}
}
@@ -457,7 +534,8 @@ completion_list_add_self_nick (t_completion *completion)
{
if (completion->server)
{
completion_list_add (completion, ((t_irc_server *)(completion->server))->nick);
completion_list_add (completion,
((t_irc_server *)(completion->server))->nick, 0);
}
}
@@ -469,22 +547,34 @@ void
completion_list_add_channel_nicks (t_completion *completion)
{
t_irc_nick *ptr_nick;
t_weelist *ptr_weelist;
if (completion->channel)
{
if (((t_irc_channel *)(completion->channel))->type == CHANNEL_TYPE_CHANNEL)
{
/* add channel nicks */
for (ptr_nick = ((t_irc_channel *)(completion->channel))->nicks;
ptr_nick; ptr_nick = ptr_nick->next_nick)
{
completion_list_add (completion, ptr_nick->nick);
completion_list_add (completion, ptr_nick->nick, 1);
}
/* add nicks speaking recently on this channel */
if (cfg_look_nick_completion_smart)
{
for (ptr_weelist = ((t_irc_channel *)(completion->channel))->nicks_speaking;
ptr_weelist; ptr_weelist = ptr_weelist->next_weelist)
{
if (nick_search ((t_irc_channel *)(completion->channel), ptr_weelist->data))
completion_list_add (completion, ptr_weelist->data, -1);
}
}
}
if ((((t_irc_channel *)(completion->channel))->type == CHANNEL_TYPE_PRIVATE)
|| (((t_irc_channel *)(completion->channel))->type == CHANNEL_TYPE_DCC_CHAT))
{
completion_list_add (completion,
((t_irc_channel *)(completion->channel))->name);
((t_irc_channel *)(completion->channel))->name, 1);
}
completion->arg_is_nick = 1;
}
@@ -508,7 +598,7 @@ completion_list_add_channel_nicks_hosts (t_completion *completion)
for (ptr_nick = ((t_irc_channel *)(completion->channel))->nicks;
ptr_nick; ptr_nick = ptr_nick->next_nick)
{
completion_list_add (completion, ptr_nick->nick);
completion_list_add (completion, ptr_nick->nick, 1);
if (ptr_nick->host)
{
length = strlen (ptr_nick->nick) + 1 +
@@ -518,7 +608,7 @@ completion_list_add_channel_nicks_hosts (t_completion *completion)
{
snprintf (buf, length, "%s!%s",
ptr_nick->nick, ptr_nick->host);
completion_list_add (completion, buf);
completion_list_add (completion, buf, 1);
free (buf);
}
}
@@ -528,7 +618,7 @@ completion_list_add_channel_nicks_hosts (t_completion *completion)
|| (((t_irc_channel *)(completion->channel))->type == CHANNEL_TYPE_PRIVATE))
{
completion_list_add (completion,
((t_irc_channel *)(completion->channel))->name);
((t_irc_channel *)(completion->channel))->name, 1);
}
completion->arg_is_nick = 1;
}
@@ -553,7 +643,7 @@ completion_list_add_option (t_completion *completion)
for (j = 0; weechat_options[i][j].option_name; j++)
{
completion_list_add (completion,
weechat_options[i][j].option_name);
weechat_options[i][j].option_name, 0);
}
}
}
@@ -565,7 +655,7 @@ completion_list_add_option (t_completion *completion)
snprintf (option_name, sizeof (option_name), "%s.%s",
ptr_server->name,
weechat_options[CONFIG_SECTION_SERVER][i].option_name);
completion_list_add (completion, option_name);
completion_list_add (completion, option_name, 0);
}
}
}
@@ -583,7 +673,7 @@ completion_list_add_plugin_option (t_completion *completion)
for (ptr_option = plugin_options; ptr_option;
ptr_option = ptr_option->next_option)
{
completion_list_add (completion, ptr_option->name);
completion_list_add (completion, ptr_option->name, 0);
}
#else
/* make C compiler happy */
@@ -599,7 +689,7 @@ void
completion_list_add_part (t_completion *completion)
{
if (cfg_irc_default_msg_part && cfg_irc_default_msg_part[0])
completion_list_add (completion, cfg_irc_default_msg_part);
completion_list_add (completion, cfg_irc_default_msg_part, 0);
}
/*
@@ -615,7 +705,7 @@ completion_list_add_plugin (t_completion *completion)
for (ptr_plugin = weechat_plugins; ptr_plugin;
ptr_plugin = ptr_plugin->next_plugin)
{
completion_list_add (completion, ptr_plugin->name);
completion_list_add (completion, ptr_plugin->name, 0);
}
#else
/* make C compiler happy */
@@ -631,7 +721,7 @@ void
completion_list_add_quit (t_completion *completion)
{
if (cfg_irc_default_msg_quit && cfg_irc_default_msg_quit[0])
completion_list_add (completion, cfg_irc_default_msg_quit);
completion_list_add (completion, cfg_irc_default_msg_quit, 0);
}
/*
@@ -643,7 +733,7 @@ completion_list_add_server (t_completion *completion)
{
if (completion->server)
completion_list_add (completion,
((t_irc_server *)(completion->server))->name);
((t_irc_server *)(completion->server))->name, 0);
}
/*
@@ -658,7 +748,7 @@ completion_list_add_servers (t_completion *completion)
for (ptr_server = irc_servers; ptr_server;
ptr_server = ptr_server->next_server)
{
completion_list_add (completion, ptr_server->name);
completion_list_add (completion, ptr_server->name, 0);
}
}
@@ -681,7 +771,7 @@ completion_list_add_topic (t_completion *completion)
string = (char *)gui_color_decode ((unsigned char *)((t_irc_channel *)(completion->channel))->topic, 0);
completion_list_add (completion,
(string) ?
string : ((t_irc_channel *)(completion->channel))->topic);
string : ((t_irc_channel *)(completion->channel))->topic, 0);
if (string)
free (string);
}
@@ -713,26 +803,26 @@ completion_list_add_option_value (t_completion *completion)
{
case OPTION_TYPE_BOOLEAN:
if (option_value && (*((int *)(option_value))))
completion_list_add (completion, "on");
completion_list_add (completion, "on", 0);
else
completion_list_add (completion, "off");
completion_list_add (completion, "off", 0);
break;
case OPTION_TYPE_INT:
snprintf (option_string, sizeof (option_string) - 1,
"%d", (option_value) ? *((int *)(option_value)) : option->default_int);
completion_list_add (completion, option_string);
completion_list_add (completion, option_string, 0);
break;
case OPTION_TYPE_INT_WITH_STRING:
completion_list_add (completion,
(option_value) ?
option->array_values[*((int *)(option_value))] :
option->array_values[option->default_int]);
option->array_values[option->default_int], 0);
break;
case OPTION_TYPE_COLOR:
completion_list_add (completion,
(option_value) ?
gui_color_get_name (*((int *)(option_value))) :
option->default_string);
option->default_string, 0);
break;
case OPTION_TYPE_STRING:
snprintf (option_string, sizeof (option_string) - 1,
@@ -740,7 +830,7 @@ completion_list_add_option_value (t_completion *completion)
((option_value) && (*((char **)(option_value)))) ?
*((char **)(option_value)) :
option->default_string);
completion_list_add (completion, option_string);
completion_list_add (completion, option_string, 0);
break;
}
}
@@ -768,7 +858,7 @@ completion_list_add_plugin_option_value (t_completion *completion)
ptr_option = plugin_config_search_internal (completion->args);
if (ptr_option)
completion_list_add (completion, ptr_option->value);
completion_list_add (completion, ptr_option->value, 0);
if (pos)
pos[0] = ' ';
@@ -790,7 +880,7 @@ completion_list_add_weechat_cmd (t_completion *completion)
for (i = 0; weechat_commands[i].command_name; i++)
{
completion_list_add (completion, weechat_commands[i].command_name);
completion_list_add (completion, weechat_commands[i].command_name, 0);
}
}
@@ -819,7 +909,8 @@ completion_build_list_template (t_completion *completion, char *template)
word[word_offset] = '\0';
weelist_add (&completion->completion_list,
&completion->last_completion,
word);
word,
WEELIST_POS_SORT);
}
word_offset = 0;
break;
@@ -1105,7 +1196,9 @@ completion_command (t_completion *completion)
{
if ((!completion->word_found) || word_found_seen)
{
completion->word_found = ptr_weelist->data;
if (completion->word_found)
free (completion->word_found);
completion->word_found = strdup (ptr_weelist->data);
if (completion->direction < 0)
ptr_weelist2 = ptr_weelist->prev_weelist;
@@ -1144,80 +1237,12 @@ completion_command (t_completion *completion)
}
if (completion->word_found)
{
free (completion->word_found);
completion->word_found = NULL;
completion_command (completion);
}
}
/*
* completion_is_only_alphanum: return 1 if there is only alpha/num chars
* in a string
*/
int
completion_is_only_alphanum (char *string)
{
while (string[0])
{
if (strchr (cfg_look_nick_completion_ignore, string[0]))
return 0;
string++;
}
return 1;
}
/*
* completion_strdup_alphanum: duplicate alpha/num chars in a string
*/
char *
completion_strdup_alphanum (char *string)
{
char *result, *pos;
result = (char *)malloc (strlen (string) + 1);
pos = result;
while (string[0])
{
if (!strchr (cfg_look_nick_completion_ignore, string[0]))
{
pos[0] = string[0];
pos++;
}
string++;
}
pos[0] = '\0';
return result;
}
/*
* completion_nickncmp: locale and case independent string comparison
* with max length for nicks (alpha or digits only)
*/
int
completion_nickncmp (char *base_word, char *nick, int max)
{
char *base_word2, *nick2;
int return_cmp;
if (!cfg_look_nick_completion_ignore
|| !cfg_look_nick_completion_ignore[0]
|| !base_word || !nick || !base_word[0] || !nick[0]
|| (!completion_is_only_alphanum (base_word)))
return ascii_strncasecmp (base_word, nick, max);
base_word2 = completion_strdup_alphanum (base_word);
nick2 = completion_strdup_alphanum (nick);
return_cmp = ascii_strncasecmp (base_word2, nick2, strlen (base_word2));
free (base_word2);
free (nick2);
return return_cmp;
}
/*
* completion_command_arg: complete a command argument
*/
@@ -1243,7 +1268,9 @@ completion_command_arg (t_completion *completion, int nick_completion)
{
if ((!completion->word_found) || word_found_seen)
{
completion->word_found = ptr_weelist->data;
if (completion->word_found)
free (completion->word_found);
completion->word_found = strdup (ptr_weelist->data);
if (completion->direction < 0)
ptr_weelist2 = ptr_weelist->prev_weelist;
@@ -1284,6 +1311,7 @@ completion_command_arg (t_completion *completion, int nick_completion)
}
if (completion->word_found)
{
free (completion->word_found);
completion->word_found = NULL;
completion_command_arg (completion, nick_completion);
}
@@ -1297,7 +1325,8 @@ void
completion_nick (t_completion *completion)
{
int length, word_found_seen, other_completion;
t_irc_nick *ptr_nick, *ptr_nick2;
t_irc_nick *ptr_nick;
t_weelist *ptr_weelist, *ptr_weelist2;
if (!completion->channel)
return;
@@ -1311,31 +1340,73 @@ completion_nick (t_completion *completion)
{
weelist_add (&completion->completion_list,
&completion->last_completion,
((t_irc_channel *)(completion->channel))->name);
((t_irc_channel *)(completion->channel))->name,
WEELIST_POS_SORT);
weelist_add (&completion->completion_list,
&completion->last_completion,
((t_irc_server *)(completion->server))->nick);
((t_irc_server *)(completion->server))->nick,
WEELIST_POS_SORT);
}
completion_command_arg (completion, 1);
return;
}
/* rebuild nick list for completion, with nicks speaking at beginning of list */
if ((((t_irc_channel *)(completion->channel))->nick_completion_reset)
|| (!(completion->completion_list)))
{
/* empty completion list */
if (completion->completion_list)
{
weelist_remove_all (&(completion->completion_list),
&(completion->last_completion));
completion->completion_list = NULL;
completion->last_completion = NULL;
}
/* add channel nicks */
for (ptr_nick = ((t_irc_channel *)(completion->channel))->nicks;
ptr_nick; ptr_nick = ptr_nick->next_nick)
{
weelist_add (&(completion->completion_list),
&(completion->last_completion),
ptr_nick->nick,
WEELIST_POS_SORT);
}
/* add nicks speaking recently on this channel */
if (cfg_look_nick_completion_smart)
{
for (ptr_weelist = ((t_irc_channel *)(completion->channel))->nicks_speaking;
ptr_weelist; ptr_weelist = ptr_weelist->next_weelist)
{
if (nick_search ((t_irc_channel *)(completion->channel), ptr_weelist->data))
weelist_add (&(completion->completion_list),
&(completion->last_completion),
ptr_weelist->data,
WEELIST_POS_BEGINNING);
}
}
((t_irc_channel *)(completion->channel))->nick_completion_reset = 0;
}
length = strlen (completion->base_word);
word_found_seen = 0;
other_completion = 0;
if (completion->direction < 0)
ptr_nick = ((t_irc_channel *)(completion->channel))->last_nick;
else
ptr_nick = ((t_irc_channel *)(completion->channel))->nicks;
while (ptr_nick)
if (completion->direction < 0)
ptr_weelist = completion->last_completion;
else
ptr_weelist = completion->completion_list;
while (ptr_weelist)
{
if (completion_nickncmp (completion->base_word, ptr_nick->nick, length) == 0)
if (completion_nickncmp (completion->base_word, ptr_weelist->data, length) == 0)
{
if ((!completion->word_found) || word_found_seen)
{
completion->word_found = ptr_nick->nick;
if (completion->word_found)
free (completion->word_found);
completion->word_found = strdup (ptr_weelist->data);
if (cfg_look_nick_complete_first)
{
completion->position = -1;
@@ -1343,21 +1414,21 @@ completion_nick (t_completion *completion)
}
if (completion->direction < 0)
ptr_nick2 = ptr_nick->prev_nick;
ptr_weelist2 = ptr_weelist->prev_weelist;
else
ptr_nick2 = ptr_nick->next_nick;
ptr_weelist2 = ptr_weelist->next_weelist;
while (ptr_nick2)
while (ptr_weelist2)
{
if (completion_nickncmp (completion->base_word,
ptr_nick2->nick,
ptr_weelist2->data,
length) == 0)
other_completion++;
if (completion->direction < 0)
ptr_nick2 = ptr_nick2->prev_nick;
ptr_weelist2 = ptr_weelist2->prev_weelist;
else
ptr_nick2 = ptr_nick2->next_nick;
ptr_weelist2 = ptr_weelist2->next_weelist;
}
if (other_completion == 0)
@@ -1372,16 +1443,17 @@ completion_nick (t_completion *completion)
other_completion++;
}
if (completion->word_found &&
(ascii_strcasecmp (ptr_nick->nick, completion->word_found) == 0))
(ascii_strcasecmp (ptr_weelist->data, completion->word_found) == 0))
word_found_seen = 1;
if (completion->direction < 0)
ptr_nick = ptr_nick->prev_nick;
ptr_weelist = ptr_weelist->prev_weelist;
else
ptr_nick = ptr_nick->next_nick;
ptr_weelist = ptr_weelist->next_weelist;
}
if (completion->word_found)
{
free (completion->word_found);
completion->word_found = NULL;
completion_nick (completion);
}
@@ -1435,12 +1507,15 @@ completion_search (t_completion *completion, int direction,
/* if new completion => look for base word */
if (pos != completion->position)
{
if (completion->word_found)
free (completion->word_found);
completion->word_found = NULL;
completion_find_context (completion, buffer, size, pos);
}
/* completion */
old_word_found = completion->word_found;
old_word_found = (completion->word_found) ?
strdup (completion->word_found) : NULL;
switch (completion->context)
{
case COMPLETION_NULL:
@@ -1487,6 +1562,8 @@ completion_search (t_completion *completion, int direction,
}
}
}
if (old_word_found)
free (old_word_found);
}
/*
+7 -1
View File
@@ -97,6 +97,7 @@ int cfg_look_align_size;
int cfg_look_align_size_max;
char *cfg_look_nick_completor;
char *cfg_look_nick_completion_ignore;
int cfg_look_nick_completion_smart;
int cfg_look_nick_complete_first;
int cfg_look_infobar;
char *cfg_look_infobar_timestamp;
@@ -222,6 +223,10 @@ t_config_option weechat_options_look[] =
N_("chars ignored for nick completion"),
OPTION_TYPE_STRING, 0, 0, 0,
"[]-^", NULL, NULL, &cfg_look_nick_completion_ignore, config_change_noop },
{ "look_nick_completion_smart", N_("smart completion for nicks"),
N_("smart completion for nicks (completes with last speakers first)"),
OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_TRUE,
NULL, NULL, &cfg_look_nick_completion_smart, NULL, config_change_noop },
{ "look_nick_complete_first", N_("complete only with first nick found"),
N_("complete only with first nick found"),
OPTION_TYPE_BOOLEAN, BOOL_FALSE, BOOL_TRUE, BOOL_FALSE,
@@ -2024,7 +2029,8 @@ config_read ()
{
/* create new alias */
if (alias_new (line, pos))
weelist_add (&index_commands, &last_index_command, line);
weelist_add (&index_commands, &last_index_command,
line, WEELIST_POS_SORT);
}
else if (section == CONFIG_SECTION_IGNORE)
{
+1
View File
@@ -114,6 +114,7 @@ extern int cfg_look_align_size;
extern int cfg_look_align_size_max;
extern char *cfg_look_nick_completor;
extern char *cfg_look_nick_completion_ignore;
extern int cfg_look_nick_completion_smart;
extern int cfg_look_nick_complete_first;
extern int cfg_look_infobar;
extern char *cfg_look_infobar_timestamp;
+63 -7
View File
@@ -33,6 +33,26 @@
#include "util.h"
/*
* weelist_get_size: get list size (number of elements)
*/
int
weelist_get_size (t_weelist *weelist)
{
t_weelist *ptr_weelist;
int count;
count = 0;
for (ptr_weelist = weelist; ptr_weelist; ptr_weelist = ptr_weelist->next_weelist)
{
count++;
}
return count;
}
/*
* weelist_search: search date in a list
*/
@@ -74,14 +94,36 @@ weelist_find_pos (t_weelist *weelist, char *data)
*/
void
weelist_insert (t_weelist **weelist, t_weelist **last_weelist, t_weelist *element)
weelist_insert (t_weelist **weelist, t_weelist **last_weelist, t_weelist *element,
int position)
{
t_weelist *pos_weelist;
pos_weelist = weelist_find_pos (*weelist, element->data);
if (*weelist)
{
/* remove element if already in list */
pos_weelist = weelist_search (*weelist, element->data);
if (pos_weelist)
weelist_remove (weelist, last_weelist, pos_weelist);
}
if (*weelist)
{
/* search position for new element, according to pos asked */
pos_weelist = NULL;
switch (position)
{
case WEELIST_POS_SORT:
pos_weelist = weelist_find_pos (*weelist, element->data);
break;
case WEELIST_POS_BEGINNING:
pos_weelist = *weelist;
break;
case WEELIST_POS_END:
pos_weelist = NULL;
break;
}
if (pos_weelist)
{
/* insert data into the list (before position found) */
@@ -116,7 +158,8 @@ weelist_insert (t_weelist **weelist, t_weelist **last_weelist, t_weelist *elemen
*/
t_weelist *
weelist_add (t_weelist **weelist, t_weelist **last_weelist, char *data)
weelist_add (t_weelist **weelist, t_weelist **last_weelist, char *data,
int position)
{
t_weelist *new_weelist;
@@ -126,7 +169,7 @@ weelist_add (t_weelist **weelist, t_weelist **last_weelist, char *data)
if ((new_weelist = ((t_weelist *) malloc (sizeof (t_weelist)))))
{
new_weelist->data = strdup (data);
weelist_insert (weelist, last_weelist, new_weelist);
weelist_insert (weelist, last_weelist, new_weelist, position);
return new_weelist;
}
/* failed to allocate new element */
@@ -134,7 +177,7 @@ weelist_add (t_weelist **weelist, t_weelist **last_weelist, char *data)
}
/*
* weelist_remove: free an element in a list
* weelist_remove: remove an element from a list
*/
void
@@ -142,7 +185,7 @@ weelist_remove (t_weelist **weelist, t_weelist **last_weelist, t_weelist *elemen
{
t_weelist *new_weelist;
if (!element)
if (!element || !(*weelist))
return;
/* remove element from list */
@@ -166,6 +209,19 @@ weelist_remove (t_weelist **weelist, t_weelist **last_weelist, t_weelist *elemen
*weelist = new_weelist;
}
/*
* weelist_remove_all: remove all elements from a list
*/
void
weelist_remove_all (t_weelist **weelist, t_weelist **last_weelist)
{
while (*weelist)
{
weelist_remove (weelist, last_weelist, *weelist);
}
}
/*
* weelist_print_log: print weelist in log (usually for crash dump)
*/
+7 -1
View File
@@ -21,6 +21,10 @@
#ifndef __WEECHAT_LIST_H
#define __WEECHAT_LIST_H 1
#define WEELIST_POS_SORT 0
#define WEELIST_POS_BEGINNING 1
#define WEELIST_POS_END 2
typedef struct t_weelist t_weelist;
struct t_weelist
@@ -30,9 +34,11 @@ struct t_weelist
t_weelist *next_weelist;
};
extern int weelist_get_size (t_weelist *);
extern t_weelist *weelist_search (t_weelist *, char *);
extern t_weelist *weelist_add (t_weelist **, t_weelist **, char *);
extern t_weelist *weelist_add (t_weelist **, t_weelist **, char *, int);
extern void weelist_remove (t_weelist **, t_weelist **, t_weelist *);
extern void weelist_remove_all (t_weelist **, t_weelist **);
extern void weelist_print_log (t_weelist *, char *);
#endif /* weelist.h */
+39
View File
@@ -70,9 +70,12 @@ channel_new (t_irc_server *server, int channel_type, char *channel_name)
new_channel->cycle = 0;
new_channel->close = 0;
new_channel->display_creation_date = 0;
new_channel->nick_completion_reset = 0;
new_channel->nicks = NULL;
new_channel->last_nick = NULL;
new_channel->buffer = NULL;
new_channel->nicks_speaking = NULL;
new_channel->last_nick_speaking = NULL;
/* add new channel to queue */
new_channel->prev_channel = server->last_channel;
@@ -136,6 +139,9 @@ channel_free (t_irc_server *server, t_irc_channel *channel)
nick_free_all (channel);
if (channel->away_message)
free (channel->away_message);
if (channel->nicks_speaking)
weelist_remove_all (&(channel->nicks_speaking),
&(channel->last_nick_speaking));
free (channel);
server->channels = new_channels;
}
@@ -404,6 +410,31 @@ channel_set_notify_level (t_irc_server *server, t_irc_channel *channel, int noti
config_option_list_set (&(server->notify_levels), channel->name, level_string);
}
/*
* channel_add_nick_speaking: add a nick speaking on a channel
*/
void
channel_add_nick_speaking (t_irc_channel *channel, char *nick)
{
int size, to_remove, i;
weelist_add (&(channel->nicks_speaking), &(channel->last_nick_speaking),
nick, WEELIST_POS_END);
size = weelist_get_size (channel->nicks_speaking);
if (size > CHANNEL_NICKS_SPEAKING_LIMIT)
{
to_remove = size - CHANNEL_NICKS_SPEAKING_LIMIT;
for (i = 0; i < to_remove; i++)
{
weelist_remove (&(channel->nicks_speaking),
&(channel->last_nick_speaking),
channel->nicks_speaking);
}
}
}
/*
* channel_print_log: print channel infos in log (usually for crash dump)
*/
@@ -426,6 +457,14 @@ channel_print_log (t_irc_channel *channel)
weechat_log_printf (" nicks. . . . . . . . : 0x%X\n", channel->nicks);
weechat_log_printf (" last_nick. . . . . . : 0x%X\n", channel->last_nick);
weechat_log_printf (" buffer . . . . . . . : 0x%X\n", channel->buffer);
weechat_log_printf (" nicks_speaking . . . : 0x%X\n", channel->nicks_speaking);
weechat_log_printf (" last_nick_speaking . : 0x%X\n", channel->last_nick_speaking);
weechat_log_printf (" prev_channel . . . . : 0x%X\n", channel->prev_channel);
weechat_log_printf (" next_channel . . . . : 0x%X\n", channel->next_channel);
if (channel->nicks_speaking)
{
weechat_log_printf ("\n");
weelist_print_log (channel->nicks_speaking,
"channel nick speaking element");
}
}
+4
View File
@@ -232,6 +232,8 @@ nick_new (t_irc_server *server, t_irc_channel *channel, char *nick_name,
nick_insert_sorted (channel, new_nick);
channel->nicks_count++;
channel->nick_completion_reset = 1;
/* all is ok, return address of new nick */
return new_nick;
@@ -296,6 +298,8 @@ nick_free (t_irc_channel *channel, t_irc_nick *nick)
free (nick->host);
free (nick);
channel->nicks = new_nicks;
channel->nick_completion_reset = 1;
}
/*
+2
View File
@@ -1392,6 +1392,7 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *nick, char *argume
gui_printf (ptr_channel->buffer, " %s%s\n",
GUI_COLOR(COLOR_WIN_CHAT), pos);
}
channel_add_nick_speaking (ptr_channel, nick);
}
return 0;
}
@@ -1520,6 +1521,7 @@ irc_cmd_recv_privmsg (t_irc_server *server, char *host, char *nick, char *argume
gui_printf_type (ptr_channel->buffer, MSG_TYPE_MSG,
"%s\n", pos);
}
channel_add_nick_speaking (ptr_channel, nick);
}
}
else
+8 -2
View File
@@ -90,15 +90,16 @@ struct t_irc_nick
t_irc_nick *next_nick; /* link to next nick on the channel */
};
/* channel types */
#define CHANNEL_PREFIX "#&+!"
/* channel types */
#define CHANNEL_TYPE_UNKNOWN -1
#define CHANNEL_TYPE_CHANNEL 0
#define CHANNEL_TYPE_PRIVATE 1
#define CHANNEL_TYPE_DCC_CHAT 2
#define CHANNEL_NICKS_SPEAKING_LIMIT 32
typedef struct t_irc_channel t_irc_channel;
struct t_irc_channel
@@ -116,8 +117,12 @@ struct t_irc_channel
int cycle; /* currently cycling (/part then /join) */
int close; /* close request (/buffer close) */
int display_creation_date; /* 1 if creation date should be displayed */
int nick_completion_reset; /* 1 if nick completion should be rebuilt */
/* there was some join/part on channel */
t_irc_nick *nicks; /* nicks on the channel */
t_irc_nick *last_nick; /* last nick on the channel */
t_weelist *nicks_speaking; /* nicks speaking (for smart completion) */
t_weelist *last_nick_speaking; /* last nick speaking */
t_gui_buffer *buffer; /* GUI buffer allocated for channel */
t_irc_channel *prev_channel; /* link to previous channel */
t_irc_channel *next_channel; /* link to next channel */
@@ -415,6 +420,7 @@ extern void channel_set_away (t_irc_channel *, char *, int);
extern int channel_create_dcc (t_irc_dcc *);
extern int channel_get_notify_level (t_irc_server *, t_irc_channel *);
extern void channel_set_notify_level (t_irc_server *, t_irc_channel *, int);
extern void channel_add_nick_speaking (t_irc_channel *, char *);
extern void channel_print_log (t_irc_channel *);
/* nick functions (irc-nick.c) */
+2 -1
View File
@@ -322,7 +322,8 @@ plugin_cmd_handler_add (t_weechat_plugin *plugin, char *command,
/* add command to WeeChat commands list */
if (!weelist_search (index_commands, command))
weelist_add (&index_commands, &last_index_command, command);
weelist_add (&index_commands, &last_index_command, command,
WEELIST_POS_SORT);
}
else
{