diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index cf283d905..bec819a06 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -2084,7 +2084,7 @@ _cmd_ac_complete_params(ProfWin* window, const char* const input, gboolean previ // Remove quote character before and after names when doing autocomplete char* unquoted = strip_arg_quotes(input); for (int i = 0; i < ARRAY_SIZE(contact_choices); i++) { - result = autocomplete_param_with_func(unquoted, contact_choices[i], roster_contact_autocomplete, previous, NULL); + result = autocomplete_param_with_func(unquoted, contact_choices[i], roster_contact_autocomplete_substring, previous, NULL); if (result) { free(unquoted); return result; diff --git a/src/tools/autocomplete.c b/src/tools/autocomplete.c index ebbce5e3a..8afc31062 100644 --- a/src/tools/autocomplete.c +++ b/src/tools/autocomplete.c @@ -57,7 +57,7 @@ struct autocomplete_t gchar* search_str; }; -static gchar* _search(Autocomplete ac, GList* curr, gboolean quote, search_direction direction); +static gchar* _search(Autocomplete ac, GList* curr, gboolean quote, search_direction direction, gboolean substring); Autocomplete autocomplete_new(void) @@ -245,7 +245,7 @@ autocomplete_contains(Autocomplete ac, const char* value) } gchar* -autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote, gboolean previous) +_autocomplete_complete_internal(Autocomplete ac, const gchar* search_str, gboolean quote, gboolean previous, gboolean substring) { gchar* found = NULL; @@ -266,7 +266,7 @@ autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote, } ac->search_str = strdup(search_str); - found = _search(ac, ac->items, quote, NEXT); + found = _search(ac, ac->items, quote, NEXT, substring); return found; @@ -274,13 +274,13 @@ autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote, } else { if (previous) { // search from here-1 to beginning - found = _search(ac, g_list_previous(ac->last_found), quote, PREVIOUS); + found = _search(ac, g_list_previous(ac->last_found), quote, PREVIOUS, substring); if (found) { return found; } } else { // search from here+1 to end - found = _search(ac, g_list_next(ac->last_found), quote, NEXT); + found = _search(ac, g_list_next(ac->last_found), quote, NEXT, substring); if (found) { return found; } @@ -288,13 +288,13 @@ autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote, if (previous) { // search from end - found = _search(ac, g_list_last(ac->items), quote, PREVIOUS); + found = _search(ac, g_list_last(ac->items), quote, PREVIOUS, substring); if (found) { return found; } } else { // search from beginning - found = _search(ac, ac->items, quote, NEXT); + found = _search(ac, ac->items, quote, NEXT, substring); if (found) { return found; } @@ -307,6 +307,18 @@ autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote, } } +gchar* +autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote, gboolean previous) +{ + return _autocomplete_complete_internal(ac, search_str, quote, previous, FALSE); +} + +gchar* +autocomplete_complete_substring(Autocomplete ac, const gchar* search_str, gboolean quote, gboolean previous) +{ + return _autocomplete_complete_internal(ac, search_str, quote, previous, TRUE); +} + // autocomplete_func func is used -> autocomplete_param_with_func // Autocomplete ac, gboolean quote are used -> autocomplete_param_with_ac static char* @@ -399,7 +411,7 @@ autocomplete_remove_older_than_max_reverse(Autocomplete ac, int maxsize) } static gchar* -_search(Autocomplete ac, GList* curr, gboolean quote, search_direction direction) +_search(Autocomplete ac, GList* curr, gboolean quote, search_direction direction, gboolean substring) { auto_gchar gchar* search_str_ascii = g_str_to_ascii(ac->search_str, NULL); auto_gchar gchar* search_str_lower = g_ascii_strdown(search_str_ascii, -1); @@ -408,9 +420,18 @@ _search(Autocomplete ac, GList* curr, gboolean quote, search_direction direction auto_gchar gchar* curr_ascii = g_str_to_ascii(curr->data, NULL); auto_gchar gchar* curr_lower = g_ascii_strdown(curr_ascii, -1); - // match found - if (strncmp(curr_lower, search_str_lower, strlen(search_str_lower)) == 0) { + gboolean found = FALSE; + if (!substring && (strncmp(curr_lower, search_str_lower, strlen(search_str_lower)) == 0)) { + // if we want to start from beginning (prefix) + found = TRUE; + } else if (substring && (strstr(curr_lower, search_str_lower) != 0)) { + // if we only are looking for a substring + found = TRUE; + } + + // match found + if (found) { // set pointer to last found ac->last_found = curr; diff --git a/src/tools/autocomplete.h b/src/tools/autocomplete.h index 851dbc0df..3a492cac8 100644 --- a/src/tools/autocomplete.h +++ b/src/tools/autocomplete.h @@ -59,6 +59,8 @@ void autocomplete_add_unsorted(Autocomplete ac, const char* item, const gboolean // find the next item prefixed with search string gchar* autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote, gboolean previous); +// find the next item containing search string +gchar* autocomplete_complete_substring(Autocomplete ac, const gchar* search_str, gboolean quote, gboolean previous); GList* autocomplete_create_list(Autocomplete ac); gint autocomplete_length(Autocomplete ac); diff --git a/src/xmpp/roster_list.c b/src/xmpp/roster_list.c index 40b8210d4..d1cf9fafd 100644 --- a/src/xmpp/roster_list.c +++ b/src/xmpp/roster_list.c @@ -517,6 +517,14 @@ roster_contact_autocomplete(const char* const search_str, gboolean previous, voi return autocomplete_complete(roster->name_ac, search_str, TRUE, previous); } +char* +roster_contact_autocomplete_substring(const char* const search_str, gboolean previous, void* context) +{ + assert(roster != NULL); + + return autocomplete_complete_substring(roster->name_ac, search_str, TRUE, previous); +} + char* roster_fulljid_autocomplete(const char* const search_str, gboolean previous, void* context) { diff --git a/src/xmpp/roster_list.h b/src/xmpp/roster_list.h index be29bd69f..02e9ae3ff 100644 --- a/src/xmpp/roster_list.h +++ b/src/xmpp/roster_list.h @@ -64,6 +64,7 @@ GSList* roster_get_contacts(roster_ord_t order); GSList* roster_get_contacts_online(void); gboolean roster_has_pending_subscriptions(void); char* roster_contact_autocomplete(const char* const search_str, gboolean previous, void* context); +char* roster_contact_autocomplete_substring(const char* const search_str, gboolean previous, void* context); char* roster_fulljid_autocomplete(const char* const search_str, gboolean previous, void* context); GSList* roster_get_group(const char* const group, roster_ord_t order); GList* roster_get_groups(void);