Skip to content
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

Implement substring autocompletion for /msg #1985

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
2 changes: 1 addition & 1 deletion src/command/cmd_ac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
41 changes: 31 additions & 10 deletions src/tools/autocomplete.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;

Expand All @@ -266,35 +266,35 @@ 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;

// subsequent search attempt
} 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;
}
}

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;
}
Expand All @@ -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*
Expand Down Expand Up @@ -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);
Expand All @@ -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;

Expand Down
2 changes: 2 additions & 0 deletions src/tools/autocomplete.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 8 additions & 0 deletions src/xmpp/roster_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
1 change: 1 addition & 0 deletions src/xmpp/roster_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading