Merge pull request #1503 from profanity-im/cleanup/autocomplete-1
Cleanup autocomplete
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -43,6 +44,11 @@
|
|||||||
#include "tools/parser.h"
|
#include "tools/parser.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PREVIOUS,
|
||||||
|
NEXT
|
||||||
|
} search_direction;
|
||||||
|
|
||||||
struct autocomplete_t
|
struct autocomplete_t
|
||||||
{
|
{
|
||||||
GList* items;
|
GList* items;
|
||||||
@@ -50,8 +56,7 @@ struct autocomplete_t
|
|||||||
gchar* search_str;
|
gchar* search_str;
|
||||||
};
|
};
|
||||||
|
|
||||||
static gchar* _search_next(Autocomplete ac, GList* curr, gboolean quote);
|
static gchar* _search(Autocomplete ac, GList* curr, gboolean quote, search_direction direction);
|
||||||
static gchar* _search_prev(Autocomplete ac, GList* curr, gboolean quote);
|
|
||||||
|
|
||||||
Autocomplete
|
Autocomplete
|
||||||
autocomplete_new(void)
|
autocomplete_new(void)
|
||||||
@@ -257,7 +262,7 @@ autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ac->search_str = strdup(search_str);
|
ac->search_str = strdup(search_str);
|
||||||
found = _search_next(ac, ac->items, quote);
|
found = _search(ac, ac->items, quote, NEXT);
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
|
|
||||||
@@ -265,13 +270,13 @@ autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote,
|
|||||||
} else {
|
} else {
|
||||||
if (previous) {
|
if (previous) {
|
||||||
// search from here-1 to beginning
|
// search from here-1 to beginning
|
||||||
found = _search_prev(ac, g_list_previous(ac->last_found), quote);
|
found = _search(ac, g_list_previous(ac->last_found), quote, PREVIOUS);
|
||||||
if (found) {
|
if (found) {
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// search from here+1 to end
|
// search from here+1 to end
|
||||||
found = _search_next(ac, g_list_next(ac->last_found), quote);
|
found = _search(ac, g_list_next(ac->last_found), quote, NEXT);
|
||||||
if (found) {
|
if (found) {
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
@@ -279,13 +284,13 @@ autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote,
|
|||||||
|
|
||||||
if (previous) {
|
if (previous) {
|
||||||
// search from end
|
// search from end
|
||||||
found = _search_prev(ac, g_list_last(ac->items), quote);
|
found = _search(ac, g_list_last(ac->items), quote, PREVIOUS);
|
||||||
if (found) {
|
if (found) {
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// search from beginning
|
// search from beginning
|
||||||
found = _search_next(ac, ac->items, quote);
|
found = _search(ac, ac->items, quote, NEXT);
|
||||||
if (found) {
|
if (found) {
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
@@ -298,53 +303,38 @@ autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char*
|
// autocomplete_func func is used -> autocomplete_param_with_func
|
||||||
autocomplete_param_with_func(const char* const input, char* command, autocomplete_func func, gboolean previous, void* context)
|
// Autocomplete ac, gboolean quote are used -> autocomplete_param_with_ac
|
||||||
|
static char*
|
||||||
|
_autocomplete_param_common(const char* const input, char* command, autocomplete_func func, Autocomplete ac, gboolean quote, gboolean previous, void* context)
|
||||||
{
|
{
|
||||||
GString* auto_msg = NULL;
|
GString* auto_msg;
|
||||||
|
char* command_cpy;
|
||||||
char* result = NULL;
|
char* result = NULL;
|
||||||
char command_cpy[strlen(command) + 2];
|
int len;
|
||||||
sprintf(command_cpy, "%s ", command);
|
|
||||||
int len = strlen(command_cpy);
|
len = asprintf(&command_cpy, "%s ", command);
|
||||||
|
if (len == -1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (strncmp(input, command_cpy, len) == 0) {
|
if (strncmp(input, command_cpy, len) == 0) {
|
||||||
int inp_len = strlen(input);
|
int inp_len = strlen(input);
|
||||||
char prefix[inp_len];
|
char prefix[inp_len];
|
||||||
|
char *found;
|
||||||
|
|
||||||
for (int i = len; i < inp_len; i++) {
|
for (int i = len; i < inp_len; i++) {
|
||||||
prefix[i - len] = input[i];
|
prefix[i - len] = input[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix[inp_len - len] = '\0';
|
prefix[inp_len - len] = '\0';
|
||||||
|
|
||||||
char* found = func(prefix, previous, context);
|
if (func) {
|
||||||
if (found) {
|
found = func(prefix, previous, context);
|
||||||
auto_msg = g_string_new(command_cpy);
|
} else {
|
||||||
g_string_append(auto_msg, found);
|
found = autocomplete_complete(ac, prefix, quote, previous);
|
||||||
free(found);
|
|
||||||
result = auto_msg->str;
|
|
||||||
g_string_free(auto_msg, FALSE);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
char*
|
|
||||||
autocomplete_param_with_ac(const char* const input, char* command, Autocomplete ac, gboolean quote, gboolean previous)
|
|
||||||
{
|
|
||||||
GString* auto_msg = NULL;
|
|
||||||
char* result = NULL;
|
|
||||||
char* command_cpy = malloc(strlen(command) + 2);
|
|
||||||
sprintf(command_cpy, "%s ", command);
|
|
||||||
int len = strlen(command_cpy);
|
|
||||||
int inp_len = strlen(input);
|
|
||||||
if (strncmp(input, command_cpy, len) == 0) {
|
|
||||||
char prefix[inp_len];
|
|
||||||
for (int i = len; i < inp_len; i++) {
|
|
||||||
prefix[i - len] = input[i];
|
|
||||||
}
|
|
||||||
prefix[inp_len - len] = '\0';
|
|
||||||
|
|
||||||
char* found = autocomplete_complete(ac, prefix, quote, previous);
|
|
||||||
if (found) {
|
if (found) {
|
||||||
auto_msg = g_string_new(command_cpy);
|
auto_msg = g_string_new(command_cpy);
|
||||||
g_string_append(auto_msg, found);
|
g_string_append(auto_msg, found);
|
||||||
@@ -358,6 +348,18 @@ autocomplete_param_with_ac(const char* const input, char* command, Autocomplete
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
autocomplete_param_with_func(const char* const input, char* command, autocomplete_func func, gboolean previous, void* context)
|
||||||
|
{
|
||||||
|
return _autocomplete_param_common(input, command, func, NULL, FALSE, previous, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
autocomplete_param_with_ac(const char* const input, char* command, Autocomplete ac, gboolean quote, gboolean previous)
|
||||||
|
{
|
||||||
|
return _autocomplete_param_common(input, command, NULL, ac, quote, previous, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
char*
|
char*
|
||||||
autocomplete_param_no_with_func(const char* const input, char* command, int arg_number, autocomplete_func func, gboolean previous, void* context)
|
autocomplete_param_no_with_func(const char* const input, char* command, int arg_number, autocomplete_func func, gboolean previous, void* context)
|
||||||
{
|
{
|
||||||
@@ -411,7 +413,7 @@ autocomplete_remove_older_than_max_reverse(Autocomplete ac, int maxsize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gchar*
|
static gchar*
|
||||||
_search_next(Autocomplete ac, GList* curr, gboolean quote)
|
_search(Autocomplete ac, GList* curr, gboolean quote, search_direction direction)
|
||||||
{
|
{
|
||||||
gchar* search_str_ascii = g_str_to_ascii(ac->search_str, NULL);
|
gchar* search_str_ascii = g_str_to_ascii(ac->search_str, NULL);
|
||||||
gchar* search_str_lower = g_ascii_strdown(search_str_ascii, -1);
|
gchar* search_str_lower = g_ascii_strdown(search_str_ascii, -1);
|
||||||
@@ -450,54 +452,12 @@ _search_next(Autocomplete ac, GList* curr, gboolean quote)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_free(curr_lower);
|
g_free(curr_lower);
|
||||||
curr = g_list_next(curr);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free(search_str_lower);
|
if (direction == PREVIOUS) {
|
||||||
return NULL;
|
curr = g_list_previous(curr);
|
||||||
}
|
} else {
|
||||||
|
curr = g_list_next(curr);
|
||||||
static gchar*
|
|
||||||
_search_prev(Autocomplete ac, GList* curr, gboolean quote)
|
|
||||||
{
|
|
||||||
gchar* search_str_ascii = g_str_to_ascii(ac->search_str, NULL);
|
|
||||||
gchar* search_str_lower = g_ascii_strdown(search_str_ascii, -1);
|
|
||||||
g_free(search_str_ascii);
|
|
||||||
|
|
||||||
while (curr) {
|
|
||||||
gchar* curr_ascii = g_str_to_ascii(curr->data, NULL);
|
|
||||||
gchar* curr_lower = g_ascii_strdown(curr_ascii, -1);
|
|
||||||
g_free(curr_ascii);
|
|
||||||
|
|
||||||
// match found
|
|
||||||
if (strncmp(curr_lower, search_str_lower, strlen(search_str_lower)) == 0) {
|
|
||||||
|
|
||||||
// set pointer to last found
|
|
||||||
ac->last_found = curr;
|
|
||||||
|
|
||||||
// if contains space, quote before returning
|
|
||||||
if (quote && g_strrstr(curr->data, " ")) {
|
|
||||||
GString* quoted = g_string_new("\"");
|
|
||||||
g_string_append(quoted, curr->data);
|
|
||||||
g_string_append(quoted, "\"");
|
|
||||||
|
|
||||||
gchar* result = quoted->str;
|
|
||||||
g_string_free(quoted, FALSE);
|
|
||||||
|
|
||||||
g_free(search_str_lower);
|
|
||||||
g_free(curr_lower);
|
|
||||||
return result;
|
|
||||||
|
|
||||||
// otherwise just return the string
|
|
||||||
} else {
|
|
||||||
g_free(search_str_lower);
|
|
||||||
g_free(curr_lower);
|
|
||||||
return strdup(curr->data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(curr_lower);
|
|
||||||
curr = g_list_previous(curr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(search_str_lower);
|
g_free(search_str_lower);
|
||||||
|
|||||||
Reference in New Issue
Block a user