mirror of
https://github.com/profanity-im/profanity.git
synced 2024-12-04 14:46:46 -05:00
Implement substring autocompletion for /msg
People with huge contact lists most likely happen to have contacts starting with popular names more often. They can use /msg Arthur to find the correct person. But if they have 50 Arthurs it will take a while. Using the surname might be faster. So a substring search of /msg Clarke<tab> will be faster. Fix https://github.com/profanity-im/profanity/issues/1984
This commit is contained in:
parent
4d9852a76a
commit
8ce8f8e6dc
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user