From 40f47a0a5f94499b59e38dba6a2c154cbe25e7f7 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 22 May 2001 00:29:31 +0000 Subject: [PATCH] /SET completion_strict OFF - specifies if the tab nick completion should ignore non-alphanumeric characters. Alieases are now completed in command completion. Patch by fuchs. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1513 dbcabf3a-b0e7-0310-adc4-f8d773084564 --- src/fe-common/core/chat-completion.c | 64 ++++++++++++++++++++++++++-- src/fe-common/core/completion.c | 42 ++++++++++++++++++ 2 files changed, 103 insertions(+), 3 deletions(-) diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index 67631dd2..f14c0730 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -38,6 +38,7 @@ static int keep_privates_count, keep_publics_count; static int completion_lowercase; static const char *completion_char, *cmdchars; static GSList *global_lastmsgs; +static int completion_auto, completion_strict; #define SERVER_LAST_MSG_ADD(server, nick) \ last_msg_add(&((MODULE_SERVER_REC *) MODULE_DATA(server))->lastmsgs, \ @@ -350,6 +351,57 @@ static void complete_from_nicklist(GList **outlist, CHANNEL_REC *channel, *outlist = g_list_concat(ownlist, *outlist); } +static GList *completion_nicks_nonstrict(CHANNEL_REC *channel, + const char *nick, + const char *suffix) +{ + GSList *nicks, *tmp; + GList *list; + char *tnick, *str, *in, *out; + int len, str_len; + + g_return_val_if_fail(channel != NULL, NULL); + + list = NULL; + + /* get all nicks from current channel, strip non alnum chars, + compare again and add to completion list on matching */ + len = strlen(nick); + nicks = nicklist_getnicks(channel); + + str_len = 80; str = g_malloc(str_len+1); + for (tmp = nicks; tmp != NULL; tmp = tmp->next) { + NICK_REC *rec = tmp->data; + + len = strlen(rec->nick); + if (len > str_len) { + str_len = len*2; + str = g_realloc(str, str_len+1); + } + + /* remove non alnum chars from nick */ + in = rec->nick; out = str; + while (*in != '\0') { + if (isalnum(*in)) + *out++ = *in; + in++; + } + *out = '\0'; + + /* add to list if 'cleaned' nick matches */ + if (g_strncasecmp(str, nick, len) == 0) { + tnick = g_strconcat(rec->nick, suffix, NULL); + if (completion_lowercase) + g_strdown(tnick); + list = g_list_append(list, tnick); + } + + } + g_slist_free(nicks); + + return list; +} + static GList *completion_channel_nicks(CHANNEL_REC *channel, const char *nick, const char *suffix) { @@ -385,6 +437,10 @@ static GList *completion_channel_nicks(CHANNEL_REC *channel, const char *nick, } g_slist_free(nicks); + /* remove non alphanum chars from nick and search again in case + list is still NULL ("foo" would match "_foo_" f.e.) */ + if (!completion_strict) + list = g_list_concat(list, completion_nicks_nonstrict(channel, nick, suffix)); return list; } @@ -687,8 +743,7 @@ static void event_text(const char *data, SERVER_REC *server, WI_ITEM_REC *item) comp = NULL; channel = CHANNEL(item); - if (channel != NULL && comp_char != '\0' && - settings_get_bool("completion_auto")) { + if (completion_auto && channel != NULL && comp_char != '\0') { ptr = strchr(line, comp_char); if (ptr != NULL) { *ptr++ = '\0'; @@ -746,6 +801,8 @@ static void read_settings(void) completion_lowercase = settings_get_bool("completion_nicks_lowercase"); completion_char = settings_get_str("completion_char"); cmdchars = settings_get_str("cmdchars"); + completion_auto = settings_get_bool("completion_auto"); + completion_strict = settings_get_bool("completion_strict"); } void chat_completion_init(void) @@ -756,8 +813,9 @@ void chat_completion_init(void) settings_add_int("completion", "completion_keep_privates", 10); settings_add_bool("completion", "expand_escapes", FALSE); settings_add_bool("completion", "completion_nicks_lowercase", FALSE); + settings_add_bool("completion", "completion_strict", FALSE); - read_settings(); + read_settings(); signal_add("complete word", (SIGNAL_FUNC) sig_complete_word); signal_add("complete command msg", (SIGNAL_FUNC) sig_complete_msg); signal_add("complete command connect", (SIGNAL_FUNC) sig_complete_connect); diff --git a/src/fe-common/core/completion.c b/src/fe-common/core/completion.c index 3c41eeee..16427610 100644 --- a/src/fe-common/core/completion.c +++ b/src/fe-common/core/completion.c @@ -320,6 +320,42 @@ static GList *completion_get_bool_settings(const char *key) return complist; } +static GList *completion_get_aliases(const char *alias, char cmdchar) +{ + CONFIG_NODE *node; + GList *complist; + GSList *tmp; + char *word; + int len; + + g_return_val_if_fail(alias != NULL, NULL); + + /* get list of aliases from mainconfig */ + node = iconfig_node_traverse("aliases", FALSE); + tmp = node == NULL ? NULL : node->value; + + len = strlen(alias); + complist = NULL; + for (; tmp != NULL; tmp = tmp->next) { + CONFIG_NODE *node = tmp->data; + + if (node->type != NODE_TYPE_KEY) + continue; + + if (g_strncasecmp(node->key, alias, len) == 0) { + word = g_strdup_printf("%c%s", cmdchar, node->key); + /* add matching alias to completion list, aliases will + be appended after command completions and kept in + uppercase to show it's an alias */ + if (glist_find_icase_string(complist, word) == NULL) + complist = g_list_insert_sorted(complist, word, (GCompareFunc) g_istr_cmp); + else + g_free(word); + } + } + return complist; +} + static GList *completion_get_commands(const char *cmd, char cmdchar) { GList *complist; @@ -490,6 +526,10 @@ static void sig_complete_word(GList **list, WINDOW_REC *window, /* complete /command */ *list = completion_get_commands(word+1, *word); + /* complete aliases, too */ + *list = g_list_concat(*list, + completion_get_aliases(word+1, *word)); + if (*list != NULL) signal_stop(); return; } @@ -637,3 +677,5 @@ void completion_deinit(void) signal_remove("complete command rawlog save", (SIGNAL_FUNC) sig_complete_filename); signal_remove("complete command help", (SIGNAL_FUNC) sig_complete_command); } + +